libpcap报文解析: ipv4、ipv6 @ 2014.7.2
2014-07-02 23:56
323 查看
#include <string.h> #include <stdlib.h> #include <pcap.h> #include <stdio.h> #include <sys/time.h> #include <unistd.h> #include <netinet/in.h> #include <pthread.h> #include "packet_header.h" #include <iostream> #include <string> using namespace std; #define MAXBYTE2CAPTURE 2048 pthread_t g_thread[2]; pthread_mutex_t g_mutex; int isprint(char c) { return 0; } void print_buf(u_char* pBuf, u_int32 len) { if (!pBuf) { return; } for(int i=0; i<len; i++) { printf("%02x ", (u_char*)pBuf[i]); if ((i%16 == 0 && i!=0) || i == len-1) { printf("\r\n"); } } } void parse_ethII(u_char* pData, u_int32 len) { if (!pData || len <14) { return; } printf("eth II frame: \r\n"); print_buf(pData, 14); /* parse src mac and dst mac */ EthHeader_t* pEth = (EthHeader_t*)pData; printf("destination: %02x:%02x:%02x:%02x:%02x:%02x ", pEth->dest_hwaddr[0], pEth->dest_hwaddr[1], pEth->dest_hwaddr[2], pEth->dest_hwaddr[3], pEth->dest_hwaddr[4], pEth->dest_hwaddr[5]); printf("source : %02x:%02x:%02x:%02x:%02x:%02x", pEth->source_hwaddr[0], pEth->source_hwaddr[1], pEth->source_hwaddr[2], pEth->source_hwaddr[3], pEth->source_hwaddr[4], pEth->source_hwaddr[5]); /* parse frame type */ printf("\r\nframe type: 0x%x\r\n", ntohs(pEth->frame_type)); } void parse_ipheader(u_char* pData, u_int32 len) { if (!pData || len <14) { return; } printf("ip header: \r\n"); print_buf(pData, 20); /* parse ip header */ IPHeader_t* pIpHeader = (IPHeader_t*)pData; printf("\tversion : %02x\r\n" "\ttos : %02x\r\n" "\ttotal length: %d(0x%02x)\r\n" "\tid : %d(0x%02x)\r\n" "\tsegment flag: %d(0x%02x)\r\n" "\tttl : %02x\r\n" "\tprotocol : %02x\r\n" "\tchecksum : %d(0x%02x)\r\n" "\tsrc ip : %d.%d.%d.%d\r\n" "\tdst ip : %d.%d.%d.%d\r\n", pIpHeader->Ver_HLen, pIpHeader->TOS, ntohs(pIpHeader->TotalLen), ntohs(pIpHeader->TotalLen), ntohs(pIpHeader->ID), ntohs(pIpHeader->ID), ntohs(pIpHeader->Flag_Segment), ntohs(pIpHeader->Flag_Segment), pIpHeader->TTL, pIpHeader->Protocol, ntohs(pIpHeader->Checksum), ntohs(pIpHeader->Checksum), pIpHeader->SrcIP[0],pIpHeader->SrcIP[1],pIpHeader->SrcIP[2],pIpHeader->SrcIP[3], pIpHeader->DstIP[0],pIpHeader->DstIP[1],pIpHeader->DstIP[2],pIpHeader->DstIP[3]); } void parse_ip6header(u_char* pData, u_int32 len) { if (!pData || len <14) { return; } printf("ipv6 header: \r\n"); print_buf(pData, 40); /* parse ipv6 header */ IPv6Header_t* pIpv6Header = (IPv6Header_t*)pData; printf("\tversion : %x\r\n" "\ttraffic class : %x\r\n" "\tflow label : %x\r\n" "\tpayload length : %x\r\n" "\tnext header : %x\r\n" "\thop limit : %x\r\n" "\tsource : %x\r\n" "\tdestination : %x\r\n", pIpv6Header->ip6_ctlun.ip6_un2_vfc, pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_flow, pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_flow, pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_plen, pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_nxt, pIpv6Header->ip6_ctlun.ip6_unl.ip6_unl_hlim, pIpv6Header->ip6_src, pIpv6Header->ip6_dst); } void parse_packet(const u_char* packet, u_int32 len) { u_short ftype = 0; if (!packet) { return ; } u_char* pMbuf = (u_char*)packet; parse_ethII(pMbuf, len); ftype = ntohs(((EthHeader_t*)pMbuf)->frame_type); switch(ftype) { case 0x0800: /* ipv4 */ pMbuf = (u_char*)packet + 14; parse_ipheader(pMbuf, len-14); break; case 0x86dd: /* ipv6 */ pMbuf = (u_char*)packet + 14; parse_ip6header(pMbuf, len-14); break; default: printf("frame type : 0x%x\r\n", ftype); break; } printf("\r\n"); } void processPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet) { int i = 0, *counter = (int *)arg; printf("--------------------------------------------\r\n"); printf("Packet Count: %d\n", ++(*counter)); printf("Received Packet Size: %d\n", pkthdr->len); printf("Payload:\n"); #if 1 for (i = 0; i < pkthdr->len; i++) { if (isprint(packet[i])) { printf("%02d ", packet[i]); } else { printf("%02x ", packet[i]); } if ((i % 16 == 0 && i != 0) || i == pkthdr->len-1) { printf("\n"); } } #endif parse_packet(packet, pkthdr->len); return; } void* thread_recv_pkt(void *) { while(1) { cout << "recv pkt: " << endl; sleep(1); } } void* thread_send_pkt(void *) { while (1) { cout << "send pkt: " << endl; sleep(1); } } int create_pkt_process_task() { int ret = 0; memset(&g_thread, 0, sizeof(g_thread)); ret = pthread_create(&g_thread[0], NULL, thread_send_pkt, NULL); if (0 == ret) { cout << "packet send thread create successfully." << endl; } else { cout << "packet send thread create failed." << endl; } ret = pthread_create(&g_thread[1], NULL, thread_recv_pkt, NULL); if (0 == ret) { cout << "packet send thread create successfully." << endl; } else { cout << "packet send thread create failed." << endl; } return 0; } void pkt_process_task_wait() { if(g_thread[0] !=0) { //comment4 pthread_join(g_thread[0],NULL); printf("线程1 已经结束\n"); } if(g_thread[1] !=0) { //comment5 pthread_join(g_thread[1],NULL); printf("线程2 已经结束\n"); } } int main() { int i = 0, count = 0; pcap_t *descr = NULL; char errbuf[PCAP_ERRBUF_SIZE], *device = NULL; memset(errbuf, 0, PCAP_ERRBUF_SIZE); create_pkt_process_task(); pkt_process_task_wait(); /* Get the name of the first device suitable for capture */ device = pcap_lookupdev(errbuf); if (!device) { printf("Open device failed."); return -1; } printf("Opening device %s\n", device); /* Open device in promiscuous mode */ descr = pcap_open_live(device, MAXBYTE2CAPTURE, 1, 512, errbuf); /* Loop forever & call processPacket() for every received packet */ pcap_loop(descr, -1, processPacket, (u_char *)&count); return 0; }
相关文章推荐
- libpcap报文解析: ipv4、ipv6 @ 2014.7.2
- libpcap报文解析: ipv4、ipv6(待优化)
- libpcap报文解析: ipv4、ipv6(待优化)
- 解析IPV4报文 和IPV6 报文的 checksum
- 解析IPV4报文 和IPV6 报文的 checksum 的算法
- 理解并取证:ICMPV6代替IPV4中的ARP进行IPv6的MAC地址解析
- 理解并取证:IPv6与IPv4在报文结构上的区别
- IPv4与IPv6数据报格式解析
- 承载于以太网帧之上的数据包的解析——ARP、IPv4、IPv6
- getaddrinfo 进行域名解析 ipv4 and ipv6
- 承载于以太网帧之上的数据包的解析——ARP、IPv4、IPv6
- mr解析xml将数据(ipv4、ipv6)批量导入hbase
- IPv6终于要取代IPv4了!阿里云将全面提供IPv6服务
- 第11章 拾遗5:IPv6和IPv4共存技术(2)_ISATAP隧道技术
- UNXI网络编程笔记 第12章IPV4与IPV6的互操作性
- RR报文解析(三)利用LSR, DLSR计算RTT
- 从IPV4到IPV6之双栈
- C++ IPv4与IPv6的兼容编码
- IPv6使用隧道穿越IPv4网络