void do_tcp(void *p) { g.packet_tcp++; if(g.print_flag_tcp) print_tcp(p); }
void do_tcp( char * data ) { global.packet_tcp ++; struct tcphdr * ptcp; ptcp = ( struct tcphdr * )data; if( global.print_flag_tcp ) print_tcp( ptcp ); }
static void print_ipv4(FILE* dst, const struct ip* ip, bool compact){ void* payload = ((char*)ip) + 4*ip->ip_hl; fprintf(dst, ";IPv4[%d/", 4*ip->ip_hl); if(!compact){ fprintf(dst, "%d/",(u_int16_t)ntohs(ip->ip_len)); fprintf(dst, "%d",(u_int8_t)ip->ip_ttl); } else { fprintf(dst, "Len=%d:",(u_int16_t)ntohs(ip->ip_len)); fprintf(dst, "ID=%d:",(u_int16_t)ntohs(ip->ip_id)); fprintf(dst, "TTL=%d:",(u_int8_t)ip->ip_ttl); fprintf(dst, "Chk=%d:",(u_int16_t)ntohs(ip->ip_sum)); } if(ntohs(ip->ip_off) & IP_DF) { fprintf(dst, "DF"); } if(ntohs(ip->ip_off) & IP_MF) { fprintf(dst, "MF"); } if(!compact){ fprintf(dst, "] ; "); } else { fprintf(dst, " Tos=%0x];\t",(u_int8_t)ip->ip_tos); } switch( ip->ip_p ) { case IPPROTO_TCP: print_tcp(dst, ip, (const struct tcphdr*)payload,compact); break; case IPPROTO_UDP: print_udp(dst, ip, (const struct udphdr*)payload,compact); break; case IPPROTO_ICMP: print_icmp(dst, ip, (const struct icmphdr*)payload,compact); break; case IPPROTO_IGMP: fprintf(dst, "IGMP"); break; default: fprintf(dst, "Unknown transport protocol: %d \n", ip->ip_p); break; } }
int main(int argc, char **argv) { int raw_mode = 0; struct GlobalHeader ghead; // parameter check if(argc == 1) { raw_mode = 0; } else if(argc == 2) { if(0 != strcmp(argv[1], "-r")) { usage(); return 0; } raw_mode = 1; } else { usage(); return 0; } // read global header if(!raw_mode) { // XXX Should check link type and record snapshot length. fread(&ghead, sizeof(unsigned char), sizeof(struct GlobalHeader), stdin); if(ghead.magic != MAGIC_NUMBER) { printf("invalid file format\n"); return 0; } printf("PCAP format v%d.%d, ", ghead.majorver, ghead.minorver); if(ghead.linklayertype != 1) { printf("unsupported link layer type\n"); return 0; } printf("link layer type: Ethernet.\n"); } // read each packet while (1) { int i; struct PacketHeader phead; struct EthernetHeader ehead; printf("\n"); // packet header if (!raw_mode) { // XXX Should use length information in decoding below. if(sizeof(struct PacketHeader) != fread(&phead, sizeof(unsigned char), sizeof(struct PacketHeader), stdin)) break; if(phead.packetsize > ghead.snapshotlength) { printf("wrong packet at 0x%08x\n", (int)ftell(stdin)); return 0; } printf("<<<PCAP packet\n"); printf(" packet size: %d\n", phead.packetsize); printf(" payload size: %d\n", phead.payloadsize); } // data captured from wire get_ether(&ehead); print_ether(&ehead); if (ehead.length_type <= 1500) { // old style packet printf("Old style packet, length = %d\n", ehead.length_type); printf("We don't support this packet now\n"); if (!raw_mode) { dump(phead.packetsize-sizeof(ehead), 1); } } else if (ehead.length_type == 0x0800) { // ASSIGNMENT: MODIFY THIS TO PRINT INFORMATION ABOUT ENCAPSULATED PAYLOAD. struct IPv4Header ipv4head; get_ipv4(&ipv4head); print_ipv4(&ipv4head); if(ipv4head.protocol == 4) { printf("IP packet\n"); printf("Wedon't support this packet now\n"); dump(ipv4head.datalen-sizeof(ipv4head), 1); } else if(ipv4head.protocol == 6) { struct TCPHeader tcphead; get_tcp(&tcphead); print_tcp(&tcphead); // get payload in TCP packet //dump(ipv4head.datalen-sizeof(ipv4head)-sizeof(tcphead), 2); if(phead.packetsize >= sizeof(ehead)+ipv4head.datalen) { dump(ipv4head.datalen-sizeof(ipv4head)-sizeof(tcphead), 0); } else { dump((ipv4head.datalen-sizeof(ipv4head)-sizeof(tcphead))-(sizeof(ehead)+ipv4head.datalen-phead.packetsize), 0); } } else if(ipv4head.protocol == 17) { struct UDPHeader udphead; get_udp(&udphead); assert(udphead.size == ipv4head.datalen-sizeof(ipv4head)); print_udp(&udphead); // get payload in UDP packet if(phead.packetsize >= sizeof(ehead)+ipv4head.datalen) { dump(udphead.size-sizeof(udphead), 0); } else { dump((udphead.size-sizeof(udphead))-(sizeof(ehead)+ipv4head.datalen-phead.packetsize), 0); } } else { printf("Unexpected IP packet\n"); dump(ipv4head.datalen-sizeof(ipv4head), 1); } if(!raw_mode) { if(phead.packetsize > sizeof(ehead)+ipv4head.datalen) { printf("pad:\n"); dump(phead.packetsize-sizeof(ehead)-ipv4head.datalen, 1); } } } else if(ehead.length_type == 0x0806) { printf("ARP packet\n"); printf("We don't support this packet now\n"); if (!raw_mode) { dump(phead.packetsize-sizeof(ehead), 1); } } else if(ehead.length_type == 0x86DD) { printf("IPv6 packet\n"); printf("We don't support this packet now\n"); if (!raw_mode) { dump(phead.packetsize-sizeof(ehead), 1); } } else { printf("Unexpected Ethernet packet\n"); if (!raw_mode) { dump(phead.packetsize-sizeof(ehead), 1); } } } return 0; }