📄 decode.c
字号:
/* calculate the checksum */ csum = checksum((u_int16_t *)&ph, 12, (u_int16_t *)(p->tcph), len); if(csum) { p->csum_flags |= CSE_TCP;#ifdef DEBUG printf("Bad TCP checksum\n");#endif }#ifdef DEBUG else { printf("TCP Checksum: OK\n"); }#endif#ifdef DEBUG printf("tcp header starts at: %p\n", p->tcph);#endif /* if options are present, decode them */ if(hlen > 20) {#ifdef DEBUG printf("%lu bytes of tcp options....\n", (unsigned long)(hlen - 20));#endif DecodeTCPOptions((u_int8_t *) (pkt + 20), (hlen - 20), p); } else { p->tcp_option_count = 0; } /* stuff more data into the printout data struct */ p->sp = ntohs(p->tcph->th_sport); p->dp = ntohs(p->tcph->th_dport); /* set the data pointer and size */ p->data = (u_int8_t *) (pkt + hlen); if(hlen < len) { p->dsize = len - hlen; } else { p->dsize = 0; }}/* * Function: DecodeUDP(u_int8_t *, const u_int32_t, Packet *) * * Purpose: Decode the UDP transport layer * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to decoded packet struct * * Returns: void function */void DecodeUDP(u_int8_t * pkt, const u_int32_t len, Packet * p){ struct pseudoheader { u_int32_t sip, dip; u_int8_t zero; u_int8_t protocol; u_int16_t udplen; }; u_short csum; struct pseudoheader ph; if(len < sizeof(UDPHdr)) { if(pv.verbose_flag) { ErrorMessage("[!] WARNING: Truncated UDP header (%d bytes)\n", len); } if(pv.logbin_flag) LogBin(p, NULL, NULL); p->udph = NULL; pc.discards++; return; } /* set the ptr to the start of the UDP header */ p->udph = (UDPHdr *) pkt; /* look at the UDP checksum to make sure we've got a good packet */ 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.udplen = htons((unsigned short)len); csum = checksum((u_short *)&ph, 12, (u_short *)(p->udph), len); if(csum) { p->csum_flags |= CSE_UDP;#ifdef DEBUG printf("Bad UDP Checksum\n");#endif }#ifdef DEBUG else { printf("UDP Checksum: OK\n"); }#endif#ifdef DEBUG printf("UDP header starts at: %p\n", p->udph);#endif /* fill in the printout data structs */ p->sp = ntohs(p->udph->uh_sport); p->dp = ntohs(p->udph->uh_dport); p->data = (u_int8_t *) (pkt + UDP_HEADER_LEN); if((len - UDP_HEADER_LEN) > 0) { p->dsize = len - UDP_HEADER_LEN; } else { p->dsize = 0; }}/* * Function: DecodeICMP(u_int8_t *, const u_int32_t, Packet *) * * Purpose: Decode the ICMP transport layer * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to the decoded packet struct * * Returns: void function */void DecodeICMP(u_int8_t * pkt, const u_int32_t len, Packet * p){ u_int16_t csum; if(len < sizeof(ICMPHdr)) { if(pv.verbose_flag) { ErrorMessage("[!] WARNING: Truncated ICMP header(%d bytes)\n", len); } if(pv.logbin_flag) LogBin(p, NULL, NULL); p->icmph = NULL; pc.discards++; return; } /* set the header ptr first */ p->icmph = (ICMPHdr *) pkt; csum = checksum((u_int16_t *)p->icmph, len, NULL, 0); if(csum) { p->csum_flags |= CSE_ICMP;#ifdef DEBUG printf("Bad ICMP Checksum\n");#endif }#ifdef DEBUG else { printf("ICMP Checksum: OK\n"); }#endif p->dsize = len - ICMP_HEADER_LEN; p->data = pkt + ICMP_HEADER_LEN;#ifdef DEBUG printf("ICMP type: %d code: %d\n", p->icmph->code, p->icmph->type);#endif switch(p->icmph->type) { case ICMP_ECHOREPLY: /* setup the pkt id ans seq numbers */ p->ext = (echoext *) (pkt + ICMP_HEADER_LEN); p->dsize -= sizeof(echoext); p->data += sizeof(echoext); break; case ICMP_ECHO: /* setup the pkt id ans seq numbers */ p->ext = (echoext *) (pkt + ICMP_HEADER_LEN); p->dsize -= 4; /* add the size of the echo ext to the data * ptr and subtract it from the data size */ p->data += 4; break; case ICMP_DEST_UNREACH: { Packet orig_p; /* if unreach packet is smaller than expected! */ if(len < 16) { if(pv.verbose_flag) ErrorMessage("[!] WARNING: Truncated ICMP-UNREACH header (%d bytes)\n", len); /* if it is less than 8 we are in trouble */ if(len < 8) break; } bzero((char *)&orig_p, sizeof(Packet)); orig_p.caplen = len - 8; if(DecodeIPOnly(pkt + 8, orig_p.caplen, &orig_p)) { /* * that's probably what we need to know about an original * datagram */ p->orig_iph = orig_p.iph; p->orig_tcph = orig_p.tcph; p->orig_udph = orig_p.udph; p->orig_icmph = orig_p.icmph; p->orig_sp = orig_p.sp; p->orig_dp = orig_p.dp; } else { if(pv.logbin_flag) LogBin(p, NULL, NULL); } break; } } return;}/* * Function: DecodeARP(u_int8_t *, u_int32_t, Packet *) * * Purpose: Decode ARP stuff * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * p => pointer to decoded packet struct * * Returns: void function */void DecodeARP(u_int8_t * pkt, u_int32_t len, Packet * p){ p->ah = (EtherARP *) pkt; if(len < sizeof(EtherARP)) { if(pv.verbose_flag) printf("Truncated packet\n"); if(pv.logbin_flag) LogBin(p, NULL, NULL); pc.discards++; return; } return;}/* * Function: DecodeIPV6(u_int8_t *, u_int32_t) * * Purpose: Just like IPX, it's just for counting. * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * * Returns: void function */void DecodeIPV6(u_int8_t *pkt, u_int32_t len){ if(pv.verbose_flag) { puts("IPV6 packet"); } return;}/* * Function: DecodeIPX(u_int8_t *, u_int32_t) * * Purpose: Well, it doesn't do much of anything right now... * * Arguments: pkt => ptr to the packet data * len => length from here to the end of the packet * * Returns: void function * */void DecodeIPX(u_int8_t *pkt, u_int32_t len){ if(pv.verbose_flag) { puts("IPX packet"); } return;}/* * Function: DecodeTCPOptions(u_int8_t *, u_int32_t, Packet *) * * Purpose: Fairly self explainatory name, don't you think? * * Arguments: o_list => ptr to the option list * o_len => length of the option list * p => pointer to decoded packet struct * * Returns: void function */void DecodeTCPOptions(u_int8_t *o_list, u_int32_t o_len, Packet *p){ u_int8_t *option_ptr; u_int32_t bytes_processed; u_int32_t current_option; u_char done = 0; option_ptr = o_list; bytes_processed = 0; current_option = 0; while((bytes_processed < o_len) && (current_option < 40) && !done) { p->tcp_options[current_option].code = *option_ptr; switch(*option_ptr) { case TCPOPT_NOP: case TCPOPT_EOL: if(*option_ptr == TCPOPT_EOL) done = 1; p->tcp_options[current_option].len = 0; p->tcp_options[current_option].data = NULL; bytes_processed++; current_option++; option_ptr++; break; case TCPOPT_SACKOK: p->tcp_options[current_option].len = 0; p->tcp_options[current_option].data = NULL; bytes_processed += 2; option_ptr += 2; current_option++; break; case TCPOPT_WSCALE: p->tcp_options[current_option].len = 3; p->tcp_options[current_option].data = option_ptr + 2; option_ptr += 3; bytes_processed += 3; current_option++; break; default: p->tcp_options[current_option].len = *(option_ptr + 1); if(p->tcp_options[current_option].len > 40) { p->tcp_options[current_option].len = 40; } else if( p->tcp_options[current_option].len == 0) { /* got a bad option, we're all done */ done = 1; p->tcp_lastopt_bad = 1; } p->tcp_options[current_option].data = option_ptr + 2; option_ptr += p->tcp_options[current_option].len; bytes_processed += p->tcp_options[current_option].len; current_option++; break; } } if(bytes_processed > o_len) { p->tcp_options[current_option].len = p->tcp_options[current_option].len - (bytes_processed - o_len); /* * in reality shouldn't happen until we got the option type and len * on the packet header boundary.. then we just drop last option (as * it is corrupted anyway). */ if(p->tcp_options[current_option].len < 0) current_option--; } p->tcp_option_count = current_option; return;}/* * Function: DecodeIPOptions(u_int8_t *, u_int32_t, Packet *) * * Purpose: Once again, a fairly self-explainatory name * * Arguments: o_list => ptr to the option list * o_len => length of the option list * p => pointer to decoded packet struct * * Returns: void function */void DecodeIPOptions(u_int8_t *o_list, u_int32_t o_len, Packet *p){ u_int8_t *option_ptr; u_int32_t bytes_processed; u_int32_t current_option; u_char done = 0; option_ptr = o_list; bytes_processed = 0; current_option = 0;#ifdef DEBUG printf("Decoding %d bytes of IP options\n", o_len);#endif while((bytes_processed < o_len) && (current_option < 40) && !done) {#ifdef DEBUG printf(" => %d bytes processed\n", bytes_processed);#endif p->ip_options[current_option].code = *option_ptr; switch(*option_ptr) { case IPOPT_RTRALT: case IPOPT_NOP: case IPOPT_EOL: /* if we hit an EOL, we're done */ if(*option_ptr == IPOPT_EOL) done = 1; p->ip_options[current_option].len = 0; p->ip_options[current_option].data = NULL; bytes_processed++; current_option++; option_ptr++; break; default: p->ip_options[current_option].len = *(option_ptr + 1); if(p->ip_options[current_option].len > 40) { p->ip_options[current_option].len = 40; } else if(p->ip_options[current_option].len == 0) { /* * this shouldn't happen, indicates a bad option list * so we bail */ done = 1; p->ip_lastopt_bad = 1; } p->ip_options[current_option].data = option_ptr + 2; option_ptr += p->ip_options[current_option].len;#ifdef DEBUG printf(" => Adding %d bytes\n", p->ip_options[current_option].len);#endif bytes_processed += p->ip_options[current_option].len; current_option++; break; } }#ifdef DEBUG printf(" => %d total bytes processed\n", bytes_processed);#endif if(bytes_processed > o_len) { p->ip_options[current_option].len = p->ip_options[current_option].len - (bytes_processed - o_len); /* * in reality shouldn't happen until we got the option type and len * on the packet header boundary.. then we just drop last option (as * it is corrupted anyway). */ if(p->ip_options[current_option].len < 0) current_option--; } p->ip_option_count = current_option; return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -