Created
August 12, 2015 17:01
-
-
Save jossef/2c70d1b18375d2786ffb to your computer and use it in GitHub Desktop.
iterates pcap using libpcap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <pcap.h> | |
| #include <stdlib.h> | |
| #include <iostream> | |
| #include <algorithm> | |
| #include <netinet/ip.h> | |
| #include <arpa/inet.h> | |
| #include <netinet/if_ether.h> | |
| #include <string> | |
| #include <sstream> | |
| using namespace std; | |
| #define ETHER_TYPE_IP (0x0800) | |
| #define TCP_TYPE 6 | |
| #define UDP_TYPE 17 | |
| typedef struct { | |
| uint8_t dst_addr[6]; | |
| uint8_t src_addr[6]; | |
| uint16_t llc_len; | |
| } ether_header_t; | |
| typedef struct { | |
| uint8_t ver_ihl; | |
| uint8_t tos; | |
| uint16_t total_length; | |
| uint16_t id; | |
| uint16_t flags_fo; | |
| uint8_t ttl; | |
| uint8_t protocol; | |
| uint16_t checksum; | |
| uint32_t src_addr; | |
| uint32_t dst_addr; | |
| } ip_header_t; | |
| typedef struct { | |
| uint16_t src_port; | |
| uint16_t dst_port; | |
| uint16_t length; | |
| uint16_t checksum; | |
| } udp_header_t; | |
| typedef struct { | |
| uint16_t src_port; | |
| uint16_t dst_port; | |
| uint32_t seq; | |
| uint32_t ack; | |
| uint8_t data_offset; | |
| uint8_t flags; | |
| uint16_t window_size; | |
| uint16_t checksum; | |
| uint16_t urgent_p; | |
| } tcp_header_t; | |
| char* convert_ip_int_to_string(uint32_t ip) | |
| { | |
| struct in_addr ip_addr = {0}; | |
| ip_addr.s_addr = ip; | |
| return inet_ntoa(ip_addr); | |
| } | |
| //------------------------------------------------------------------- | |
| int main(int argc, char **argv) | |
| { | |
| unsigned int pkt_counter=0; | |
| unsigned long byte_counter=0; | |
| unsigned long cur_counter=0; | |
| unsigned long max_volume = 0; | |
| unsigned long current_ts=0; | |
| //temporary packet buffers | |
| struct pcap_pkthdr header; | |
| const u_char *packet; | |
| //check command line arguments | |
| if (argc < 2) { | |
| fprintf(stderr, "Usage: %s [input pcaps]\n", argv[0]); | |
| exit(1); | |
| } | |
| for (int fnum=1; fnum < argc; fnum++) { | |
| pcap_t *handle; | |
| char errbuf[PCAP_ERRBUF_SIZE]; | |
| char* inputPcapFileName = argv[fnum]; | |
| char* outputPcapFileName = "/tmp/cap.pcap"; | |
| u_char *ptr; | |
| int i; | |
| handle = pcap_open_offline(inputPcapFileName, errbuf); | |
| if (handle == NULL) { | |
| fprintf(stderr,"Couldn't open pcap file %s: %s\n", argv[fnum], errbuf); | |
| return(2); | |
| } | |
| pcap_dumper_t *dumper = pcap_dump_open(handle, outputPcapFileName); | |
| int counter2 = 0; | |
| while (packet = pcap_next(handle,&header)) { | |
| ether_header_t* ether_header = (ether_header_t *)(packet + sizeof(ether_header_t)); | |
| u_char *pkt_ptr = (u_char *)packet; | |
| int ether_type = ((int)(pkt_ptr[12]) << 8) | (int)pkt_ptr[13]; | |
| if (ether_type != ETHER_TYPE_IP) | |
| continue; | |
| ip_header_t* ip_header = (ip_header_t *)(packet + sizeof(ether_header_t)); | |
| // ---------------------- | |
| int protocol = ip_header->protocol; | |
| string minIpAddress; | |
| string maxIpAddress; | |
| int minPort; | |
| int maxPort; | |
| if (protocol != TCP_TYPE && protocol != UDP_TYPE) | |
| { | |
| continue; | |
| } | |
| if (ip_header->src_addr > ip_header->dst_addr) | |
| { | |
| minIpAddress = convert_ip_int_to_string(ip_header->dst_addr); | |
| maxIpAddress = convert_ip_int_to_string(ip_header->src_addr); | |
| } | |
| else | |
| { | |
| maxIpAddress = convert_ip_int_to_string(ip_header->dst_addr); | |
| minIpAddress = convert_ip_int_to_string(ip_header->src_addr); | |
| } | |
| int ip_size = 4 * (ip_header->ver_ihl & 0x0F); | |
| if (protocol == TCP_TYPE) | |
| { | |
| // TCP | |
| tcp_header_t* tcp_header = (tcp_header_t *)(packet + ip_size + sizeof(ether_header_t)); | |
| int sourcePort = ntohs(tcp_header->src_port); | |
| int destinationPort = ntohs(tcp_header->dst_port); | |
| minPort = min(sourcePort, destinationPort); | |
| maxPort = max(sourcePort, destinationPort); | |
| } | |
| else | |
| { | |
| // UDP | |
| udp_header_t* udp_header = (udp_header_t *)(packet + ip_size + sizeof(ether_header_t)); | |
| int sourcePort = ntohs(udp_header->src_port); | |
| int destinationPort = ntohs(udp_header->dst_port); | |
| minPort = min(sourcePort, destinationPort); | |
| maxPort = max(sourcePort, destinationPort); | |
| } | |
| stringstream ss; | |
| ss << minIpAddress << "_" << maxIpAddress << "_" << minPort << "_" << maxPort << "_" << ( protocol == TCP_TYPE ? "TCP":"UDP" ); | |
| string name = ss.str(); | |
| cout << "channel: " << name << endl; | |
| // | |
| // int ether_type = ((int)(pkt_ptr[12]) << 8) | (int)pkt_ptr[13]; | |
| // int ether_offset = 0; | |
| // | |
| // if (ether_type == ETHER_TYPE_IP) | |
| // ether_offset = 14; | |
| // else | |
| // continue; | |
| // | |
| // | |
| // // --------------------------- | |
| // | |
| // char* ipAddress1 = ""; | |
| // char* ipAddress2 = ""; | |
| // int sourcePort = 1; | |
| // int destinationPort = 1; | |
| // bool isTcp = false; | |
| // | |
| // char* name="{minIp}_{minPort}_{maxIp}_{maxPort}_{TPC/UDP}.pcap"; | |
| // | |
| // //parse the IP header | |
| // pkt_ptr += ether_offset; //skip past the Ethernet II header | |
| // struct ip *ip_hdr = (struct ip *)pkt_ptr; //point to an IP header structure | |
| // | |
| // int packet_length = ntohs(ip_hdr->ip_len); | |
| // | |
| // //check to see if the next second has started, for statistics purposes | |
| // if (current_ts == 0) { //this takes care of the very first packet seen | |
| // current_ts = header.ts.tv_sec; | |
| // } else if (header.ts.tv_sec > current_ts) { | |
| // printf("%d KBps\n", cur_counter/1000); //print | |
| // cur_counter = 0; //reset counters | |
| // current_ts = header.ts.tv_sec; //update time interval | |
| // } | |
| // | |
| // cur_counter += packet_length; | |
| // byte_counter += packet_length; //byte counter update | |
| // pkt_counter++; //increment number of packets seen | |
| // | |
| // | |
| // | |
| pcap_dump((u_char *)dumper, &header, packet); | |
| counter2++; | |
| if (counter2>=10000) | |
| { | |
| break; | |
| } | |
| } | |
| pcap_close(handle); | |
| pcap_dump_close(dumper); | |
| } | |
| return 0; | |
| } |
jossef
commented
Aug 12, 2015
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment