@xunuo
2017-08-05T07:02:32.000000Z
字数 15539
阅读 1640
网络数据包分析
用一个两个链表:tcpsessionhead和tcpnodehead;
第一个链表用来确定唯一的一次tcp会话,则需要六元组(源mac,目的mac,源ip,目的ip,源端口,目的端口)(其实实际上可以不用源mac和目的mac),以及一个指向下一个节点的指针next和指向对应会话具体内容的指针tcpnodehead;
第二个链表存该会话的具体内容L:syn,seq,fin,len,以及该数据包传输的数据data[];
只是单纯的把该数据包内的东西解析出来了而已;
当检测到的数据包的syn==1&&是第一次出现syn=1时,就新建一个链表来存该tcp会话,如果检测到数据包的syn==0&&fin==0&&数据包除以太网头,ip头,tcp头外,数据长度不为0,则说明有数据传输,则将这个数据包加入tcpnode链表;如果fin==1,则说明数据传输结束,可以打印出数据。
首先创建tcpsession链表函数create():
将该数据包的六元祖存好,然后记住:一定要将next和tcpnodehead置空。不然会出问题,后面如果要用到他们的时候会无法读取内存。
插入函数insert():
在插入之前要先查一遍它所在的tcp会话(其实文件里只有一个,貌似没必要。。);然后分一下几种情况:如果这个数据包是第一个插入的,那么直接进去就行了,如果不是,就要看它的seq的大小和tcpnode链表里面已经存在的节点的seq比较,然后插入合适的位置。
#include "pcap.h"const int MAXETHERLEN = 1500;struct ether_header{u_int8_t ether_dhost[6];//目的mac;u_int8_t ether_shost[6];//源mac;u_int16_t ether_type;};/*ip地址*/typedef struct ip_address{u_char byte1;u_char byte2;u_char byte3;u_char byte4;} ip_address;/*IPv4协议头*/struct ip_header{#if defined(WORDS_BIENDIAN)u_int8_t ip_version : 4, ip_header_length : 4;#elseu_int8_t ip_header_length : 4, ip_version : 4;#endifu_int8_t ip_tos;u_int16_t ip_length;u_int16_t ip_id;u_int16_t ip_off;u_int8_t ip_ttl;u_int8_t ip_protocol;u_int16_t ip_checksum;ip_address saddr; /*源地址(Source address)*/ip_address daddr; /*目的地址(Destination address)*/};//TCP协议头#define __LITTLE_ENDIAN_BITFIELDstruct tcphdr{u_int16_t source_port; /*源地址端口*/u_int16_t dest_port; /*目的地址端口*/u_int32_t seq; /*序列号*/u_int32_t ack_seq; /*确认序列号*/u_int8_t res1 : 3, /*偏移*/doff : 1, /*保留*/tcp_header_length : 4;u_int8_t fin : 1, /*关闭连接标志*/syn : 1, /*请求连接标志*/rst : 1, /*重置连接标志*/psh : 1, /*接收方尽快将数据放到应用层标志*/ack : 1, /*确认序号标志*/urg : 1, /*紧急指针标志*/ece : 1, /*拥塞标志位*/cwr : 1; /*拥塞标志位*/u_int16_t flag;u_int16_t window; /*滑动窗口大小*/u_int16_t check; /*校验和*/u_int16_t urg_ptr; /*紧急字段指针*/};/*两个链表*//*list.1==tcplist*/typedef struct tcpnode{int syn;int fin;unsigned long seq;int len;tcpnode *prev;tcpnode *next;unsigned char data[MAXETHERLEN];}node;/*list.2=tcpsession*/typedef struct tcpsession{ip_address saddr;ip_address daddr;unsigned short sport;unsigned short dport;tcpsession* next;tcpnode *tcplisthead;}tcpss;void createtcpsession(tcpss *tcpsessionhead);bool isempty(tcpss* tcpsessionhead);bool search(tcpss *head);int insert(tcpss* tcpsessionheadconst, u_int32_t &cnt, int &flag1);void print(FILE* file, tcpss* tcpsessionhead);struct pcap_pkthdr *header;const u_char *packet_content;struct ether_header *ethernet_protocol;struct ip_header *ip_protocol;struct tcphdr *tcp_protocol;int flag = 0;u_int32_t fin_seq = 0;u_int32_t syn_seq = 0;u_int32_t cnt = 0;int flag1;int len;int main(int argc, char* argv[]){if (argc <= 1){printf("argc<=1,break!\n");return -1;}pcap_t *adapterHandle;//适配器句柄;char errorBuffer[PCAP_ERRBUF_SIZE];//错误缓冲区;char source[PCAP_BUF_SIZE];if (pcap_createsrcstr(source, PCAP_SRC_FILE, NULL, NULL, argv[1], errorBuffer) != 0){printf("数据源创建失败!\n");return -1;}if ((adapterHandle = pcap_open(source, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errorBuffer)) == NULL){printf("文件打开失败!\n");return -1;}tcpsession* tcpsessionhead = (tcpsession*)malloc(sizeof(tcpsession));tcpsessionhead->next = nullptr;tcpsessionhead->tcplisthead = nullptr;FILE* file;if (fopen_s(&file, argv[2], "w+") != 0){printf("打开文件失败!\n");}int pkt_number = 1;int res;while ((res = pcap_next_ex(adapterHandle, &header, &packet_content)) >= 0){if (res == 0)/* 超时时间到 */continue;printf("这是第%d个数据包!\n", pkt_number++);/*for (int i = 1; i <= header->len; i++){printf("%02x ", packet_content[i - 1]);if (i % 8 == 0)printf(" ");if (i % 16 == 0)printf("\n");}printf("\n");*/ethernet_protocol = (struct ether_header*)packet_content;ip_protocol = (struct ip_header *)(packet_content + sizeof(ether_header));tcp_protocol = (struct tcphdr *) (packet_content + sizeof(ether_header) + sizeof(ip_header));int ip_len = ntohs(ip_protocol->ip_length);printf("%d.%d.%d.%d\n", ip_protocol->saddr.byte1, ip_protocol->saddr.byte2, ip_protocol->saddr.byte3, ip_protocol->saddr.byte4);printf("%d.%d.%d.%d\n", ip_protocol->daddr.byte1, ip_protocol->daddr.byte2, ip_protocol->daddr.byte3, ip_protocol->daddr.byte4);len = ip_len - sizeof(ip_header) - tcp_protocol->tcp_header_length * 4;printf("长度:%d %d\n", ip_len - sizeof(ip_header) - tcp_protocol->tcp_header_length * 4, sizeof(ip_header) + tcp_protocol->tcp_header_length * 4);printf("%02x %02x\n", ntohs(tcp_protocol->source_port), ntohs(tcp_protocol->dest_port));printf("%u %u\n", ntohl(tcp_protocol->seq), ntohl(tcp_protocol->ack_seq));printf("syn and fin:%d %d\n", tcp_protocol->syn, tcp_protocol->fin);if (tcp_protocol->syn == 1 && flag == 0){createtcpsession(tcpsessionhead);flag = 1;syn_seq = ntohl(tcp_protocol->seq);}else if (tcp_protocol->syn == 0 && tcp_protocol->fin == 0 && len>0){cnt = insert(tcpsessionhead, cnt, flag1);}else if (tcp_protocol->fin == 1){flag = 0;print(file, tcpsessionhead);fclose(file);break;}printf("\n");}if (res == -1){printf("Error reading the packets: %s\n", pcap_geterr(adapterHandle));return -1;}return 0;}void createtcpsession(tcpss *tcpsessionhead){tcpss *root = tcpsessionhead;while (!isempty(root)){root = root->next;}root->saddr.byte1 = ip_protocol->saddr.byte1;root->saddr.byte2 = ip_protocol->saddr.byte2;root->saddr.byte3 = ip_protocol->saddr.byte3;root->saddr.byte4 = ip_protocol->saddr.byte4;root->daddr.byte1 = ip_protocol->daddr.byte1;root->daddr.byte2 = ip_protocol->daddr.byte2;root->daddr.byte3 = ip_protocol->daddr.byte3;root->daddr.byte4 = ip_protocol->daddr.byte4;root->sport = tcp_protocol->source_port;root->dport = tcp_protocol->dest_port;root->next = (tcpss*)malloc(sizeof(tcpss));root->next->next = NULL;root->next->tcplisthead = NULL;}bool isempty(tcpss* tcpsessionhead){if (tcpsessionhead->next == NULL)return true;elsereturn false;}bool search(tcpss *head){if ((head->saddr.byte1 == ip_protocol->saddr.byte1&&head->saddr.byte2 == ip_protocol->saddr.byte2&&head->saddr.byte3 == ip_protocol->saddr.byte3&&head->saddr.byte4 == ip_protocol->saddr.byte4&&head->daddr.byte1 == ip_protocol->daddr.byte1&&head->daddr.byte2 == ip_protocol->daddr.byte2&&head->daddr.byte3 == ip_protocol->daddr.byte3&&head->daddr.byte4 == ip_protocol->daddr.byte4&&head->sport == tcp_protocol->source_port&&head->dport == tcp_protocol->dest_port)|| (head->saddr.byte1 == ip_protocol->daddr.byte1&&head->saddr.byte2 == ip_protocol->daddr.byte2&&head->saddr.byte3 == ip_protocol->daddr.byte3&&head->saddr.byte4 == ip_protocol->daddr.byte4&&head->daddr.byte1 == ip_protocol->saddr.byte1&&head->daddr.byte2 == ip_protocol->saddr.byte2&&head->daddr.byte3 == ip_protocol->saddr.byte3&&head->daddr.byte4 == ip_protocol->saddr.byte4&&head->sport == tcp_protocol->dest_port&&head->dport == tcp_protocol->source_port))return true;elsereturn false;}int insert(tcpss* tcpsessionhead, u_int32_t &cnt, int &flag1){tcpss* tcpsshead = tcpsessionhead;while (!search(tcpsshead)){tcpsshead = tcpsshead->next;}if (tcpsshead->tcplisthead == NULL){cnt += len;tcpnode* tcpnodehead = (tcpnode*)malloc(sizeof(tcpnode));tcpsshead->tcplisthead = tcpnodehead;tcpnodehead->prev = tcpsshead->tcplisthead;tcpnodehead->syn = tcp_protocol->syn;tcpnodehead->fin = tcp_protocol->fin;tcpnodehead->seq = ntohl(tcp_protocol->seq);tcpnodehead->len = len;tcpnodehead->next = NULL;for (int i = 0; i < tcpnodehead->len; i++)tcpnodehead->data[i] = packet_content[i + sizeof(ether_header)+sizeof(ip_header) + tcp_protocol->tcp_header_length * 4];}else{tcpnode* tcpnodehead = tcpsshead->tcplisthead;tcpnode* tcpnewnode = (tcpnode*)malloc(sizeof(tcpnode));tcpnewnode->syn = tcp_protocol->syn;tcpnewnode->fin = tcp_protocol->fin;tcpnewnode->seq = ntohl(tcp_protocol->seq);tcpnewnode->len = len;tcpnewnode->next = NULL;for (int i = 0; i < tcpnewnode->len; i++){tcpnewnode->data[i] = packet_content[i + sizeof(ether_header) + sizeof(ip_header) + tcp_protocol->tcp_header_length * 4];}if (tcp_protocol->fin == 1)flag1 = 1;if (tcpnodehead->seq > tcpnewnode->seq){cnt += len;tcpsshead->tcplisthead = tcpnewnode;tcpnewnode->prev = tcpsshead->tcplisthead;tcpnewnode->next = tcpnodehead;tcpnodehead->prev = tcpnewnode;}else{cnt += len;while (tcpnodehead->seq < tcpnewnode->seq){if (&tcpnodehead->next == NULL||tcpnodehead->next->seq > tcpnewnode->seq){tcpnewnode->prev = tcpnodehead;tcpnewnode->next = tcpnodehead->next;tcpnodehead->next = tcpnewnode;tcpnodehead->next->prev = tcpnewnode;break;}elsetcpnodehead = tcpnodehead->next;}}}return cnt;}void print(FILE* file, tcpss* tcpsessionhead){tcpss* tcpsshead = tcpsessionhead;while (!search(tcpsshead)){tcpsshead = tcpsshead->next;}tcpnode* tcpnodehead=tcpsshead->tcplisthead;while (tcpnodehead->next != NULL){for (int i = 1; i < tcpnodehead->len; i++){printf("%c", tcpnodehead->data[i - 1]);fprintf(file, "%c", tcpnodehead->data[i - 1]);}//if (tcpnodehead->next == NULL)//break;//elsetcpnodehead = tcpnodehead->next;}}
#include "pcap.h"const int MAXETHERLEN = 1500;struct ether_header{u_int8_t ether_dhost[6];//目的mac;u_int8_t ether_shost[6];//源mac;u_int16_t ether_type;};/*ip地址*/typedef struct ip_address{u_char byte1;u_char byte2;u_char byte3;u_char byte4;} ip_address;/*IPv4协议头*/struct ip_header{#if defined(WORDS_BIENDIAN)u_int8_t ip_version : 4, ip_header_length : 4;#elseu_int8_t ip_header_length : 4, ip_version : 4;#endifu_int8_t ip_tos;u_int16_t ip_length;u_int16_t ip_id;u_int16_t ip_off;u_int8_t ip_ttl;u_int8_t ip_protocol;u_int16_t ip_checksum;ip_address saddr; /*源地址(Source address)*/ip_address daddr; /*目的地址(Destination address)*/};//TCP协议头#define __LITTLE_ENDIAN_BITFIELDstruct tcphdr{u_int16_t source_port; /*源地址端口*/u_int16_t dest_port; /*目的地址端口*/u_int32_t seq; /*序列号*/u_int32_t ack_seq; /*确认序列号*/u_int8_t res1 : 3, /*偏移*/doff : 1, /*保留*/tcp_header_length : 4;u_int8_t fin : 1, /*关闭连接标志*/syn : 1, /*请求连接标志*/rst : 1, /*重置连接标志*/psh : 1, /*接收方尽快将数据放到应用层标志*/ack : 1, /*确认序号标志*/urg : 1, /*紧急指针标志*/ece : 1, /*拥塞标志位*/cwr : 1; /*拥塞标志位*/u_int16_t flag;u_int16_t window; /*滑动窗口大小*/u_int16_t check; /*校验和*/u_int16_t urg_ptr; /*紧急字段指针*/};/*两个链表*//*list.1==tcplist*/typedef struct tcpnode{int syn;int fin;unsigned long seq;int len;tcpnode *prev;tcpnode *next;unsigned char data[MAXETHERLEN];}node;/*list.2=tcpsession*/typedef struct tcpsession{ip_address saddr;ip_address daddr;unsigned short sport;unsigned short dport;tcpsession* next;tcpnode *tcplisthead;}tcpss;tcpsession* createtcpsession(tcpss *tcpsessionhead);bool isempty(tcpss* tcpsessionhead);bool search(tcpss *head);int insert(tcpss* tcpsessionheadconst, u_int32_t &cnt, int &flag1);void print(FILE* file, tcpss* tcpsessionhead);struct pcap_pkthdr *header;const u_char *packet_content;struct ether_header *ethernet_protocol;struct ip_header *ip_protocol;struct tcphdr *tcp_protocol;tcpsession* tcpsessionhead = (tcpsession*)malloc(sizeof(tcpsession));tcpsession* tcpsshead = tcpsessionhead;int flag = 0;u_int32_t fin_seq = 0;u_int32_t syn_seq = 0;u_int32_t cnt = 0;int flag1;int len;int main(int argc, char* argv[]){if (argc <= 1){printf("argc<=1,break!\n");return -1;}pcap_t *adapterHandle;//适配器句柄;char errorBuffer[PCAP_ERRBUF_SIZE];//错误缓冲区;char source[PCAP_BUF_SIZE];if (pcap_createsrcstr(source, PCAP_SRC_FILE, NULL, NULL, argv[1], errorBuffer) != 0){printf("数据源创建失败!\n");return -1;}if ((adapterHandle = pcap_open(source, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errorBuffer)) == NULL){printf("文件打开失败!\n");return -1;}tcpsessionhead->next = NULL;;tcpsshead->next = NULL;tcpsessionhead->tcplisthead = NULL;tcpsshead->tcplisthead = NULL;FILE* file1,*file2;if (fopen_s(&file1, argv[2], "w+") != 0){printf("打开文件失败!\n");}if (fopen_s(&file2, argv[3], "w+") != 0){printf("打开文件失败!\n");}int pkt_number = 1;int res;int flag3 = 0;while ((res = pcap_next_ex(adapterHandle, &header, &packet_content)) >= 0){if (res == 0)/* 超时时间到 */continue;printf("这是第%d个数据包!\n", pkt_number++);/*for (int i = 1; i <= header->len; i++){printf("%02x ", packet_content[i - 1]);if (i % 8 == 0)printf(" ");if (i % 16 == 0)printf("\n");}printf("\n");*/ethernet_protocol = (struct ether_header*)packet_content;ip_protocol = (struct ip_header *)(packet_content + sizeof(ether_header));tcp_protocol = (struct tcphdr *) (packet_content + sizeof(ether_header) + sizeof(ip_header));int ip_len = ntohs(ip_protocol->ip_length);printf("%d.%d.%d.%d\n", ip_protocol->saddr.byte1, ip_protocol->saddr.byte2, ip_protocol->saddr.byte3, ip_protocol->saddr.byte4);printf("%d.%d.%d.%d\n", ip_protocol->daddr.byte1, ip_protocol->daddr.byte2, ip_protocol->daddr.byte3, ip_protocol->daddr.byte4);len = ip_len - sizeof(ip_header) - tcp_protocol->tcp_header_length * 4;printf("长度:%d %d\n", ip_len - sizeof(ip_header) - tcp_protocol->tcp_header_length * 4, sizeof(ip_header) + tcp_protocol->tcp_header_length * 4);printf("%02x %02x\n", ntohs(tcp_protocol->source_port), ntohs(tcp_protocol->dest_port));printf("%u %u\n", ntohl(tcp_protocol->seq), ntohl(tcp_protocol->ack_seq));printf("syn and fin:%d %d\n", tcp_protocol->syn, tcp_protocol->fin);if (tcp_protocol->syn == 1){tcpsshead=createtcpsession(tcpsshead);}else if (tcp_protocol->syn == 0 && tcp_protocol->fin == 0 && len>0){cnt = insert(tcpsessionhead, cnt, flag1);}else if (tcp_protocol->fin == 1){if (flag3 == 0){print(file1,tcpsessionhead);///fclose(file1);flag3 = 1;}else{print(file2, tcpsessionhead);//fclose(file2);}}printf("\n");}if (res == -1){printf("Error reading the packets: %s\n", pcap_geterr(adapterHandle));return -1;}return 0;}tcpsession* createtcpsession(tcpss *tcpsessionhead){tcpss *root = tcpsessionhead;while (!isempty(root)){root = root->next;}root->saddr.byte1 = ip_protocol->saddr.byte1;root->saddr.byte2 = ip_protocol->saddr.byte2;root->saddr.byte3 = ip_protocol->saddr.byte3;root->saddr.byte4 = ip_protocol->saddr.byte4;root->daddr.byte1 = ip_protocol->daddr.byte1;root->daddr.byte2 = ip_protocol->daddr.byte2;root->daddr.byte3 = ip_protocol->daddr.byte3;root->daddr.byte4 = ip_protocol->daddr.byte4;root->sport = tcp_protocol->source_port;root->dport = tcp_protocol->dest_port;root->next = (tcpss*)malloc(sizeof(tcpss));root->next->next = NULL;root->next->tcplisthead = NULL;return root;}bool isempty(tcpss* tcpsessionhead){if (tcpsessionhead->next == NULL)return true;elsereturn false;}bool search(tcpss *head){if ((head->saddr.byte1 == ip_protocol->saddr.byte1&&head->saddr.byte2 == ip_protocol->saddr.byte2&&head->saddr.byte3 == ip_protocol->saddr.byte3&&head->saddr.byte4 == ip_protocol->saddr.byte4&&head->daddr.byte1 == ip_protocol->daddr.byte1&&head->daddr.byte2 == ip_protocol->daddr.byte2&&head->daddr.byte3 == ip_protocol->daddr.byte3&&head->daddr.byte4 == ip_protocol->daddr.byte4&&head->sport == tcp_protocol->source_port&&head->dport == tcp_protocol->dest_port))return true;elsereturn false;}int insert(tcpss* tcpsessionhead, u_int32_t &cnt, int &flag1){tcpss* tcpsshead = tcpsessionhead;while (!search(tcpsshead)){tcpsshead = tcpsshead->next;}if (tcpsshead->tcplisthead == NULL){cnt += len;tcpnode* tcpnodehead = (tcpnode*)malloc(sizeof(tcpnode));tcpsshead->tcplisthead = tcpnodehead;tcpnodehead->prev = tcpsshead->tcplisthead;tcpnodehead->syn = tcp_protocol->syn;tcpnodehead->fin = tcp_protocol->fin;tcpnodehead->seq = ntohl(tcp_protocol->seq);tcpnodehead->len = len;tcpnodehead->next = NULL;for (int i = 0; i < tcpnodehead->len; i++)tcpnodehead->data[i] = packet_content[i + sizeof(ether_header)+sizeof(ip_header) + tcp_protocol->tcp_header_length * 4];}else{tcpnode* tcpnodehead = tcpsshead->tcplisthead;tcpnode* tcpnewnode = (tcpnode*)malloc(sizeof(tcpnode));tcpnewnode->syn = tcp_protocol->syn;tcpnewnode->fin = tcp_protocol->fin;tcpnewnode->seq = ntohl(tcp_protocol->seq);tcpnewnode->len = len;tcpnewnode->next = NULL;for (int i = 0; i < tcpnewnode->len; i++){tcpnewnode->data[i] = packet_content[i + sizeof(ether_header) + sizeof(ip_header) + tcp_protocol->tcp_header_length * 4];}if (tcp_protocol->fin == 1)flag1 = 1;if (tcpnodehead->seq > tcpnewnode->seq){cnt += len;tcpsshead->tcplisthead = tcpnewnode;tcpnewnode->prev = tcpsshead->tcplisthead;tcpnewnode->next = tcpnodehead;tcpnodehead->prev = tcpnewnode;}else if(tcpnodehead->seq < tcpnewnode->seq){cnt += len;while (tcpnodehead->seq < tcpnewnode->seq){if (tcpnodehead->next == NULL||tcpnodehead->next->seq > tcpnewnode->seq){tcpnewnode->prev = tcpnodehead;tcpnewnode->next = tcpnodehead->next;tcpnodehead->next = tcpnewnode;tcpnodehead->next->prev = tcpnewnode;break;}elsetcpnodehead = tcpnodehead->next;}}}return cnt;}void print(FILE* file, tcpss* tcpsessionhead){tcpss* tcpsshead = tcpsessionhead;while (!search(tcpsshead)){tcpsshead = tcpsshead->next;}tcpnode* tcpnodehead=tcpsshead->tcplisthead;while (tcpnodehead->next != NULL){for (int i = 1; i < tcpnodehead->len; i++){printf("%c", tcpnodehead->data[i - 1]);fprintf(file, "%c", tcpnodehead->data[i - 1]);}//if (tcpnodehead->next == NULL)//break;//elsetcpnodehead = tcpnodehead->next;}}