bool IPAddress::parse_packet( IPAddress & src, IPAddress & dst, size_t packet_length, uint8_t const * packet) { // Determine the IP version and address field offsets. IPAddress::Version ip_version; size_t src_address_offset; size_t dst_address_offset; if (packet_length >= 20 && IP_VERSION(packet) == 4) { ip_version = IPAddress::IPv4; src_address_offset = 12; dst_address_offset = 16; } else if (packet_length >= 40 && IP_VERSION(packet) == 6) { ip_version = IPAddress::IPv6; src_address_offset = 8; dst_address_offset = 24; } else { return false; } // Extract the IP addresses. src.mVersion = ip_version; memcpy( src.mBytes, packet + src_address_offset, IPAddress::LENGTHS[ip_version]); dst.mVersion = ip_version; memcpy( dst.mBytes, packet + dst_address_offset, IPAddress::LENGTHS[ip_version]); return true; }
/* callback() pcap callback */ void callback(unsigned char *string, const struct pcap_pkthdr *framehdr, const unsigned char buf[]) { time_t timestamp = framehdr->ts.tv_sec; int usecs = framehdr->ts.tv_usec; int max_offset = framehdr->caplen; iphdr ip; tcphdr tcp; /* make sure the frame is long enough */ if (max_offset < 14 + 20 + 20) return; /* make sure it's ethernet */ if (ex16(buf,12) != 0x0800) return; /* IP */ ip.offset = 14; if (IP_VERSION(buf,ip.offset) != 4) return; ip.proto = IP_PROTOCOL(buf,ip.offset); ip.src = IP_SRC(buf,ip.offset); ip.dst = IP_DST(buf,ip.offset); ip.data_offset = ip.offset + IP_SIZEOF_HDR(buf,ip.offset); if (max_offset > IP_TOTALLENGTH(buf,ip.offset) + ip.offset) ip.max_offset = IP_TOTALLENGTH(buf,ip.offset) + ip.offset; else ip.max_offset = max_offset; /* UDP */ if (ip.proto != 17 ) return; tcp.offset = ip.data_offset; tcp.dst = TCP_DST(buf,tcp.offset); tcp.src = TCP_SRC(buf,tcp.offset); tcp.data_offset = tcp.offset + 8; #ifdef DO_DUMP pcap_dump(NULL, framehdr, (buf)); #endif examine(timestamp, usecs, &ip, &tcp, buf); return; }
void process_packet(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet) { int i = 0; int *counter = (int *)arg; const struct ethernet_head *ethernet = NULL; const struct ip_head *ip = NULL; const struct tcp_head *tcp = NULL; const u_char *payload = NULL; int payload_len = 0; printf("packet count : %d\n", ++(*counter)); printf("receive packet size : %d\n", pkthdr->len); printf("payload : \n"); for (i = 0; i < pkthdr->len; ++i) { if (i % 16 == 0 && i != 0) printf("\n"); if (isprint(packet[i])) printf("%c ", packet[i]); else printf(". "); } printf("\n"); // 数据包解析 ethernet = (struct ethernet_head *)packet; // 链路层 printf("ethernet(%lu)\n", sizeof(struct ethernet_head)); printf("源mac地址 : %02X-%02X-%02X-%02X-%02X-%02X => ", ethernet->source_mac[0], ethernet->source_mac[1], ethernet->source_mac[2], ethernet->source_mac[3], ethernet->source_mac[4], ethernet->source_mac[5]); printf("目的mac地址 : %02X-%02X-%02X-%02X-%02X-%02X\n", ethernet->dest_mac[0], ethernet->dest_mac[1], ethernet->dest_mac[2], ethernet->dest_mac[3], ethernet->dest_mac[4], ethernet->dest_mac[5]); // printf("ethernet协议号 : %04X\n", (unsigned short)ntohs(ethernet->type)); // ip层 arp层 if ((unsigned short)ntohs(ethernet->type) == 0x0800) { ip = (struct ip_head *)(packet + sizeof(struct ethernet_head)); printf("ipv%d(%d)\n", IP_VERSION(ip), IP_HEAD_LEN(ip) * 4); // printf("ip version : %d\n", IP_VERSION(ip)); // ip层的头部长度 // printf("ip header len : %d\n", IP_HEAD_LEN(ip) * 4); // total len 首部+数据部分 // printf("total len : %d\n", ntohs(ip->total_len)); // protocol // printf("protocol : %d\n", ip->protocol); printf("源ip地址 : %d.%d.%d.%d => ", ip->source_ip[0], ip->source_ip[1], ip->source_ip[2], ip->source_ip[3]); printf("目的ip地址 : %d.%d.%d.%d\n", ip->dest_ip[0], ip->dest_ip[1], ip->dest_ip[2], ip->dest_ip[3]); // 应用层 // printf("%d\n", ip->protocol); if (ip->protocol == 6) { // tcp tcp = (struct tcp_head *)(packet + sizeof(struct ethernet_head) + IP_HEAD_LEN(ip) * 4); printf("tcp(%d)\n", TCP_HEAD_LEN(tcp) * 4); // printf("%d\n", TCP_HEAD_LEN(tcp)); printf("源port : %d => 目的port : %d\n", ntohs(tcp->source_port), ntohs(tcp->dest_port)); payload = (u_char *)(packet + sizeof(struct ethernet_head) + IP_HEAD_LEN(ip) * 4 + TCP_HEAD_LEN(tcp) * 4); payload_len = ntohs(ip->total_len) - (IP_HEAD_LEN(ip) * 4 + TCP_HEAD_LEN(tcp) * 4 ); printf("payload_len %d\n", payload_len); // test for http // todo if ((ntohs(tcp->source_port) == 80) || (ntohs(tcp->dest_port) == 80)) { printf("http包体:\n"); int j = 0; u_char *ptr = payload; for (j = 0; j < payload_len; j++, ptr++) { printf("%c", *ptr); } // todo // 数据包需要组装、拼接,显示 // char buf[4000]; // memcpy(buf, payload, payload_len); // *(buf + payload_len) = 0; // printf("%s\n", buf); } } if (ip->protocol == 17) { // udp printf("udp\n"); } if (ip->protocol == 47) { // pptp } } if ((unsigned short)ntohs(ethernet->type) == 0x0806) { printf("arp\n"); } printf("-------------------------------------------------------------------\n"); }