/* * is_nlanr() is the input file in tsh format?? */ pread_f *is_nlanr(char *filename) { struct tsh_frame tf; int rlen; #ifdef __WIN32 if((fp = fopen(filename, "r")) == NULL) { perror(filename); exit(-1); } #endif /* __WIN32 */ /* tsh is a little hard because there's no magic number */ /* read the tsh file header */ if ((rlen=fread(&tf,1,sizeof(tf),SYS_STDIN)) != sizeof(tf)) { /* not even a full frame */ rewind(SYS_STDIN); return(NULL); } rewind(SYS_STDIN); if (debug) { printf("nlanr tsh ts_secs: %d\n", tf.tph.ts_secs); printf("nlanr tsh ts_usecs: %d\n", tf.tph.ts_usecs); printf("nlanr tsh interface: %d\n", tf.tph.interface_id); printf("nlanr sizeof(tf): %d\n", sizeof(tf)); printf("nlanr sizeof(tph): %d\n", sizeof(tf.tph)); if (debug > 1) PrintRawDataHex("NLANR TSH header",&tf,(char *)&tf+39); } /* quick heuristics */ if (((tf.ip_header.ip_v != 4) && (tf.ip_header.ip_v != 6)) ) { return(NULL); } /* OK, let's hope it's a tsh file */ /* there's no physical header present, so make up one */ pep = MallocZ(sizeof(struct ether_header)); pep->ether_type = htons(ETHERTYPE_IP); if (debug) fprintf(stderr,"TSH format, interface ID %d\n", tf.tph.interface_id); return(pread_nlanr); }
/* currently only works for ETHERNET */ static int pread_EP( struct timeval *ptime, int *plen, int *ptlen, void **pphys, int *pphystype, struct ip **ppip, void **pplast) { u_int packlen; u_int rlen; u_int len; /* read the EP packet header */ while(1){ if (EP_V5 || EP_V6) { struct EPFilePacket_v5_6 hdr; struct EPFilePacket2_v5_6 hdr2; struct EPFilePacket3_v5_6 hdr3; if ((rlen=fread(&hdr,1,Real_Size_FP,SYS_STDIN)) != Real_Size_FP) { if (rlen != 0) fprintf(stderr,"Bad EP header\n"); return(0); } hdr.packetlength = ntohs(hdr.packetlength); hdr.slicelength = ntohs(hdr.slicelength); if (debug>1) { printf("EP_read: next packet: original length: %d, saved length: %d\n", hdr.packetlength, hdr.slicelength); } if ((rlen=fread(&hdr2,1,Real_Size_FP2,SYS_STDIN)) !=Real_Size_FP2) { if (rlen != 0) fprintf(stderr,"Bad EP header\n"); return(0); } if ((rlen=fread(&hdr3,1,Real_Size_FP3,SYS_STDIN)) != Real_Size_FP3) { if (rlen != 0) fprintf(stderr,"Bad EP header\n"); return(0); } if (hdr.slicelength) packlen = hdr.slicelength; else packlen = hdr.packetlength; hdr3.timestamp = ntohl(hdr3.timestamp); ptime->tv_sec = mactime + (hdr3.timestamp / 1000); /*milliseconds div 1000*/ ptime->tv_usec = 1000 * (hdr3.timestamp % 1000); *plen = hdr.packetlength; /* hmmm... I guess 0 bytes means that they grabbed the whole */ /* packet. Seems to work that way... sdo - Thu Feb 13, 1997 */ if (hdr.slicelength) *ptlen = hdr.slicelength; else *ptlen = hdr.packetlength; } else { /* version 7 */ struct PeekPacket_v7 hdrv7; if ((rlen=fread(&hdrv7,sizeof(hdrv7),1,SYS_STDIN)) != 1) { if (rlen != 0) fprintf(stderr,"Bad EP V7 header (rlen is %d)\n", rlen); return(0); } hdrv7.packetlength = ntohs(hdrv7.packetlength); hdrv7.slicelength = ntohs(hdrv7.slicelength); if (hdrv7.slicelength) packlen = hdrv7.slicelength; else packlen = hdrv7.packetlength; /* file save version 7 time is NOT an offset, it's a 64 bit counter in microseconds */ #ifdef HAVE_LONG_LONG { /* not everybody has LONG LONG now */ unsigned long long int usecs; /* avoid ugly alignment problems */ usecs = ntohl(hdrv7.timestamphi); usecs <<= 32; usecs |= ntohl(hdrv7.timestamplo); ptime->tv_sec = usecs / 1000000 - Mac2unix; ptime->tv_usec = usecs % 1000000; } #else /* HAVE_LONG_LONG */ { double usecs; /* secs is hard because I don't want to depend on "long long" */ /* which isn't universal yet. "float" probably isn't enough */ /* signigicant figures to make this work, so I'll do it in */ /* (slow) double precision :-( */ usecs = (double)hdrv7.timestamphi * (65536.0 * 65536.0); usecs += (double)hdrv7.timestamplo; usecs -= (double)Mac2unix*1000000.0; ptime->tv_sec = usecs/1000000.0; /* usecs is easier, the part we want is all in the lower word */ ptime->tv_usec = usecs - (double)ptime->tv_sec * 1000000.0; } #endif /* HAVE_LONG_LONG */ *plen = hdrv7.packetlength; /* hmmm... I guess 0 bytes means that they grabbed the whole */ /* packet. Seems to work that way... sdo - Thu Feb 13, 1997 */ if (hdrv7.slicelength) *ptlen = hdrv7.slicelength; else *ptlen = hdrv7.packetlength; if (debug>1) { printf("File position: %ld\n", ftell(SYS_STDIN)); printf("pread_EP (v7) next packet:\n"); printf(" packetlength: %d\n", hdrv7.packetlength); printf(" slicelength: %d\n", hdrv7.slicelength); printf(" packlen: %d\n", packlen); printf(" time: %s\n", ts2ascii_date(ptime)); } } len= packlen; /* read the ethernet header */ rlen=fread(pep,1,sizeof(struct ether_header),SYS_STDIN); if (rlen != sizeof(struct ether_header)) { fprintf(stderr,"Couldn't read ether header\n"); return(0); } if (debug > 3) { PrintRawDataHex("EP_READ: Ethernet Dump", pep, (char *)(pep+1)-1); } /* read the rest of the packet */ len -= sizeof(struct ether_header); if (len >= IP_MAXPACKET) { /* sanity check */ fprintf(stderr, "pread_EP: invalid next packet, IP len is %d, return EOF\n", len); return(0); } if ((rlen=fread(pip_buf,1,len,SYS_STDIN)) != len) { if (rlen != 0) if (debug) fprintf(stderr, "Couldn't read %d more bytes, skipping last packet\n", len); return(0); } if (debug > 3) PrintRawDataHex("EP_READ: IP Dump", pip_buf, (char *)pip_buf+len-1); /* round to 2 bytes for V7 */ if (EP_V7) { if (len%2 != 0) { /* can't SEEK, because this might be a pipe!! */ (void) fgetc(SYS_STDIN); } } *ppip = (struct ip *) pip_buf; *pplast = (char *)pip_buf+len-1; /* last byte in the IP packet */ *pphys = pep; *pphystype = PHYS_ETHER; /* if it's not IP, then skip it */ if ((ntohs(pep->ether_type) != ETHERTYPE_IP) && (ntohs(pep->ether_type) != ETHERTYPE_IPV6)) { if (debug > 2) fprintf(stderr,"pread_EP: not an IP packet\n"); continue; } return(1); } }