/* IP header tracing routines * Copyright 1991 Phil Karn, KA9Q */ #include #include "global.h" #include "mbuf.h" #include "internet.h" #include "iface.h" #include "ip.h" #include "trace.h" #include "netuser.h" void ip_dump(fp,bpp,check) FILE *fp; struct mbuf **bpp; int check; { struct ip ip; int16 ip_len; int16 length; int16 csum; if(bpp == NULLBUFP || *bpp == NULLBUF) return; fprintf(fp,"IP:"); /* Sneak peek at IP header and find length */ ip_len = ((*bpp)->data[0] & 0xf) << 2; if(ip_len < IPLEN){ fprintf(fp," bad header\n"); return; } if(check) csum = cksum(NULLHEADER,*bpp,ip_len); else csum = 0; ntohip(&ip,bpp); /* Can't fail, we've already checked ihl */ /* Trim data segment if necessary. */ length = ip.length - ip_len; /* Length of data portion */ trim_mbuf(bpp,length); fprintf(fp," len %u",ip.length); fprintf(fp," %s",inet_ntoa(ip.source)); fprintf(fp,"->%s ihl %u ttl %u", inet_ntoa(ip.dest),ip_len,uchar(ip.ttl)); if(ip.tos != 0) fprintf(fp," tos %u",uchar(ip.tos)); if(ip.offset != 0 || ip.flags.mf) fprintf(fp," id %u offs %u",ip.id,ip.offset); if(ip.flags.df) fprintf(fp," DF"); if(ip.flags.mf){ fprintf(fp," MF"); check = 0; /* Bypass host-level checksum verify */ } if(ip.flags.congest){ fprintf(fp," CE"); } if(csum != 0) fprintf(fp," CHECKSUM ERROR (%u)",csum); if(ip.offset != 0){ putc('\n',fp); return; } switch(uchar(ip.protocol)){ case IP_PTCL: fprintf(fp," prot IP\n"); ip_dump(fp,bpp,check); break; case TCP_PTCL: fprintf(fp," prot TCP\n"); tcp_dump(fp,bpp,ip.source,ip.dest,check); break; case UDP_PTCL: fprintf(fp," prot UDP\n"); udp_dump(fp,bpp,ip.source,ip.dest,check); break; case ICMP_PTCL: fprintf(fp," prot ICMP\n"); icmp_dump(fp,bpp,ip.source,ip.dest,check); break; default: fprintf(fp," prot %u\n",uchar(ip.protocol)); break; } }