Skip to content

Commit

Permalink
Merge pull request #54 from Netis/feature/multi_remoteip
Browse files Browse the repository at this point in the history
send GRE to multi-remoteip
  • Loading branch information
lcywoodlucy committed Aug 15, 2019
2 parents 58f8f47 + 16eacbd commit 5b93332
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 63 deletions.
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

The list of the most significant changes made in Netis Packet Agent over time.

## Netis Packet Agent 0.3.3
* Support send GRE packets to multi-remoteip
* Support send GRE packets from binded device (network interface).
* Support systemd

## Netis Packet Agent 0.3.2

### Features
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ endif ()
# set PKTMINERG_MAJOR_VERSION, PKTMINERG_MINOR_VERSION, etc.
set(PKTMINERG_MAJOR_VERSION "0")
set(PKTMINERG_MINOR_VERSION "3")
set(PKTMINERG_PATCH_VERSION "2")
set(PKTMINERG_PATCH_VERSION "3")
set(PKTMINERG_VERSION_STRING "${PKTMINERG_MAJOR_VERSION}.${PKTMINERG_MINOR_VERSION}.${PKTMINERG_PATCH_VERSION}")

if(WIN32)
Expand Down
8 changes: 4 additions & 4 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ yum install libpcap wget
2. Download and install the RPM package. Find the latest package from [Releases Page](https://github.com/Netis/packet-agent/releases).

```shell
wget https://github.com/Netis/packet-agent/releases/download/v0.3.2/netis-packet-agent-0.3.2.el6.x86_64.rpm
rpm -ivh netis-packet-agent-0.3.2.el6.x86_64.rpm
wget https://github.com/Netis/packet-agent/releases/download/v0.3.3/netis-packet-agent-0.3.3.el6.x86_64.rpm
rpm -ivh netis-packet-agent-0.3.3.el6.x86_64.rpm
```

## SUSE 12

1. Download and install the RPM package. Find the latest package from [Releases Page](https://github.com/Netis/packet-agent/releases).

```shell
wget https://github.com/Netis/packet-agent/releases/download/v0.3.2/netis-packet-agent-0.3.2.el6.x86_64.rpm
rpm -ivh netis-packet-agent-0.3.2.el6.x86_64.rpm
wget https://github.com/Netis/packet-agent/releases/download/v0.3.3/netis-packet-agent-0.3.3.el6.x86_64.rpm
rpm -ivh netis-packet-agent-0.3.3.el6.x86_64.rpm
```
16 changes: 8 additions & 8 deletions README-zh-Hans.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
[English](README.md) ∙ 简体中文

![packet agent's title](./img/title.jpg)
# Netis Packet Agent 0.3.2
# Netis Packet Agent 0.3.3

[![Stable release](https://img.shields.io/badge/version-0.3.2-green.svg)](https://github.com/Netis/packet-agent/releases/tag/0.3.2)
[![Stable release](https://img.shields.io/badge/version-0.3.3-green.svg)](https://github.com/Netis/packet-agent/releases/tag/0.3.3)
[![Software License](https://img.shields.io/badge/license-BSD3-green.svg)](./LICENSE.md)


Expand Down Expand Up @@ -35,14 +35,14 @@ yum install libpcap wget

2. 下载并安装RPM包。您可以从[这个地址](https://github.com/Netis/packet-agent/releases)获取最新版本的软件包。
```bash
wget https://github.com/Netis/packet-agent/releases/download/v0.3.2/netis-packet-agent-0.3.2.el6.x86_64.rpm
rpm -ivh netis-packet-agent-0.3.2.el6.x86_64.rpm
wget https://github.com/Netis/packet-agent/releases/download/v0.3.3/netis-packet-agent-0.3.3.el6.x86_64.rpm
rpm -ivh netis-packet-agent-0.3.3.el6.x86_64.rpm
```
#### SUSE12
1. 下载并安装RPM包。您可以从[这个地址](https://github.com/Netis/packet-agent/releases)获取最新版本的软件包。
```bash
wget https://github.com/Netis/packet-agent/releases/download/v0.3.2/netis-packet-agent-0.3.2.el6.x86_64.rpm
rpm -ivh netis-packet-agent-0.3.2.el6.x86_64.rpm
wget https://github.com/Netis/packet-agent/releases/download/v0.3.3/netis-packet-agent-0.3.3.el6.x86_64.rpm
rpm -ivh netis-packet-agent-0.3.3.el6.x86_64.rpm
```

#### Ubuntu 18.04LTS
Expand All @@ -53,8 +53,8 @@ sudo apt-get install libpcap-dev wget

2. 下载并安装DEB包。您可以从[这个地址](https://github.com/Netis/packet-agent/releases)获取最新版本的软件包。
```bash
wget https://github.com/Netis/packet-agent/releases/download/v0.3.2/netis-packet-agent-0.3.2_amd64.deb
sudo dpkg -i netis-packet-agent-0.3.2_amd64.deb
wget https://github.com/Netis/packet-agent/releases/download/v0.3.3/netis-packet-agent-0.3.3_amd64.deb
sudo dpkg -i netis-packet-agent-0.3.3_amd64.deb
```

3. 如果提示libpcap.so找不到,到libpcap.so所在目录下创建libpcap.so.1软链接。
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
English ∙ [简体中文](README-zh-Hans.md)

![packet agent's title](./img/title.jpg)
# Netis Packet Agent 0.3.2
# Netis Packet Agent 0.3.3

[![Stable release](https://img.shields.io/badge/version-0.3.2-green.svg)](https://github.com/Netis/packet-agent/releases/tag/0.3.2)
[![Stable release](https://img.shields.io/badge/version-0.3.3-green.svg)](https://github.com/Netis/packet-agent/releases/tag/0.3.3)
[![Software License](https://img.shields.io/badge/license-BSD3-green.svg)](./LICENSE.md)

## What is Netis Packet Agent?
Expand Down Expand Up @@ -35,15 +35,15 @@ yum install libpcap wget

2. Download and install the RPM package. Find the latest package from [Releases Page](https://github.com/Netis/packet-agent/releases).
```bash
wget https://github.com/Netis/packet-agent/releases/download/v0.3.2/netis-packet-agent-0.3.2.el6.x86_64.rpm
rpm -ivh netis-packet-agent-0.3.2.el6.x86_64.rpm
wget https://github.com/Netis/packet-agent/releases/download/v0.3.3/netis-packet-agent-0.3.3.el6.x86_64.rpm
rpm -ivh netis-packet-agent-0.3.3.el6.x86_64.rpm
```

#### SUSE 12
1. Download and install the RPM package. Find the latest package from [Releases Page](https://github.com/Netis/packet-agent/releases).
```bash
wget https://github.com/Netis/packet-agent/releases/download/v0.3.2/netis-packet-agent-0.3.2.el6.x86_64.rpm
rpm -ivh netis-packet-agent-0.3.2.el6.x86_64.rpm
wget https://github.com/Netis/packet-agent/releases/download/v0.3.3/netis-packet-agent-0.3.3.el6.x86_64.rpm
rpm -ivh netis-packet-agent-0.3.3.el6.x86_64.rpm
```


Expand All @@ -55,8 +55,8 @@ sudo apt-get install libpcap-dev wget

2. Download and install the DEB package. Find the latest package from [Releases Page](https://github.com/Netis/packet-agent/releases).
```bash
wget https://github.com/Netis/packet-agent/releases/download/v0.3.2/netis-packet-agent-0.3.2_amd64.deb
sudo dpkg -i netis-packet-agent-0.3.2_amd64.deb
wget https://github.com/Netis/packet-agent/releases/download/v0.3.3/netis-packet-agent-0.3.3_amd64.deb
sudo dpkg -i netis-packet-agent-0.3.3_amd64.deb
```

3. If libpcap.so.1 not found when running pktminerg, create softlink for libpcap.so.1 in suitable directory.
Expand Down
8 changes: 5 additions & 3 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ Generic options:
Allowed options:
-i [ --interface ] NIC interface to capture packets
-B [ --bind_device ] BIND send GRE packets from this binded device
-f [ --pcapfile ] PATH specify pcap file for offline mode, mostly
-B [ --bind_device ] BIND send GRE packets from this binded
device.(Not available on Windows)
-f [ --pcapfile ] PATH specify pcap file for offline mode, mostly
for test
-r [ --remoteip ] IP set gre remote ip
-r [ --remoteip ] IPs set gre remote IPs, seperate by ',' Example:
-r 8.8.4.4,8.8.8.8
-k [ --keybit ] BIT (=1) set gre key bit; BIT defaults 1
-s [ --snaplen ] LENGTH (=2048) set snoop packet snaplen; LENGTH defaults
2048 and units byte
Expand Down
2 changes: 1 addition & 1 deletion scripts/ansible_pktg.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 说明
1. 在主控的中心服务器上需要安装有 ansible 程序。如果没有,可以使用类似 yum install ansible 的命令安装。</br>
2. 将需要安装 packet-agent 的机器加入 ansible 的 hosts 文件:比如添加组 [servers_to_install_pktg] 到 /etc/ansible/hosts,并在该组下加入若干机器IP。</br>
3. 拷贝待安装的 packet-agent rpm/deb 到 ansible_pktg.yaml 同一目录下。如果待安装的 rpm/deb 不是 yaml 中指定的 netis-packet-agent-0.3.2.el6.x86_64.rpm / netis-packet-agent-0.3.2_amd64.deb,则将 ansible_pktg.yaml 中 rpm_file/deb_file 修改为你需要的文件名。</br>
3. 拷贝待安装的 packet-agent rpm/deb 到 ansible_pktg.yaml 同一目录下。如果待安装的 rpm/deb 不是 yaml 中指定的 netis-packet-agent-0.3.3.el6.x86_64.rpm / netis-packet-agent-0.3.3_amd64.deb,则将 ansible_pktg.yaml 中 rpm_file/deb_file 修改为你需要的文件名。</br>
4. 执行 ansible-playbook ansible_pktg.yaml 命令,将 packet-agent 程序安装到各个目标机器上。</br>

4 changes: 2 additions & 2 deletions scripts/ansible_pktg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
- name: install packet-agent and its depends
hosts: servers_to_install_pktg
vars:
rpm_file: netis-packet-agent-0.3.2.el6.x86_64.rpm
deb_file: netis-packet-agent-0.3.2_amd64.deb
rpm_file: netis-packet-agent-0.3.3.el6.x86_64.rpm
deb_file: netis-packet-agent-0.3.3_amd64.deb
remote_user: root
gather_facts: True

Expand Down
27 changes: 17 additions & 10 deletions src/pktminerg.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <iostream>
#include <csignal>
#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>
#include "pcaphandler.h"
#include "socketgre.h"
#include "versioninfo.h"
Expand All @@ -19,10 +20,11 @@ int main(int argc, const char* argv[]) {
("interface,i", boost::program_options::value<std::string>()->value_name("NIC"),
"interface to capture packets")
("bind_device,B", boost::program_options::value<std::string>()->value_name("BIND"),
"send GRE packets from this binded device")
"send GRE packets from this binded device.(Not available on Windows)")
("pcapfile,f", boost::program_options::value<std::string>()->value_name("PATH"),
"specify pcap file for offline mode, mostly for test")
("remoteip,r", boost::program_options::value<std::string>()->value_name("IP"), "set gre remote ip")
("remoteip,r", boost::program_options::value<std::string>()->value_name("IPs"),
"set gre remote IPs, seperate by ',' Example: -r 8.8.4.4,8.8.8.8")
("keybit,k", boost::program_options::value<int>()->default_value(1)->value_name("BIT"),
"set gre key bit; BIT defaults 1")
("snaplen,s", boost::program_options::value<int>()->default_value(2048)->value_name("LENGTH"),
Expand Down Expand Up @@ -90,6 +92,9 @@ int main(int argc, const char* argv[]) {
}

std::string remoteip = vm["remoteip"].as<std::string>();
std::vector<std::string> remoteips;
boost::algorithm::split(remoteips, remoteip, boost::algorithm::is_any_of(","));

int keybit = vm["keybit"].as<int>();

std::string filter = "";
Expand All @@ -105,14 +110,16 @@ int main(int argc, const char* argv[]) {
nofilter = true;
}

if (!nofilter) {
if (filter.length() > 0) {
filter = filter + "and not host " + remoteip;
} else {
filter = "not host " + remoteip;
}
} else {
if (nofilter) {
filter = "";
} else {
for (size_t i = 0; i < remoteips.size(); ++i) {
if (filter.length() > 0) {
filter = filter + " and not host " + remoteips[i];
} else {
filter = "not host " + remoteips[i];
}
}
}

// dump option
Expand Down Expand Up @@ -186,7 +193,7 @@ int main(int argc, const char* argv[]) {
});

// export gre
std::shared_ptr<PcapExportBase> greExport = std::make_shared<PcapExportGre>(remoteip, keybit, bind_device);
std::shared_ptr<PcapExportBase> greExport = std::make_shared<PcapExportGre>(remoteips, keybit, bind_device);
int err = greExport->initExport();
if (err != 0) {
std::cerr << StatisLogContext::getTimeString()
Expand Down
73 changes: 53 additions & 20 deletions src/socketgre.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,39 @@

const int INVALIDE_SOCKET_FD = -1;

PcapExportGre::PcapExportGre(const std::string& remoteip, uint32_t keybit, const std::string& bind_device) :
_remoteip(remoteip),
PcapExportGre::PcapExportGre(const std::vector<std::string>& remoteips, uint32_t keybit, const std::string& bind_device) :
_remoteips(remoteips),
_keybit(keybit),
_bind_device(bind_device),
_socketfd(INVALIDE_SOCKET_FD) {
_socketfds(remoteips.size()),
_remote_addrs(remoteips.size()),
_grebuffers(remoteips.size()) {
_type = exporttype::gre;
std::memset(_grebuffer, 0, sizeof(_grebuffer));
for (size_t i = 0; i < remoteips.size(); ++i) {
_socketfds[i] = INVALIDE_SOCKET_FD;
_grebuffers[i].resize(65535 + sizeof(grehdr_t), '\0');
}
}

PcapExportGre::~PcapExportGre() {
closeExport();
}

int PcapExportGre::initExport() {
int PcapExportGre::initSockets(size_t index, uint32_t keybit, const std::string& bind_device) {
auto& socketfd = _socketfds[index];
auto& grebuffer = _grebuffers[index];

grehdr_t grehdr;
if (_socketfd == INVALIDE_SOCKET_FD) {
if (socketfd == INVALIDE_SOCKET_FD) {
grehdr.flags = htons(0x2000);
grehdr.protocol = htons(0x6558);
grehdr.keybit = htonl(_keybit);
std::memcpy(reinterpret_cast<void*>(_grebuffer), &grehdr, sizeof(grehdr_t));
grehdr.keybit = htonl(keybit);
std::memcpy(reinterpret_cast<void*>(&(grebuffer[0])), &grehdr, sizeof(grehdr_t));

_remote_addr.sin_family = AF_INET;
_remote_addr.sin_addr.s_addr = inet_addr(_remoteip.c_str());
_remote_addrs[index].sin_family = AF_INET;
_remote_addrs[index].sin_addr.s_addr = inet_addr(_remoteips[index].c_str());

if ((_socketfd = socket(AF_INET, SOCK_RAW, IPPROTO_GRE)) == INVALIDE_SOCKET_FD) {
if ((socketfd = socket(AF_INET, SOCK_RAW, IPPROTO_GRE)) == INVALIDE_SOCKET_FD) {
std::cerr << StatisLogContext::getTimeString() << "Create socket failed, error code is " << errno
<< ", error is " << strerror(errno) << "."
<< std::endl;
Expand All @@ -53,7 +61,7 @@ int PcapExportGre::initExport() {
#ifdef WIN32
//TODO: bind device on WIN32
#else
if (setsockopt(_socketfd, SOL_SOCKET, SO_BINDTODEVICE, _bind_device.c_str(), _bind_device.length()) < 0) {
if (setsockopt(socketfd, SOL_SOCKET, SO_BINDTODEVICE, _bind_device.c_str(), _bind_device.length()) < 0) {
std::cerr << StatisLogContext::getTimeString() << "SO_BINDTODEVICE failed, error code is " << errno
<< ", error is " << strerror(errno) << "."
<< std::endl;
Expand All @@ -65,28 +73,53 @@ int PcapExportGre::initExport() {
return 0;
}

int PcapExportGre::initExport() {
for (size_t i = 0; i < _remoteips.size(); ++i) {
int ret = initSockets(i, _keybit, _bind_device);
if (ret != 0) {
std::cerr << "Failed with index: " << i << std::endl;
return ret;
}
}
return 0;
}

int PcapExportGre::closeExport() {
if (_socketfd != INVALIDE_SOCKET_FD) {
for (size_t i = 0; i < _remoteips.size(); ++i) {
if (_socketfds[i] != INVALIDE_SOCKET_FD) {
#ifdef WIN32
shutdown(_socketfd, SD_BOTH);
shutdown(_socketfd, SD_BOTH);
#else
close(_socketfd);
close(_socketfds[i]);
#endif // WIN32
_socketfd = INVALIDE_SOCKET_FD;
_socketfds[i] = INVALIDE_SOCKET_FD;
}
}
return 0;
}

int PcapExportGre::exportPacket(const struct pcap_pkthdr* header, const uint8_t* pkt_data) {
int ret = 0;
for (size_t i = 0; i < _remoteips.size(); ++i) {
ret |= exportPacket(i, header, pkt_data);
}
return ret;
}

int PcapExportGre::exportPacket(size_t index, const struct pcap_pkthdr* header, const uint8_t* pkt_data) {
auto& grebuffer = _grebuffers[index];
int socketfd = _socketfds[index];
auto& remote_addr = _remote_addrs[index];

size_t length = (size_t) (header->caplen <= 65535 ? header->caplen : 65535);
std::memcpy(reinterpret_cast<void*>(_grebuffer + sizeof(grehdr_t)),
std::memcpy(reinterpret_cast<void*>(&(grebuffer[sizeof(grehdr_t)])),
reinterpret_cast<const void*>(pkt_data), length);
ssize_t nSend = sendto(_socketfd, _grebuffer, length + sizeof(grehdr_t), 0, (struct sockaddr*) &_remote_addr,
ssize_t nSend = sendto(socketfd, &(grebuffer[0]), length + sizeof(grehdr_t), 0, (struct sockaddr*) &remote_addr,
sizeof(struct sockaddr));
while (nSend == -1 && errno == ENOBUFS) {
usleep(1000);
nSend = static_cast<int>(sendto(_socketfd, _grebuffer, length + sizeof(grehdr_t), 0,
(struct sockaddr*) &_remote_addr,
nSend = static_cast<int>(sendto(socketfd, &(grebuffer[0]), length + sizeof(grehdr_t), 0,
(struct sockaddr*) &remote_addr,
sizeof(struct sockaddr)));
}
if (nSend == -1) {
Expand Down
17 changes: 12 additions & 5 deletions src/socketgre.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,26 @@
#include <netinet/in.h>
#endif
#include <string>
#include <vector>
#include "pcapexport.h"
#include "gredef.h"


class PcapExportGre : public PcapExportBase {
protected:
std::string _remoteip;
std::vector<std::string> _remoteips;
uint32_t _keybit;
std::string _bind_device;
int _socketfd;
struct sockaddr_in _remote_addr;
char _grebuffer[65535 + sizeof(grehdr_t)];
std::vector<int> _socketfds;
std::vector<struct sockaddr_in> _remote_addrs;
std::vector<std::vector<char>> _grebuffers;

private:
int initSockets(size_t index, uint32_t keybit, const std::string& bind_device);
int exportPacket(size_t index, const struct pcap_pkthdr *header, const uint8_t *pkt_data);

public:
PcapExportGre(const std::string &remoteip, uint32_t keybit, const std::string& bind_device);
PcapExportGre(const std::vector<std::string>& remoteips, uint32_t keybit, const std::string& bind_device);
~PcapExportGre();
int initExport();
int exportPacket(const struct pcap_pkthdr *header, const uint8_t *pkt_data);
Expand Down
4 changes: 3 additions & 1 deletion test/unit_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ namespace {
}

TEST(PcapExportGre, test) {
PcapExportGre greExport("127.0.1.1", 2, "");
std::vector<std::string> remoteips;
remoteips.push_back("127.0.1.1");
PcapExportGre greExport(remoteips, 2, "");
EXPECT_EQ(0, greExport.initExport());
pcap_pkthdr header;
header.caplen = 32;
Expand Down

0 comments on commit 5b93332

Please sign in to comment.