📄 decode.c
字号:
{ ErrorMessage("SLIP header length < captured len! (%d bytes)\n", cap_len); return; } DecodeIP(p->pkt + SLIP_HEADER_LEN, cap_len - SLIP_HEADER_LEN, p);}/* * Function: DecodeRawPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*) * * Purpose: Decodes packets coming in raw on layer 2, like PPP. Coded and * in by Jed Pickle (thanks Jed!) and modified for a few little tweaks * by me. * * Arguments: p => pointer to decoded packet struct * user => Utility pointer, unused * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */void DecodeRawPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt){ bzero((char *) p, sizeof(Packet)); p->pkth = pkthdr; p->pkt = pkt;#ifdef DEBUG printf("Packet!\n");#endif DecodeIP(pkt, p->pkth->caplen, p); return;}/* * Function: DecodeI4LRawIPPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*) * * Purpose: Decodes packets coming in raw on layer 2, like PPP. Coded and * in by Jed Pickle (thanks Jed!) and modified for a few little tweaks * by me. * * Arguments: p => pointer to decoded packet struct * user => Utility pointer, unused * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */void DecodeI4LRawIPPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt){ bzero((char *) p, sizeof(Packet)); p->pkth = pkthdr; p->pkt = pkt;#ifdef DEBUG printf("Packet!\n");#endif DecodeIP(pkt + 2, p->pkth->len - 2, p); return;}/* * Function: DecodeI4LCiscoIPPkt(Packet *, char *, * struct pcap_pkthdr*, u_int8_t*) * * Purpose: Decodes packets coming in raw on layer 2, like PPP. Coded and * in by Jed Pickle (thanks Jed!) and modified for a few little tweaks * by me. * * Arguments: p => pointer to decoded packet struct * user => Utility pointer, unused * pkthdr => ptr to the packet header * pkt => pointer to the real live packet data * * Returns: void function */void DecodeI4LCiscoIPPkt(Packet *p, struct pcap_pkthdr *pkthdr, u_int8_t *pkt){ bzero((char *) p, sizeof(Packet)); p->pkth = pkthdr; p->pkt = pkt;#ifdef DEBUG printf("Packet!\n");#endif DecodeIP(pkt + 4, p->pkth->caplen - 4, p); return;}/* * Function: DecodeIP(u_int8_t *, const u_int32_t, Packet *) * * Purpose: Decode the IP network layer * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to the packet decode struct * * Returns: void function */void DecodeIP(u_int8_t * pkt, const u_int32_t len, Packet * p){ u_int32_t ip_len; /* length from the start of the ip hdr to the * pkt end */ u_int32_t hlen; /* ip header length */ u_int16_t csum; /* checksum */ /* lay the IP struct over the raw data */ p->iph = (IPHdr *) pkt;#ifdef DEBUG printf("ip header starts at: %p, length is %lu\n", p->iph, (unsigned long) len);#endif /* do a little validation */ if(len < IP_HEADER_LEN) { if(pv.verbose_flag) { ErrorMessage("IP header truncated! (%d bytes)\n", len); } p->iph = NULL; return; } /* * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP. * So we are just ignoring non IP datagrams */ if(p->iph->ip_ver != 4) { if(pv.verbose_flag) { ErrorMessage("[!] WARNING: Not IPv4 datagram! ([ver: 0x%x][len: 0x%x])\n", p->iph->ip_ver, p->iph->ip_len); } if(pv.logbin_flag) LogBin(p, NULL, NULL); p->iph = NULL; pc.discards++; return; } /* set the IP datagram length */ ip_len = ntohs(p->iph->ip_len); /* set the IP header length */ hlen = p->iph->ip_hlen << 2; if (ip_len != len) { if (ip_len > len) {#ifdef DEBUG if (pv.verbose_flag) ErrorMessage("[!] WARNING: IP Len field is %d bytes bigger than captured length.\n" " (ip.len: %lu, cap.len: %lu)\n", ip_len - len, ip_len, len);#endif ip_len = len; } else {#ifdef DEBUG if (pv.verbose_flag) ErrorMessage("[!] WARNING: IP Len field is %d bytes smaller than captured length.\n" " (ip.len: %lu, cap.len: %lu)\n", len - ip_len, ip_len, len);#endif } } if(ip_len < hlen) { if(pv.verbose_flag) { ErrorMessage("[!] WARNING: IP dgm len (%d bytes) < IP hdr len (%d bytes), packet discarded\n", ip_len, hlen); } if(pv.logbin_flag) LogBin(p, NULL, NULL); p->iph = NULL; pc.discards++; return; } csum = checksum((u_short *)p->iph, hlen, (u_short *)NULL, 0); if(csum) { p->csum_flags |= CSE_IP;#ifdef DEBUG printf("Bad IP checksum\n");#endif }#ifdef DEBUG else { printf("IP Checksum: OK\n"); }#endif /* test for IP options */ if(p->iph->ip_hlen > 5) { DecodeIPOptions((pkt + IP_HEADER_LEN), hlen - IP_HEADER_LEN, p); } else { p->ip_option_count = 0; } /* set the remaining packet length */ ip_len -= hlen; /* check for fragmented packets */ p->frag_offset = ntohs(p->iph->ip_off); /* get the values of the reserved, more fragments and don't fragment flags */ p->rf = (p->frag_offset & 0x8000) >> 15; p->df = (p->frag_offset & 0x4000) >> 14; p->mf = (p->frag_offset & 0x2000) >> 13; /* mask off the high bits in the fragment offset field */ p->frag_offset &= 0x1FFF; if(p->frag_offset || p->mf) { /* set the packet fragment flag */ p->frag_flag = 1; pc.frags++; } /* if this packet isn't a fragment */ if(!(p->frag_flag)) { /* set the packet fragment flag */ p->frag_flag = 0;#ifdef DEBUG printf("IP header length: %lu\n", (unsigned long)hlen);#endif switch(p->iph->ip_proto) { case IPPROTO_TCP: pc.tcp++; DecodeTCP(pkt + hlen, ip_len, p); ClearDumpBuf(); return; case IPPROTO_UDP: pc.udp++; DecodeUDP(pkt + hlen, ip_len, p); ClearDumpBuf(); return; case IPPROTO_ICMP: pc.icmp++; DecodeICMP(pkt + hlen, ip_len, p); ClearDumpBuf(); return; default: pc.other++; p->data = pkt + hlen; p->dsize = ip_len; ClearDumpBuf(); return; } } else { /* set the payload pointer and payload size */ p->data = pkt + hlen; p->dsize = ip_len; }}/* * Function: DecodeIPOnly(u_int8_t *, const u_int32_t, Packet *) * * Purpose: Decode the IP network layer but not recurse * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to dummy packet decode struct * * Returns: void function */int DecodeIPOnly(u_int8_t * pkt, const u_int32_t len, Packet * p){ u_int32_t ip_len; /* length from the start of the ip hdr to the * pkt end */ u_int32_t hlen; /* ip header length */ /* lay the IP struct over the raw data */ p->iph = (IPHdr *) pkt;#ifdef DEBUG printf("DecodeIPOnly: ip header starts at: %p, length is %lu\n", p->iph, (unsigned long) len);#endif /* do a little validation */ if(len < IP_HEADER_LEN) { ErrorMessage("ICMP Unreachable IP short header (%d bytes)\n", len); p->iph = NULL; return(0); } /* * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP. * So we are just ignoring non IP datagrams */ if(p->iph->ip_ver != 4) { if(pv.verbose_flag) { ErrorMessage("[!] WARNING: ICMP Unreachable not IPv4 datagram ([ver: 0x%x][len: 0x%x])\n", p->iph->ip_ver, p->iph->ip_len); } p->iph = NULL; return(0); } /* set the IP datagram length */ ip_len = ntohs(p->iph->ip_len); /* set the IP header length */ hlen = p->iph->ip_hlen << 2; if(len < hlen) { ErrorMessage("[!] WARNING: ICMP Unreachable IP len (%d bytes) < IP hdr len (%d bytes), packet discarded\n", ip_len, hlen); p->iph = NULL; return(0); } /* don't try to recalculate the checksum of the encapsulated packet, * it will almost always be wrong and we already tested it on the * packet that spawned this UNREACH packet -MFR */ /*csum = checksum((u_short *)p->iph, hlen, (u_short *)NULL, 0); if(csum) { p->csum_flags |= CSE_IP;#ifdef DEBUG printf("Bad IP checksum\n");#endif }#ifdef DEBUG else { printf("IP Checksum: OK\n"); }#endif*/ /* we probably aren't real interested in IP options, we already put them * out for the originating packet so it'd probably be best to advance the * packet pointer up to the next layer if it's available -MFR */ /* test for IP options */ /*if(p->iph->ip_hlen > 5) { DecodeIPOptions((pkt + IP_HEADER_LEN), hlen - IP_HEADER_LEN, p); } else {*/ p->ip_option_count = 0; /*}*/ /* set the remaining packet length */ ip_len = len - hlen; /* check for fragmented packets */ p->frag_offset = ntohs(p->iph->ip_off); /* get the values of the reserved, more fragments and don't fragment flags */ p->rf = (p->frag_offset & 0x8000) >> 15; p->df = (p->frag_offset & 0x4000) >> 14; p->mf = (p->frag_offset & 0x2000) >> 13; /* mask off the high bits in the fragment offset field */ p->frag_offset &= 0x1FFF; if(p->frag_offset || p->mf) { /* set the packet fragment flag */ p->frag_flag = 1; /* set the payload pointer and payload size */ p->data = pkt + hlen; p->dsize = ip_len; } else { p->frag_flag = 0;#ifdef DEBUG printf("ICMP Unreachable IP header length: %lu\n", (unsigned long)hlen);#endif switch(p->iph->ip_proto) { case IPPROTO_TCP: /* decode the interesting part of the header */ if(ip_len > 4) { p->tcph =(TCPHdr *)(pkt + hlen); /* stuff more data into the printout data struct */ p->sp = ntohs(p->tcph->th_sport); p->dp = ntohs(p->tcph->th_dport); } break; case IPPROTO_UDP: if(ip_len > 4) { p->udph = (UDPHdr *)(pkt + hlen); /* fill in the printout data structs */ p->sp = ntohs(p->udph->uh_sport); p->dp = ntohs(p->udph->uh_dport); } break; } } return(1);}/* * Function: DecodeTCP(u_int8_t *, const u_int32_t, Packet *) * * Purpose: Decode the TCP transport layer * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => Pointer to packet decode struct * * Returns: void function */void DecodeTCP(u_int8_t * pkt, const u_int32_t len, Packet * p){ struct pseudoheader /* pseudo header for TCP checksum calculations */ { u_int32_t sip, dip; /* IP addr */ u_int8_t zero; /* checksum placeholder */ u_int8_t protocol; /* protocol number */ u_int16_t tcplen; /* tcp packet length */ }; u_int32_t hlen; /* TCP header length */ u_short csum; /* checksum */ struct pseudoheader ph; /* pseudo header declaration */ if(len < 20) { if(pv.verbose_flag) { ErrorMessage("[!] WARNING: TCP packet (len = %d) cannot contain 20 byte header\n", len); } if(pv.logbin_flag) LogBin(p, NULL, NULL); p->tcph = NULL; pc.discards++; } /* lay TCP on top of the data cause there is enough of it! */ p->tcph = (TCPHdr *) pkt; /* multiply the payload offset value by 4 */ hlen = p->tcph->th_off << 2;#ifdef DEBUG printf("TCP th_off is %d, passed len is %lu\n", p->tcph->th_off, (unsigned long)len);#endif if(hlen < 20) { if(pv.verbose_flag) { ErrorMessage("[!] WARNING: TCP Data Offset %d < 5 \n", p->tcph->th_off); } if(pv.logbin_flag) LogBin(p, NULL, NULL); hlen = 20; } /* setup the pseudo header for checksum calculation */ ph.sip = (u_int32_t)(p->iph->ip_src.s_addr); ph.dip = (u_int32_t)(p->iph->ip_dst.s_addr); ph.zero = 0; ph.protocol = p->iph->ip_proto; ph.tcplen = htons((unsigned short)len);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -