diff --git a/CMakeLists.txt b/CMakeLists.txt index 55ef81309..2a5ab756c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ endif () # set PKTMINERG_MAJOR_VERSION, PKTMINERG_MINOR_VERSION, etc. set(PKTMINERG_MAJOR_VERSION "0") set(PKTMINERG_MINOR_VERSION "5") -set(PKTMINERG_PATCH_VERSION "6") +set(PKTMINERG_PATCH_VERSION "7") set(PKTMINERG_VERSION_STRING "${PKTMINERG_MAJOR_VERSION}.${PKTMINERG_MINOR_VERSION}.${PKTMINERG_PATCH_VERSION}") if(WIN32) diff --git a/src/pcapexport.h b/src/pcapexport.h index b3067efa8..eb57cccb0 100644 --- a/src/pcapexport.h +++ b/src/pcapexport.h @@ -9,6 +9,16 @@ #define PKTD_OG 2 #define PKTD_NONCHECK 0 +typedef struct +{ + uint8_t reserved1:4; + uint8_t rra:4; + uint8_t service_tag_h : 4; + uint8_t reserved2 : 4; + uint8_t service_tag_l:8; + uint8_t check; +}pa_tag_t; + static inline uint64_t tv2us(const timeval* tv) { diff --git a/src/pcaphandler.cpp b/src/pcaphandler.cpp index 3124e897c..e56139617 100644 --- a/src/pcaphandler.cpp +++ b/src/pcaphandler.cpp @@ -124,9 +124,14 @@ void PcapHandler::packetHandler(const struct pcap_pkthdr* header, const uint8_t* ether_header* eth; iphdr* ip; ip6_hdr* ipv6; + vlan_tag *vlan_hdr; + udphdr *udp_hdr; + tcphdr *tcp_hdr; uint16_t eth_type; + uint16_t sport = 0; + uint16_t dport = 0; int direct; - vlan_tag *vlan_hdr; + int cap_len = header->len; if(header->caplen < sizeof(ether_header)) return; @@ -137,20 +142,38 @@ void PcapHandler::packetHandler(const struct pcap_pkthdr* header, const uint8_t* switch(eth_type) { case ETHERTYPE_IP: ip = (iphdr*)(pkt_data + sizeof(ether_header)); - direct = checkPktDirectionV4((const in_addr*)&ip->saddr, (const in_addr*)&ip->daddr); - break; - case ETHERTYPE_IPV6: - ipv6 = (ip6_hdr*)(pkt_data + sizeof(ether_header)); - direct = checkPktDirectionV6(&ipv6->ip6_src, &ipv6->ip6_dst); - break; + if (ip->protocol == 17) { + udp_hdr = (udphdr*) (pkt_data + sizeof(ether_header)+sizeof(iphdr)); + sport = ntohs(udp_hdr->source); + dport = ntohs(udp_hdr->dest); + } + else if (ip->protocol == 6) { + tcp_hdr = (tcphdr*) (pkt_data + sizeof(ether_header)+sizeof(iphdr)); + sport = ntohs(tcp_hdr->source); + dport = ntohs(tcp_hdr->dest); + } + direct = checkPktDirection((const in_addr*)&ip->saddr, (const in_addr*)&ip->daddr, sport, dport); case ETHERTYPE_VLAN: { - vlan_hdr = (vlan_tag *) (pkt_data + sizeof(ether_header)); + vlan_hdr = (vlan_tag*) (pkt_data + sizeof(ether_header)); uint16_t vlan_type = ntohs(vlan_hdr->vlan_tci); - switch (vlan_type) { + switch(vlan_type) { case ETHERTYPE_IP: - ip = (iphdr *) (pkt_data + sizeof(ether_header) + sizeof(vlan_tag)); - direct = checkPktDirectionV4((const in_addr *) &ip->saddr, (const in_addr *) &ip->daddr); + ip = (iphdr*)(pkt_data + sizeof(ether_header)+sizeof(vlan_tag)); + if (ip->protocol == 17) { + udp_hdr = (udphdr*) (pkt_data + sizeof(ether_header) + sizeof(iphdr) + sizeof(vlan_tag)) ; + sport = ntohs(udp_hdr->source); + dport = ntohs(udp_hdr->dest); + } + else if (ip->protocol == 6) { + tcp_hdr = (tcphdr*) (pkt_data + sizeof(ether_header)+sizeof(iphdr) + sizeof(vlan_tag)); + sport = ntohs(tcp_hdr->source); + dport = ntohs(tcp_hdr->dest); + } + direct = checkPktDirection((const in_addr*)&ip->saddr, (const in_addr*)&ip->daddr, sport, dport); + break; + + default: break; } } @@ -223,31 +246,19 @@ void PcapHandler::stopPcapLoop() { pcap_breakloop(_pcap_handle); } -int PcapHandler::checkPktDirectionV4(const in_addr *sip, const in_addr *dip) { - for(auto& ipv4 : _ipv4s) - { - if(ipv4.s_addr == sip->s_addr) - return PKTD_OG; - else if(ipv4.s_addr == dip->s_addr) - return PKTD_IC; +int PcapHandler::checkPktDirection(const in_addr *sip, const in_addr *dip, const uint16_t sport, const uint16_t dport) { + if (!_addr.isInited()) { + return PKTD_NONCHECK; } - return PKTD_UNKNOWN; -} -int PcapHandler::checkPktDirectionV6(const in6_addr *sip, const in6_addr *dip) { - for(auto& ipv6 : _ipv6s) - { - if(ipv6.s6_addr32[0] == sip->s6_addr32[0] && - ipv6.s6_addr32[1] == sip->s6_addr32[1] && - ipv6.s6_addr32[2] == sip->s6_addr32[2] && - ipv6.s6_addr32[3] == sip->s6_addr32[3]) - return PKTD_OG; - else if(ipv6.s6_addr32[0] == dip->s6_addr32[0] && - ipv6.s6_addr32[1] == dip->s6_addr32[1] && - ipv6.s6_addr32[2] == dip->s6_addr32[2] && - ipv6.s6_addr32[3] == dip->s6_addr32[3]) - return PKTD_IC; + if (_addr.matchIpPort(sip, sport)) { + return PKTD_OG; + } + + if (_addr.matchIpPort(dip, dport)) { + return PKTD_IC; } + return PKTD_UNKNOWN; } diff --git a/src/pcaphandler.h b/src/pcaphandler.h index 711f8dfad..0ff581f97 100644 --- a/src/pcaphandler.h +++ b/src/pcaphandler.h @@ -12,7 +12,46 @@ #include "pcapexport.h" #include "statislog.h" - +struct tcphdr +{ + uint16_t source; + uint16_t dest; + uint32_t seq; + uint32_t ack_seq; +# if __BYTE_ORDER == __LITTLE_ENDIAN + uint16_t res1:4; + uint16_t doff:4; + uint16_t fin:1; + uint16_t syn:1; + uint16_t rst:1; + uint16_t psh:1; + uint16_t ack:1; + uint16_t urg:1; + uint16_t res2:2; +# elif __BYTE_ORDER == __BIG_ENDIAN + uint16_t doff:4; + uint16_t res1:4; + uint16_t res2:2; + uint16_t urg:1; + uint16_t ack:1; + uint16_t psh:1; + uint16_t rst:1; + uint16_t syn:1; + uint16_t fin:1; +# else +# error "Adjust your defines" +# endif + u_int16_t window; + u_int16_t check; + u_int16_t urg_ptr; +}; +struct udphdr +{ + uint16_t source; + uint16_t dest; + uint16_t len; + uint16_t check; +}; typedef struct PcapInit { int snaplen; int timeout; @@ -60,8 +99,7 @@ class PcapHandler { int openPcapDumper(pcap_t *pcap_handle); void closePcapDumper(); - int checkPktDirectionV4(const in_addr* sip, const in_addr* dip); - int checkPktDirectionV6(const in6_addr* sip, const in6_addr* dip); + int checkPktDirection(const in_addr *sip, const in_addr *dip, const uint16_t sport, const uint16_t dport); public: PcapHandler(std::string dumpDir, int16_t dumpInterval); virtual ~PcapHandler(); @@ -72,6 +110,7 @@ class PcapHandler { virtual int openPcap(const std::string &dev, const pcap_init_t ¶m, const std::string &expression, bool dumpfile=false) = 0; void closePcap(); + void setDirIPPorts(std::string str) {_addr.init(str);}; }; class PcapOfflineHandler : public PcapHandler { diff --git a/src/pktminerg.cpp b/src/pktminerg.cpp index 779c70060..9ba68d6d2 100644 --- a/src/pktminerg.cpp +++ b/src/pktminerg.cpp @@ -60,6 +60,8 @@ int main(int argc, const char* argv[]) { "specify the interval for dump file creation") ("mbps", boost::program_options::value()->default_value(0)->value_name("mbps"), "specify a floating point value for the Mbps rate that pktmg should send packets at.") + ("dir", boost::program_options::value()->value_name("DIR"), + "specify the direction determination expression") ("nofilter", "force no filter; In online mode, only use when GRE interface " "is set via CLI, AND you confirm that the snoop interface is " @@ -256,6 +258,9 @@ int main(int argc, const char* argv[]) { // online std::string dev = vm["interface"].as(); handler = std::make_shared(vm["dump"].as(), vm["interval"].as()); + if (vm.count("dir")) { + handler->setDirIPPorts(vm["dir"].as()); + } if (handler->openPcap(dev, param, filter, dumpfile) != 0) { std::cerr << StatisLogContext::getTimeString() << "Call PcapLiveHandler openPcap failed." << std::endl; return 1; diff --git a/src/socketvxlan.cpp b/src/socketvxlan.cpp index 4f054236d..151f05745 100644 --- a/src/socketvxlan.cpp +++ b/src/socketvxlan.cpp @@ -143,11 +143,18 @@ int PcapExportVxlan::exportPacket(size_t index, const struct pcap_pkthdr* header vxlan_hdr_t* hdr; hdr = (vxlan_hdr_t*)&*vxlanbuffer.begin(); - hdr->vx_flags = htonl(0x08000000); - hdr->vx_vni = htonl(_vni | (direct << 28)); - std::memcpy(reinterpret_cast(&(vxlanbuffer[sizeof(vxlan_hdr_t)])), reinterpret_cast(pkt_data), length); + + hdr->vx_vni = htonl(_vni<<8); + if (direct != 0) { + ((pa_tag_t*)&hdr->vx_vni)->rra = direct; + ((pa_tag_t*)&hdr->vx_vni)->reserved1 = 0; + ((pa_tag_t*)&hdr->vx_vni)->reserved2 = 0; + ((pa_tag_t*)&hdr->vx_vni)->check = 0; + } + + ssize_t nSend = sendto(socketfd, &(vxlanbuffer[0]), length + sizeof(vxlan_hdr_t), 0, (struct sockaddr*) &remote_addr, sizeof(struct sockaddr)); while (nSend == -1 && errno == ENOBUFS) {