/* Read the header of the next packet. Return TRUE on success, FALSE on error. */ static gboolean _5views_read_header(wtap *wth, FILE_T fh, t_5VW_TimeStamped_Header *hdr, struct wtap_pkthdr *phdr, int *err, gchar **err_info) { int bytes_read, bytes_to_read; bytes_to_read = sizeof(t_5VW_TimeStamped_Header); /* Read record header. */ bytes_read = file_read(hdr, bytes_to_read, fh); if (bytes_read != bytes_to_read) { *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } hdr->Key = pletohl(&hdr->Key); if (hdr->Key != CST_5VW_RECORDS_HEADER_KEY) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("5views: Time-stamped header has bad key value 0x%08X", hdr->Key); return FALSE; } hdr->RecSubType = pletohl(&hdr->RecSubType); hdr->RecSize = pletohl(&hdr->RecSize); hdr->Utc = pletohl(&hdr->Utc); hdr->NanoSecondes = pletohl(&hdr->NanoSecondes); phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; phdr->ts.secs = hdr->Utc; phdr->ts.nsecs = hdr->NanoSecondes; phdr->caplen = hdr->RecSize; phdr->len = hdr->RecSize; switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* We assume there's no FCS in this frame. */ phdr->pseudo_header.eth.fcs_len = 0; break; } return TRUE; }
static gboolean aethra_read_rec_header(wtap *wth, FILE_T fh, struct aethrarec_hdr *hdr, struct wtap_pkthdr *phdr, int *err, gchar **err_info) { aethra_t *aethra = (aethra_t *)wth->priv; int bytes_read; guint32 rec_size; guint32 packet_size; guint32 msecs; /* Read record header. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(hdr, sizeof *hdr, fh); if (bytes_read != sizeof *hdr) { *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } rec_size = pletohs(hdr->rec_size); if (rec_size < (sizeof *hdr - sizeof hdr->rec_size)) { /* The record is shorter than a record header. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("aethra: File has %u-byte record, less than minimum of %u", rec_size, (unsigned int)(sizeof *hdr - sizeof hdr->rec_size)); return FALSE; } packet_size = rec_size - (guint32)(sizeof *hdr - sizeof hdr->rec_size); msecs = pletohl(hdr->timestamp); phdr->presence_flags = WTAP_HAS_TS; phdr->ts.secs = aethra->start + (msecs / 1000); phdr->ts.nsecs = (msecs % 1000) * 1000000; phdr->caplen = packet_size; phdr->len = packet_size; phdr->pseudo_header.isdn.uton = (hdr->flags & AETHRA_U_TO_N); phdr->pseudo_header.isdn.channel = 0; /* XXX - D channel */ return TRUE; }
int _5views_open(wtap *wth, int *err, gchar **err_info) { int bytes_read; t_5VW_Capture_Header Capture_Header; int encap = WTAP_ENCAP_UNKNOWN; errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&Capture_Header.Info_Header, sizeof(t_5VW_Info_Header), wth->fh); if (bytes_read != sizeof(t_5VW_Info_Header)) { *err = file_error(wth->fh, err_info); if (*err != 0 && *err != WTAP_ERR_SHORT_READ) return -1; return 0; } /* Check whether that's 5Views format or not */ if(Capture_Header.Info_Header.Signature != CST_5VW_INFO_HEADER_KEY) { return 0; } /* Check Version */ Capture_Header.Info_Header.Version = pletohl(&Capture_Header.Info_Header.Version); switch (Capture_Header.Info_Header.Version) { case CST_5VW_INFO_RECORD_VERSION: break; default: *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("5views: header version %u unsupported", Capture_Header.Info_Header.Version); return -1; } /* Check File Type */ Capture_Header.Info_Header.FileType = pletohl(&Capture_Header.Info_Header.FileType); if((Capture_Header.Info_Header.FileType & CST_5VW_CAPTURE_FILE_TYPE_MASK) != CST_5VW_CAPTURE_FILEID) { *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("5views: file is not a capture file (filetype is %u)", Capture_Header.Info_Header.Version); return -1; } /* Check possible Encap */ switch (Capture_Header.Info_Header.FileType) { case CST_5VW_CAPTURE_ETH_FILEID: encap = WTAP_ENCAP_ETHERNET; break; /* case CST_5VW_CAPTURE_WAN_FILEID: break; */ default: *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("5views: network type %u unknown or unsupported", Capture_Header.Info_Header.FileType); return -1; } /* read the remaining header information */ bytes_read = file_read(&Capture_Header.HeaderDateCreation, sizeof (t_5VW_Capture_Header) - sizeof(t_5VW_Info_Header), wth->fh); if (bytes_read != sizeof (t_5VW_Capture_Header)- sizeof(t_5VW_Info_Header) ) { *err = file_error(wth->fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return -1; } /* This is a 5views capture file */ wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_5VIEWS; wth->subtype_read = _5views_read; wth->subtype_seek_read = _5views_seek_read; wth->file_encap = encap; wth->snapshot_length = 0; /* not available in header */ wth->tsprecision = WTAP_FILE_TSPREC_NSEC; return 1; }
static gboolean netmon_process_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, int *err, gchar **err_info) { netmon_t *netmon = (netmon_t *)wth->priv; int hdr_size = 0; union { struct netmonrec_1_x_hdr hdr_1_x; struct netmonrec_2_x_hdr hdr_2_x; } hdr; int bytes_read; gint64 delta = 0; /* signed - frame times can be before the nominal start */ gint64 t; time_t secs; guint32 nsecs; guint32 packet_size = 0; guint32 orig_size = 0; /* Read record header. */ switch (netmon->version_major) { case 1: hdr_size = sizeof (struct netmonrec_1_x_hdr); break; case 2: hdr_size = sizeof (struct netmonrec_2_x_hdr); break; } errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&hdr, hdr_size, fh); if (bytes_read != hdr_size) { *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } switch (netmon->version_major) { case 1: orig_size = pletohs(&hdr.hdr_1_x.orig_len); packet_size = pletohs(&hdr.hdr_1_x.incl_len); break; case 2: orig_size = pletohl(&hdr.hdr_2_x.orig_len); packet_size = pletohl(&hdr.hdr_2_x.incl_len); break; } if (packet_size > WTAP_MAX_PACKET_SIZE) { /* * Probably a corrupt capture file; don't blow up trying * to allocate space for an immensely-large packet. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("netmon: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return FALSE; } /* * If this is an ATM packet, the first * "sizeof (struct netmon_atm_hdr)" bytes have destination and * source addresses (6 bytes - MAC addresses of some sort?) * and the VPI and VCI; read them and generate the pseudo-header * from them. */ switch (wth->file_encap) { case WTAP_ENCAP_ATM_PDUS: if (packet_size < sizeof (struct netmon_atm_hdr)) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("netmon: ATM file has a %u-byte packet, too small to have even an ATM pseudo-header", packet_size); return FALSE; } if (!netmon_read_atm_pseudoheader(fh, &phdr->pseudo_header, err, err_info)) return FALSE; /* Read error */ /* * Don't count the pseudo-header as part of the packet. */ orig_size -= (guint)sizeof (struct netmon_atm_hdr); packet_size -= (guint)sizeof (struct netmon_atm_hdr); break; default: break; } switch (netmon->version_major) { case 1: /* * According to Paul Long, this offset is unsigned. * It's 32 bits, so the maximum value will fit in * a gint64 such as delta, even after multiplying * it by 1000000. * * pletohl() returns a guint32; we cast it to gint64 * before multiplying, so that the product doesn't * overflow a guint32. */ delta = ((gint64)pletohl(&hdr.hdr_1_x.ts_delta))*1000000; break; case 2: /* * OK, this is weird. Microsoft's documentation * says this is in microseconds and is a 64-bit * unsigned number, but it can be negative; they * say what appears to amount to "treat it as an * unsigned number, multiply it by 10, and then * interpret the resulting 64-bit quantity as a * signed number". That operation can turn a * value with the uppermost bit 0 to a value with * the uppermost bit 1, hence turning a large * positive number-of-microseconds into a small * negative number-of-100-nanosecond-increments. */ delta = pletohll(&hdr.hdr_2_x.ts_delta)*10; /* * OK, it's now a signed value in 100-nanosecond * units. Now convert it to nanosecond units. */ delta *= 100; break; } secs = 0; t = netmon->start_nsecs + delta; while (t < 0) { /* * Propagate a borrow into the seconds. * The seconds is a time_t, and can be < 0 * (unlikely, as Windows didn't exist before * January 1, 1970, 00:00:00 UTC), while the * nanoseconds should be positive, as in * "nanoseconds since the instant of time * represented by the seconds". * * We do not want t to be negative, as, according * to the C90 standard, "if either operand [of / * or %] is negative, whether the result of the * / operator is the largest integer less than or * equal to the algebraic quotient or the smallest * greater than or equal to the algebraic quotient * is implementation-defined, as is the sign of * the result of the % operator", and we want * the result of the division and remainder * operations to be the same on all platforms. */ t += 1000000000; secs--; } secs += (time_t)(t/1000000000); nsecs = (guint32)(t%1000000000); phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; phdr->ts.secs = netmon->start_secs + secs; phdr->ts.nsecs = nsecs; phdr->caplen = packet_size; phdr->len = orig_size; return TRUE; }
gboolean nstrace_read_v20(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { nstrace_t *nstrace = (nstrace_t *)wth->priv; guint64 nsg_creltime = nstrace->nsg_creltime; gchar *nstrace_buf = nstrace->pnstrace_buf; gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset; gint32 nstrace_buflen = nstrace->nstrace_buflen; nspr_pktracefull_v20_t *fp20; nspr_pktracefull_v21_t *fp21; *err = 0; *err_info = NULL; do { while ((nstrace_buf_offset < nstrace_buflen) && ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp21->fp_RecordType)))) { fp21 = (nspr_pktracefull_v21_t *) &nstrace_buf[nstrace_buf_offset]; switch (fp21->fp_RecordType) { #define GENERATE_CASE(type,acttype) \ case NSPR_PDPKTRACEFULLTX_V##type:\ case NSPR_PDPKTRACEFULLTXB_V##type:\ case NSPR_PDPKTRACEFULLRX_V##type:\ PACKET_DESCRIBE(TIMEDEF,FPSIZEDEFV,type,v##type##_full,fp,pktracefull_v##type,acttype); GENERATE_CASE(23,203); GENERATE_CASE(22,202); GENERATE_CASE(21,201); GENERATE_CASE(20,200); #undef GENERATE_CASE #define GENERATE_CASE(type,acttype) \ case NSPR_PDPKTRACEPARTTX_V##type:\ case NSPR_PDPKTRACEPARTTXB_V##type:\ case NSPR_PDPKTRACEPARTRX_V##type:\ PACKET_DESCRIBE(TIMEDEF,PPSIZEDEFV,type,v##type##_part,pp,pktracepart_v##type,acttype); GENERATE_CASE(23,203); GENERATE_CASE(22,202); GENERATE_CASE(21,201); GENERATE_CASE(20,200); #undef GENERATE_CASE case NSPR_ABSTIME_V20: { fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset]; nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20); ns_setabstime(nstrace, pletohl(&((nspr_abstime_v20_t *) fp20)->abs_Time), pletohs(&((nspr_abstime_v20_t *) fp20)->abs_RelTime)); break; } case NSPR_RELTIME_V20: { fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset]; ns_setrelativetime(nstrace, pletohs(&((nspr_abstime_v20_t *) fp20)->abs_RelTime)); nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20); break; } case NSPR_UNUSEDSPACE_V20: { if (nstrace_buf_offset >= NSPR_PAGESIZE/2) nstrace_buf_offset = nstrace_buflen; else nstrace_buf_offset = NSPR_PAGESIZE/2; break; } default: { fp20 = (nspr_pktracefull_v20_t *) &nstrace_buf[nstrace_buf_offset]; nstrace_buf_offset += nspr_getv20recordsize((nspr_hd_v20_t *)fp20); break; } } } nstrace_buf_offset = 0; wth->data_offset += nstrace_buflen; nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - wth->data_offset)); }while((nstrace_buflen > 0) && (nstrace_buflen == (file_read(nstrace_buf, 1, nstrace_buflen, wth->fh)))); return FALSE; }
/* Read the next packet */ static gboolean netmon_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { netmon_t *netmon = (netmon_t *)wth->priv; guint32 packet_size = 0; guint32 orig_size = 0; int bytes_read; union { struct netmonrec_1_x_hdr hdr_1_x; struct netmonrec_2_x_hdr hdr_2_x; } hdr; int hdr_size = 0; int trlr_size; gint64 rec_offset; guint8 *data_ptr; gint64 delta = 0; /* signed - frame times can be before the nominal start */ gint64 t; time_t secs; guint32 nsecs; again: /* Have we reached the end of the packet data? */ if (netmon->current_frame >= netmon->frame_table_size) { /* Yes. We won't need the frame table any more; free it. */ g_free(netmon->frame_table); netmon->frame_table = NULL; *err = 0; /* it's just an EOF, not an error */ return FALSE; } /* Seek to the beginning of the current record, if we're not there already (seeking to the current position may still cause a seek and a read of the underlying file, so we don't want to do it unconditionally). Yes, the current record could be before the previous record. At least some captures put the trailer record with statistics as the first physical record in the file, but set the frame table up so it's the last record in sequence. */ rec_offset = netmon->frame_table[netmon->current_frame]; if (wth->data_offset != rec_offset) { wth->data_offset = rec_offset; if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) return FALSE; } netmon->current_frame++; /* Read record header. */ switch (netmon->version_major) { case 1: hdr_size = sizeof (struct netmonrec_1_x_hdr); break; case 2: hdr_size = sizeof (struct netmonrec_2_x_hdr); break; } errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&hdr, hdr_size, wth->fh); if (bytes_read != hdr_size) { *err = file_error(wth->fh, err_info); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } wth->data_offset += hdr_size; switch (netmon->version_major) { case 1: orig_size = pletohs(&hdr.hdr_1_x.orig_len); packet_size = pletohs(&hdr.hdr_1_x.incl_len); break; case 2: orig_size = pletohl(&hdr.hdr_2_x.orig_len); packet_size = pletohl(&hdr.hdr_2_x.incl_len); break; } if (packet_size > WTAP_MAX_PACKET_SIZE) { /* * Probably a corrupt capture file; don't blow up trying * to allocate space for an immensely-large packet. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("netmon: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return FALSE; } *data_offset = wth->data_offset; /* * If this is an ATM packet, the first * "sizeof (struct netmon_atm_hdr)" bytes have destination and * source addresses (6 bytes - MAC addresses of some sort?) * and the VPI and VCI; read them and generate the pseudo-header * from them. */ switch (wth->file_encap) { case WTAP_ENCAP_ATM_PDUS: if (packet_size < sizeof (struct netmon_atm_hdr)) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("netmon: ATM file has a %u-byte packet, too small to have even an ATM pseudo-header", packet_size); return FALSE; } if (!netmon_read_atm_pseudoheader(wth->fh, &wth->pseudo_header, err, err_info)) return FALSE; /* Read error */ /* * Don't count the pseudo-header as part of the packet. */ orig_size -= (guint)sizeof (struct netmon_atm_hdr); packet_size -= (guint)sizeof (struct netmon_atm_hdr); wth->data_offset += sizeof (struct netmon_atm_hdr); break; default: break; } buffer_assure_space(wth->frame_buffer, packet_size); data_ptr = buffer_start_ptr(wth->frame_buffer); if (!netmon_read_rec_data(wth->fh, data_ptr, packet_size, err, err_info)) return FALSE; /* Read error */ wth->data_offset += packet_size; switch (netmon->version_major) { case 1: /* * According to Paul Long, this offset is unsigned. * It's 32 bits, so the maximum value will fit in * a gint64 such as delta, even after multiplying * it by 1000000. * * pletohl() returns a guint32; we cast it to gint64 * before multiplying, so that the product doesn't * overflow a guint32. */ delta = ((gint64)pletohl(&hdr.hdr_1_x.ts_delta))*1000000; break; case 2: /* * OK, this is weird. Microsoft's documentation * says this is in microseconds and is a 64-bit * unsigned number, but it can be negative; they * say what appears to amount to "treat it as an * unsigned number, multiply it by 10, and then * interpret the resulting 64-bit quantity as a * signed number". That operation can turn a * value with the uppermost bit 0 to a value with * the uppermost bit 1, hence turning a large * positive number-of-microseconds into a small * negative number-of-100-nanosecond-increments. */ delta = pletohll(&hdr.hdr_2_x.ts_delta)*10; /* * OK, it's now a signed value in 100-nanosecond * units. Now convert it to nanosecond units. */ delta *= 100; break; } secs = 0; t = netmon->start_nsecs + delta; while (t < 0) { /* * Propagate a borrow into the seconds. * The seconds is a time_t, and can be < 0 * (unlikely, as Windows didn't exist before * January 1, 1970, 00:00:00 UTC), while the * nanoseconds should be positive, as in * "nanoseconds since the instant of time * represented by the seconds". * * We do not want t to be negative, as, according * to the C90 standard, "if either operand [of / * or %] is negative, whether the result of the * / operator is the largest integer less than or * equal to the algebraic quotient or the smallest * greater than or equal to the algebraic quotient * is implementation-defined, as is the sign of * the result of the % operator", and we want * the result of the division and remainder * operations to be the same on all platforms. */ t += 1000000000; secs--; } secs += (time_t)(t/1000000000); nsecs = (guint32)(t%1000000000); wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; wth->phdr.ts.secs = netmon->start_secs + secs; wth->phdr.ts.nsecs = nsecs; wth->phdr.caplen = packet_size; wth->phdr.len = orig_size; /* * For version 2.1 and later, there's additional information * after the frame data. */ trlr_size = (int)netmon_trailer_size(netmon); if (trlr_size != 0) { /* * I haz a trailer. */ wth->phdr.pkt_encap = netmon_read_rec_trailer(wth->fh, trlr_size, err, err_info); if (wth->phdr.pkt_encap == -1) return FALSE; /* error */ wth->data_offset += trlr_size; if (wth->phdr.pkt_encap == 0) goto again; netmon_set_pseudo_header_info(wth->phdr.pkt_encap, &wth->pseudo_header, data_ptr, packet_size); } else { netmon_set_pseudo_header_info(wth->file_encap, &wth->pseudo_header, data_ptr, packet_size); } return TRUE; }
int decode_icq(u_char *buf, int len, u_char *obuf, int olen) { struct buf inbuf, outbuf; u_short version, cmd; u_int32_t uin; u_char *p; buf_init(&inbuf, buf, len); buf_init(&outbuf, obuf, olen); if (buf_get(&inbuf, &version, sizeof(version)) != sizeof(version)) return (0); version = pletohs(&version); switch (version) { case 2: if (buf_seek(&inbuf, ICQ2_CMD_OFFSET, SEEK_SET) < 0) return (0); if (buf_get(&inbuf, &cmd, sizeof(cmd)) != sizeof(cmd)) return (0); if ((cmd = pletohs(&cmd)) != 1000) return (0); if (buf_seek(&inbuf, ICQ2_UIN_OFFSET, SEEK_SET) < 0) return (0); if (buf_get(&inbuf, &uin, sizeof(uin)) != sizeof(uin)) return (0); uin = pletohl(&uin); if (buf_seek(&inbuf, ICQ2_PASS_OFFSET, SEEK_SET) < 0) return (0); break; case 5: { u_int32_t a1, a2, a3, a4, a5, c, key, i, k; if (buf_seek(&inbuf, ICQ5_CKSUM_OFFSET, SEEK_SET) < 0) return (0); if (buf_get(&inbuf, &c, sizeof(c)) != sizeof(c)) return (0); c = pletohl(&c); a1 = c & 0x0001f000; a1 = a1 >> 0x0c; a2 = c & 0x07c007c0; a2 = a2 >> 0x01; a3 = c & 0x003e0001; a3 = a3 << 0x0a; a4 = c & 0xf8000000; a4 = a4 >> 0x10; a5 = c & 0x0000083e; a5 = a5 << 0x0f; key = len * 0x68656C6C; key += a1 + a2 + a3 + a4 + a5; p = inbuf.base; for (i = 0x0a; i < inbuf.end + 3; i += 4) { k = key + icq5_table[i & 0xff]; if (i != 0x16) { p[i] ^= (u_char)(k & 0xff); p[i + 1] ^= (u_char)((k & 0xff00) >> 8); } if (i != 0x12) { p[i + 2] ^= (u_char)((k & 0xff0000) >> 16); p[i + 3] ^= (u_char)((k & 0xff000000) >> 24); } } if (buf_seek(&inbuf, ICQ5_CMD_OFFSET, SEEK_SET) < 0) return (0); if (buf_get(&inbuf, &cmd, sizeof(cmd)) != sizeof(cmd)) return (0); if ((cmd = pletohs(&cmd)) != 1000) return (0); if (buf_seek(&inbuf, ICQ5_UIN_OFFSET, SEEK_SET) < 0) return (0); if (buf_get(&inbuf, &uin, sizeof(uin)) != sizeof(uin)) return (0); uin = pletohl(&uin); if (buf_seek(&inbuf, ICQ5_PASS_OFFSET, SEEK_SET) < 0) return (0); }
/* Read the next packet */ static gboolean aethra_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { aethra_t *aethra = (aethra_t *)wth->priv; struct aethrarec_hdr hdr; guint32 rec_size; guint32 packet_size; guint32 msecs; /* * Keep reading until we see an AETHRA_ISDN_LINK with a subtype * of AETHRA_ISDN_LINK_LAPD record or get an end-of-file. */ for (;;) { *data_offset = file_tell(wth->fh); /* Read record header. */ if (!aethra_read_rec_header(wth->fh, &hdr, &wth->pseudo_header, err, err_info)) return FALSE; rec_size = pletohs(hdr.rec_size); if (rec_size < (sizeof hdr - sizeof hdr.rec_size)) { /* The record is shorter than a record header. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("aethra: File has %u-byte record, less than minimum of %u", rec_size, (unsigned int)(sizeof hdr - sizeof hdr.rec_size)); return FALSE; } /* * XXX - if this is big, we might waste memory by * growing the buffer to handle it. */ packet_size = rec_size - (sizeof hdr - sizeof hdr.rec_size); if (packet_size != 0) { buffer_assure_space(wth->frame_buffer, packet_size); if (!aethra_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), packet_size, err, err_info)) return FALSE; /* Read error */ } #if 0 packet++; #endif switch (hdr.rec_type) { case AETHRA_ISDN_LINK: #if 0 fprintf(stderr, "Packet %u: type 0x%02x (AETHRA_ISDN_LINK)\n", packet, hdr.rec_type); #endif switch (hdr.flags & AETHRA_ISDN_LINK_SUBTYPE) { case AETHRA_ISDN_LINK_LAPD: /* * The data is a LAPD frame. */ #if 0 fprintf(stderr, " subtype 0x%02x (AETHRA_ISDN_LINK_LAPD)\n", hdr.flags & AETHRA_ISDN_LINK_SUBTYPE); #endif goto found; case AETHRA_ISDN_LINK_SA_BITS: /* * These records have one data byte, which * has the Sa bits in the lower 5 bits. * * XXX - what about stuff other than 2048K * PRI lines? */ #if 0 fprintf(stderr, " subtype 0x%02x (AETHRA_ISDN_LINK_SA_BITS)\n", hdr.flags & AETHRA_ISDN_LINK_SUBTYPE); #endif break; case AETHRA_ISDN_LINK_ALL_ALARMS_CLEARED: /* * No data, just an "all alarms cleared" * indication. */ #if 0 fprintf(stderr, " subtype 0x%02x (AETHRA_ISDN_LINK_ALL_ALARMS_CLEARED)\n", hdr.flags & AETHRA_ISDN_LINK_SUBTYPE); #endif break; default: #if 0 fprintf(stderr, " subtype 0x%02x, packet_size %u, direction 0x%02x\n", hdr.flags & AETHRA_ISDN_LINK_SUBTYPE, packet_size, hdr.flags & AETHRA_U_TO_N); #endif break; } break; default: #if 0 fprintf(stderr, "Packet %u: type 0x%02x, packet_size %u, flags 0x%02x\n", packet, hdr.rec_type, packet_size, hdr.flags); #endif break; } } found: msecs = pletohl(hdr.timestamp); wth->phdr.presence_flags = WTAP_HAS_TS; wth->phdr.ts.secs = aethra->start + (msecs / 1000); wth->phdr.ts.nsecs = (msecs % 1000) * 1000000; wth->phdr.caplen = packet_size; wth->phdr.len = packet_size; return TRUE; }
/* Read the next available packet from the file. This is called in a loop to sequentially read the entire file one time. After the file has been read once, any Future access to the packets is done through seek_read. */ static gboolean visual_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { struct visual_read_info *visual = (struct visual_read_info *)wth->priv; guint32 packet_size = 0; int bytes_read; struct visual_pkt_hdr vpkt_hdr; struct visual_atm_hdr vatm_hdr; int phdr_size = sizeof(vpkt_hdr); int ahdr_size = sizeof(vatm_hdr); time_t secs; guint32 usecs; double t; /* Check for the end of the packet data. Note that a check for file EOF will not work because there are index values stored after the last packet's data. */ if (visual->current_pkt > visual->num_pkts) { *err = 0; /* it's just an EOF, not an error */ return FALSE; } visual->current_pkt++; /* Read the packet header. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&vpkt_hdr, phdr_size, wth->fh); if (bytes_read != phdr_size) { *err = file_error(wth->fh, err_info); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } /* Get the included length of data. This includes extra headers + payload */ packet_size = pletohs(&vpkt_hdr.incl_len); /* Check for additional ATM packet header */ if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) { /* Read the atm packet header. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&vatm_hdr, ahdr_size, wth->fh); if (bytes_read != ahdr_size) { *err = file_error(wth->fh, err_info); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } /* Remove ATM header from length of included bytes in capture, as this header was appended by the processor doing the packet reassembly, and was not transmitted across the wire */ packet_size -= ahdr_size; } /* Read the packet data. */ if (packet_size > WTAP_MAX_PACKET_SIZE) { /* Probably a corrupt capture file; don't blow up trying to allocate space for an immensely-large packet. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("visual: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return FALSE; } buffer_assure_space(wth->frame_buffer, packet_size); *data_offset = file_tell(wth->fh); errno = WTAP_ERR_CANT_READ; bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), packet_size, wth->fh); if (bytes_read != (int) packet_size) { *err = file_error(wth->fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; /* Set the packet time and length. */ t = visual->start_time; t += ((double)pletohl(&vpkt_hdr.ts_delta))*1000; secs = (time_t)(t/1000000); usecs = (guint32)(t - secs*1000000); wth->phdr.ts.secs = secs; wth->phdr.ts.nsecs = usecs * 1000; /* Most visual capture types include FCS checks in the original length value, but * but don't include the FCS as part of the payload or captured length. * This causes the RTP audio payload save to fail since then captured len != orig len. * Adjusting the original length to remove the FCS bytes we counted based * on the file encapsualtion type. * * Only downside to this fix is throughput calculations will be slightly lower * as they won't include the FCS bytes. */ wth->phdr.caplen = packet_size; wth->phdr.len = pletohs(&vpkt_hdr.orig_len); switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: wth->phdr.len -= 4; break; case WTAP_ENCAP_FRELAY_WITH_PHDR: case WTAP_ENCAP_CHDLC_WITH_PHDR: case WTAP_ENCAP_LAPB: wth->phdr.len -= 2; break; /* ATM original length doesn't include any FCS. Do nothing. */ case WTAP_ENCAP_ATM_PDUS: /* Not sure about token ring. Just leaving alone for now. */ case WTAP_ENCAP_TOKEN_RING: default: break; } if (wth->phdr.len > WTAP_MAX_PACKET_SIZE) { /* Check if wth->phdr.len is sane, small values of wth.phdr.len before the case loop above can cause integer underflows */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("visual: File has %u-byte original packet, bigger than maximum of %u", wth->phdr.len, WTAP_MAX_PACKET_SIZE); return FALSE; } /* Sanity check */ if (wth->phdr.len < wth->phdr.caplen) { wth->phdr.len = wth->phdr.caplen; } /* Set the pseudo_header. */ visual_set_pseudo_header(wth->file_encap, &vpkt_hdr, &vatm_hdr, &wth->phdr.pseudo_header); /* Fill in the encapsulation. Visual files have a media type in the file header and an encapsulation type in each packet header. Files with a media type of HDLC can be either Cisco EtherType or PPP. The encapsulation hint values we've seen are: 2 - seen in an Ethernet capture 13 - seen in a PPP capture; possibly also seen in Cisco HDLC captures 14 - seen in a PPP capture; probably seen only for PPP */ if (wth->file_encap == WTAP_ENCAP_CHDLC_WITH_PHDR) { /* If PPP is specified in the encap hint, then use that */ if (vpkt_hdr.encap_hint == 14) { /* But first we need to examine the first three octets to try to determine the proper encapsulation, see RFC 2364. */ guint8 *buf = buffer_start_ptr(wth->frame_buffer); if ((0xfe == buf[0]) && (0xfe == buf[1]) && (0x03 == buf[2])) { /* It is actually LLC encapsulated PPP */ wth->phdr.pkt_encap = WTAP_ENCAP_ATM_RFC1483; } else { /* It is actually PPP */ wth->phdr.pkt_encap = WTAP_ENCAP_PPP_WITH_PHDR; } } else { /* Otherwise, we need to examine the first two octets to try to determine the encapsulation. */ guint8 *buf = buffer_start_ptr(wth->frame_buffer); if ((0xff == buf[0]) && (0x03 == buf[1])) { /* It is actually PPP */ wth->phdr.pkt_encap = WTAP_ENCAP_PPP_WITH_PHDR; } } } return TRUE; }
static gboolean visual_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { struct visual_read_info *visual = (struct visual_read_info *)wth->priv; struct visual_pkt_hdr vpkt_hdr; int bytes_read; guint32 packet_size; struct visual_atm_hdr vatm_hdr; double t; time_t secs; guint32 usecs; guint32 packet_status; guint8 *pd; /* Read the packet header. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&vpkt_hdr, (unsigned int)sizeof vpkt_hdr, fh); if (bytes_read < 0 || (size_t)bytes_read != sizeof vpkt_hdr) { *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } /* Get the included length of data. This includes extra headers + payload */ packet_size = pletohs(&vpkt_hdr.incl_len); phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; /* Set the packet time and length. */ t = visual->start_time; t += ((double)pletohl(&vpkt_hdr.ts_delta))*1000; secs = (time_t)(t/1000000); usecs = (guint32)(t - secs*1000000); phdr->ts.secs = secs; phdr->ts.nsecs = usecs * 1000; phdr->len = pletohs(&vpkt_hdr.orig_len); packet_status = pletohl(&vpkt_hdr.status); /* Do encapsulation-specific processing. Most Visual capture types include the FCS in the original length value, but don't include the FCS as part of the payload or captured length. This is different from the model used in most other capture file formats, including pcap and pcap-ng in cases where the FCS isn't captured (which are the typical cases), and causes the RTP audio payload save to fail since then captured len != orig len. We adjust the original length to remove the FCS bytes we counted based on the file encapsualtion type. The only downside to this fix is throughput calculations will be slightly lower as it won't include the FCS bytes. However, as noted, that problem also exists with other capture formats. We also set status flags. The only status currently supported for all encapsulations is direction. This either goes in the p2p or the X.25 pseudo header. It would probably be better to move this up into the phdr. */ switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* Ethernet has a 4-byte FCS. */ if (phdr->len < 4) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("visual: Ethernet packet has %u-byte original packet, less than the FCS length", phdr->len); return FALSE; } phdr->len -= 4; /* XXX - the above implies that there's never an FCS; should this set the FCS length to 0? */ phdr->pseudo_header.eth.fcs_len = -1; break; case WTAP_ENCAP_CHDLC_WITH_PHDR: /* This has a 2-byte FCS. */ if (phdr->len < 2) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("visual: Cisco HDLC packet has %u-byte original packet, less than the FCS length", phdr->len); return FALSE; } phdr->len -= 2; phdr->pseudo_header.p2p.sent = (packet_status & PS_SENT) ? TRUE : FALSE; break; case WTAP_ENCAP_PPP_WITH_PHDR: /* No FCS. XXX - true? Note that PPP can negotiate no FCS, a 2-byte FCS, or a 4-byte FCS. */ phdr->pseudo_header.p2p.sent = (packet_status & PS_SENT) ? TRUE : FALSE; break; case WTAP_ENCAP_FRELAY_WITH_PHDR: /* This has a 2-byte FCS. */ if (phdr->len < 2) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("visual: Frame Relay packet has %u-byte original packet, less than the FCS length", phdr->len); return FALSE; } phdr->len -= 2; phdr->pseudo_header.x25.flags = (packet_status & PS_SENT) ? 0x00 : FROM_DCE; break; case WTAP_ENCAP_LAPB: /* This has a 2-byte FCS. */ if (phdr->len < 2) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("visual: Frame Relay packet has %u-byte original packet, less than the FCS length", phdr->len); return FALSE; } phdr->len -= 2; phdr->pseudo_header.x25.flags = (packet_status & PS_SENT) ? 0x00 : FROM_DCE; break; case WTAP_ENCAP_ATM_PDUS: /* ATM original length doesn't include any FCS. Do nothing to the packet length. ATM packets have an additional packet header; read and process it. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&vatm_hdr, (unsigned int)sizeof vatm_hdr, fh); if (bytes_read < 0 || (size_t)bytes_read != sizeof vatm_hdr) { *err = file_error(fh, err_info); if (*err == 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } /* Remove ATM header from length of included bytes in capture, as this header was appended by the processor doing the packet reassembly, and was not transmitted across the wire */ packet_size -= (guint32)sizeof vatm_hdr; /* Set defaults */ phdr->pseudo_header.atm.type = TRAF_UNKNOWN; phdr->pseudo_header.atm.subtype = TRAF_ST_UNKNOWN; phdr->pseudo_header.atm.aal5t_len = 0; /* Next two items not supported. Defaulting to zero */ phdr->pseudo_header.atm.aal5t_u2u = 0; phdr->pseudo_header.atm.aal5t_chksum = 0; /* Flags appear only to convey that packet is a raw cell. Set to 0 */ phdr->pseudo_header.atm.flags = 0; /* Not supported. Defaulting to zero */ phdr->pseudo_header.atm.aal2_cid = 0; switch(vatm_hdr.category & VN_CAT_TYPE_MASK ) { case VN_AAL1: phdr->pseudo_header.atm.aal = AAL_1; break; case VN_AAL2: phdr->pseudo_header.atm.aal = AAL_2; break; case VN_AAL34: phdr->pseudo_header.atm.aal = AAL_3_4; break; case VN_AAL5: phdr->pseudo_header.atm.aal = AAL_5; phdr->pseudo_header.atm.type = TRAF_LLCMX; phdr->pseudo_header.atm.aal5t_len = pntohl(&vatm_hdr.data_length); break; case VN_OAM: /* Marking next 3 as OAM versus unknown */ case VN_O191: case VN_IDLE: case VN_RM: phdr->pseudo_header.atm.aal = AAL_OAMCELL; break; case VN_UNKNOWN: default: phdr->pseudo_header.atm.aal = AAL_UNKNOWN; break; } phdr->pseudo_header.atm.vpi = pntohs(&vatm_hdr.vpi) & 0x0FFF; phdr->pseudo_header.atm.vci = pntohs(&vatm_hdr.vci); phdr->pseudo_header.atm.cells = pntohs(&vatm_hdr.cell_count); /* Using bit value of 1 (DCE -> DTE) to indicate From Network */ phdr->pseudo_header.atm.channel = vatm_hdr.info & FROM_NETWORK; break; /* Not sure about token ring. Just leaving alone for now. */ case WTAP_ENCAP_TOKEN_RING: default: break; } phdr->caplen = packet_size; /* Check for too-large packet. */ if (packet_size > WTAP_MAX_PACKET_SIZE) { /* Probably a corrupt capture file; don't blow up trying to allocate space for an immensely-large packet. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("visual: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return FALSE; } /* Sanity check */ if (phdr->len < phdr->caplen) { phdr->len = phdr->caplen; } /* Read the packet data */ if (!wtap_read_packet_bytes(fh, buf, packet_size, err, err_info)) return FALSE; if (wth->file_encap == WTAP_ENCAP_CHDLC_WITH_PHDR) { /* Fill in the encapsulation. Visual files have a media type in the file header and an encapsulation type in each packet header. Files with a media type of HDLC can be either Cisco EtherType or PPP. The encapsulation hint values we've seen are: 2 - seen in an Ethernet capture 13 - seen in a PPP capture; possibly also seen in Cisco HDLC captures 14 - seen in a PPP capture; probably seen only for PPP. According to bug 2005, the collection probe can be configured for PPP, in which case the encapsulation hint is 14, or can be configured for auto-detect, in which case the encapsulation hint is 13, and the encapsulation must be guessed from the packet contents. Auto-detect is the default. */ pd = buffer_start_ptr(buf); /* If PPP is specified in the encap hint, then use that */ if (vpkt_hdr.encap_hint == 14) { /* But first we need to examine the first three octets to try to determine the proper encapsulation, see RFC 2364. */ if (packet_size >= 3 && (0xfe == pd[0]) && (0xfe == pd[1]) && (0x03 == pd[2])) { /* It is actually LLC encapsulated PPP */ phdr->pkt_encap = WTAP_ENCAP_ATM_RFC1483; } else { /* It is actually PPP */ phdr->pkt_encap = WTAP_ENCAP_PPP_WITH_PHDR; } } else { /* Otherwise, we need to examine the first two octets to try to determine the encapsulation. */ if (packet_size >= 2 && (0xff == pd[0]) && (0x03 == pd[1])) { /* It is actually PPP */ phdr->pkt_encap = WTAP_ENCAP_PPP_WITH_PHDR; } } } return TRUE; }
uint32_t Tvbuff::tvb_get_letohl(tvbuff_t *tvb,int offset) { const uint8_t* ptr; ptr = ensure_contiguous(tvb,offset,sizeof(uint32_t)); return pletohl(ptr); }
/* Read the next packet */ static gboolean netmon_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { netmon_t *netmon = (netmon_t *)wth->priv; guint32 packet_size = 0; guint32 orig_size = 0; int bytes_read; union { struct netmonrec_1_x_hdr hdr_1_x; struct netmonrec_2_x_hdr hdr_2_x; } hdr; union { struct netmonrec_2_1_trlr trlr_2_1; struct netmonrec_2_2_trlr trlr_2_2; struct netmonrec_2_3_trlr trlr_2_3; } trlr; int hdr_size = 0; int trlr_size = 0; int rec_offset; guint8 *data_ptr; gint64 delta = 0; /* signed - frame times can be before the nominal start */ time_t secs; guint32 usecs; double t; guint16 network; again: /* Have we reached the end of the packet data? */ if (netmon->current_frame >= netmon->frame_table_size) { /* Yes. We won't need the frame table any more; free it. */ g_free(netmon->frame_table); netmon->frame_table = NULL; *err = 0; /* it's just an EOF, not an error */ return FALSE; } /* Seek to the beginning of the current record, if we're not there already (seeking to the current position may still cause a seek and a read of the underlying file, so we don't want to do it unconditionally). Yes, the current record could be before the previous record. At least some captures put the trailer record with statistics as the first physical record in the file, but set the frame table up so it's the last record in sequence. */ rec_offset = netmon->frame_table[netmon->current_frame]; if (wth->data_offset != rec_offset) { wth->data_offset = rec_offset; if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) return FALSE; } netmon->current_frame++; /* Read record header. */ switch (netmon->version_major) { case 1: hdr_size = sizeof (struct netmonrec_1_x_hdr); break; case 2: hdr_size = sizeof (struct netmonrec_2_x_hdr); break; } errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&hdr, hdr_size, wth->fh); if (bytes_read != hdr_size) { *err = file_error(wth->fh); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } wth->data_offset += hdr_size; switch (netmon->version_major) { case 1: orig_size = pletohs(&hdr.hdr_1_x.orig_len); packet_size = pletohs(&hdr.hdr_1_x.incl_len); break; case 2: orig_size = pletohl(&hdr.hdr_2_x.orig_len); packet_size = pletohl(&hdr.hdr_2_x.incl_len); break; } if (packet_size > WTAP_MAX_PACKET_SIZE) { /* * Probably a corrupt capture file; don't blow up trying * to allocate space for an immensely-large packet. */ *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup_printf("netmon: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return FALSE; } *data_offset = wth->data_offset; /* * If this is an ATM packet, the first * "sizeof (struct netmon_atm_hdr)" bytes have destination and * source addresses (6 bytes - MAC addresses of some sort?) * and the VPI and VCI; read them and generate the pseudo-header * from them. */ switch (wth->file_encap) { case WTAP_ENCAP_ATM_PDUS: if (packet_size < sizeof (struct netmon_atm_hdr)) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. */ *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup_printf("netmon: ATM file has a %u-byte packet, too small to have even an ATM pseudo-header", packet_size); return FALSE; } if (!netmon_read_atm_pseudoheader(wth->fh, &wth->pseudo_header, err)) return FALSE; /* Read error */ /* * Don't count the pseudo-header as part of the packet. */ orig_size -= (guint)sizeof (struct netmon_atm_hdr); packet_size -= (guint)sizeof (struct netmon_atm_hdr); wth->data_offset += sizeof (struct netmon_atm_hdr); break; case WTAP_ENCAP_ETHERNET: /* * We assume there's no FCS in this frame. */ wth->pseudo_header.eth.fcs_len = 0; break; } buffer_assure_space(wth->frame_buffer, packet_size); data_ptr = buffer_start_ptr(wth->frame_buffer); if (!netmon_read_rec_data(wth->fh, data_ptr, packet_size, err)) return FALSE; /* Read error */ wth->data_offset += packet_size; t = (double)netmon->start_usecs; switch (netmon->version_major) { case 1: /* * According to Paul Long, this offset is unsigned. * It's 32 bits, so the maximum value will fit in * a gint64 such as delta, even after multiplying * it by 1000. * * pletohl() returns a guint32; we cast it to gint64 * before multiplying, so that the product doesn't * overflow a guint32. */ delta = ((gint64)pletohl(&hdr.hdr_1_x.ts_delta))*1000; break; case 2: delta = pletohl(&hdr.hdr_2_x.ts_delta_lo) | (((guint64)pletohl(&hdr.hdr_2_x.ts_delta_hi)) << 32); break; } t += (double)delta; secs = (time_t)(t/1000000); usecs = (guint32)(t - (double)secs*1000000); wth->phdr.ts.secs = netmon->start_secs + secs; wth->phdr.ts.nsecs = usecs * 1000; wth->phdr.caplen = packet_size; wth->phdr.len = orig_size; /* * Attempt to guess from the packet data, the VPI, and the VCI * information about the type of traffic. */ if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) { atm_guess_traffic_type(data_ptr, packet_size, &wth->pseudo_header); } /* * For version 2.1 and later, there's additional information * after the frame data. */ if ((netmon->version_major == 2 && netmon->version_minor >= 1) || netmon->version_major > 2) { if (netmon->version_major > 2) { /* * Asssume 2.3 format, for now. */ trlr_size = sizeof (struct netmonrec_2_3_trlr); } else { switch (netmon->version_minor) { case 1: trlr_size = sizeof (struct netmonrec_2_1_trlr); break; case 2: trlr_size = sizeof (struct netmonrec_2_2_trlr); break; default: trlr_size = sizeof (struct netmonrec_2_3_trlr); break; } } errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&trlr, trlr_size, wth->fh); if (bytes_read != trlr_size) { *err = file_error(wth->fh); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } wth->data_offset += trlr_size; network = pletohs(trlr.trlr_2_1.network); if ((network & 0xF000) == NETMON_NET_PCAP_BASE) { /* * Converted pcap file - the LINKTYPE_ value * is the network value with 0xF000 masked off. */ network &= 0x0FFF; wth->phdr.pkt_encap = wtap_pcap_encap_to_wtap_encap(network); if (wth->phdr.pkt_encap == WTAP_ENCAP_UNKNOWN) { *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("netmon: converted pcap network type %u unknown or unsupported", network); return FALSE; } } else if (network < NUM_NETMON_ENCAPS) { /* * Regular NetMon encapsulation. */ wth->phdr.pkt_encap = netmon_encap[network]; if (wth->phdr.pkt_encap == WTAP_ENCAP_UNKNOWN) { *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("netmon: network type %u unknown or unsupported", network); return FALSE; } } else { /* * Special packet type for metadata. */ switch (network) { case NETMON_NET_NETEVENT: case NETMON_NET_NETWORK_INFO_EX: case NETMON_NET_PAYLOAD_HEADER: case NETMON_NET_NETWORK_INFO: case NETMON_NET_DNS_CACHE: case NETMON_NET_NETMON_FILTER: /* * Just ignore those record types, for * now. Read the next record. */ goto again; default: *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("netmon: network type %u unknown or unsupported", network); return FALSE; } } } return TRUE; }
/* Read the next packet */ static gboolean radcom_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { int ret; struct radcomrec_hdr hdr; guint16 data_length, real_length, length; guint32 sec; int bytes_read; struct tm tm; guint8 phdr[8]; char fcs[2]; /* Read record header. */ *data_offset = file_tell(wth->fh); ret = radcom_read_rec_header(wth->fh, &hdr, err, err_info); if (ret <= 0) { /* Read error or EOF */ return FALSE; } data_length = pletohs(&hdr.data_length); if (data_length == 0) { /* * The last record appears to have 0 in its "data_length" * field, but non-zero values in other fields, so we * check for that and treat it as an EOF indication. */ *err = 0; return FALSE; } length = pletohs(&hdr.length); real_length = pletohs(&hdr.real_length); if (wth->file_encap == WTAP_ENCAP_LAPB) { length -= 2; /* FCS */ real_length -= 2; } wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; wth->phdr.len = real_length; wth->phdr.caplen = length; tm.tm_year = pletohs(&hdr.date.year)-1900; tm.tm_mon = (hdr.date.month&0x0f)-1; tm.tm_mday = hdr.date.day; sec = pletohl(&hdr.date.sec); tm.tm_hour = sec/3600; tm.tm_min = (sec%3600)/60; tm.tm_sec = sec%60; tm.tm_isdst = -1; wth->phdr.ts.secs = mktime(&tm); wth->phdr.ts.nsecs = pletohl(&hdr.date.usec) * 1000; switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* XXX - is there an FCS? */ wth->phdr.pseudo_header.eth.fcs_len = -1; break; case WTAP_ENCAP_LAPB: wth->phdr.pseudo_header.x25.flags = (hdr.dce & 0x1) ? 0x00 : FROM_DCE; break; case WTAP_ENCAP_ATM_RFC1483: /* * XXX - is this stuff a pseudo-header? * The direction appears to be in the "hdr.dce" field. */ if (!radcom_read_rec_data(wth->fh, phdr, sizeof phdr, err, err_info)) return FALSE; /* Read error */ length -= 8; wth->phdr.len -= 8; wth->phdr.caplen -= 8; break; } /* * Read the packet data. */ buffer_assure_space(wth->frame_buffer, length); if (!radcom_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), length, err, err_info)) return FALSE; /* Read error */ if (wth->file_encap == WTAP_ENCAP_LAPB) { /* Read the FCS. XXX - should we have some way of indicating the presence and size of an FCS to our caller? That'd let us handle other file types as well. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&fcs, sizeof fcs, wth->fh); if (bytes_read != sizeof fcs) { *err = file_error(wth->fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } } return TRUE; }
/* Read the next packet */ static gboolean netmon_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { netmon_t *netmon = (netmon_t *)wth->priv; guint32 packet_size = 0; guint32 orig_size = 0; int bytes_read; union { struct netmonrec_1_x_hdr hdr_1_x; struct netmonrec_2_x_hdr hdr_2_x; } hdr; int hdr_size = 0; int rec_offset; guint8 *data_ptr; time_t secs; guint32 usecs; double t; /* Have we reached the end of the packet data? */ if (netmon->current_frame >= netmon->frame_table_size) { /* Yes. We won't need the frame table any more; free it. */ g_free(netmon->frame_table); netmon->frame_table = NULL; *err = 0; /* it's just an EOF, not an error */ return FALSE; } /* Seek to the beginning of the current record, if we're not there already (seeking to the current position may still cause a seek and a read of the underlying file, so we don't want to do it unconditionally). */ rec_offset = netmon->frame_table[netmon->current_frame]; if (wth->data_offset != rec_offset) { wth->data_offset = rec_offset; if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) return FALSE; } netmon->current_frame++; /* Read record header. */ switch (netmon->version_major) { case 1: hdr_size = sizeof (struct netmonrec_1_x_hdr); break; case 2: hdr_size = sizeof (struct netmonrec_2_x_hdr); break; } errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&hdr, 1, hdr_size, wth->fh); if (bytes_read != hdr_size) { *err = file_error(wth->fh); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } wth->data_offset += hdr_size; switch (netmon->version_major) { case 1: orig_size = pletohs(&hdr.hdr_1_x.orig_len); packet_size = pletohs(&hdr.hdr_1_x.incl_len); break; case 2: orig_size = pletohl(&hdr.hdr_2_x.orig_len); packet_size = pletohl(&hdr.hdr_2_x.incl_len); break; } if (packet_size > WTAP_MAX_PACKET_SIZE) { /* * Probably a corrupt capture file; don't blow up trying * to allocate space for an immensely-large packet. */ *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup_printf("netmon: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return FALSE; } *data_offset = wth->data_offset; /* * If this is an ATM packet, the first * "sizeof (struct netmon_atm_hdr)" bytes have destination and * source addresses (6 bytes - MAC addresses of some sort?) * and the VPI and VCI; read them and generate the pseudo-header * from them. */ switch (wth->file_encap) { case WTAP_ENCAP_ATM_PDUS: if (packet_size < sizeof (struct netmon_atm_hdr)) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. */ *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup_printf("netmon: ATM file has a %u-byte packet, too small to have even an ATM pseudo-header", packet_size); return FALSE; } if (!netmon_read_atm_pseudoheader(wth->fh, &wth->pseudo_header, err)) return FALSE; /* Read error */ /* * Don't count the pseudo-header as part of the packet. */ orig_size -= (guint)sizeof (struct netmon_atm_hdr); packet_size -= (guint)sizeof (struct netmon_atm_hdr); wth->data_offset += sizeof (struct netmon_atm_hdr); break; case WTAP_ENCAP_ETHERNET: /* * We assume there's no FCS in this frame. */ wth->pseudo_header.eth.fcs_len = 0; break; } buffer_assure_space(wth->frame_buffer, packet_size); data_ptr = buffer_start_ptr(wth->frame_buffer); if (!netmon_read_rec_data(wth->fh, data_ptr, packet_size, err)) return FALSE; /* Read error */ wth->data_offset += packet_size; t = (double)netmon->start_usecs; switch (netmon->version_major) { case 1: t += ((double)pletohl(&hdr.hdr_1_x.ts_delta))*1000; break; case 2: t += (double)pletohl(&hdr.hdr_2_x.ts_delta_lo) + (double)pletohl(&hdr.hdr_2_x.ts_delta_hi)*4294967296.0; break; } secs = (time_t)(t/1000000); usecs = (guint32)(t - (double)secs*1000000); wth->phdr.ts.secs = netmon->start_secs + secs; wth->phdr.ts.nsecs = usecs * 1000; wth->phdr.caplen = packet_size; wth->phdr.len = orig_size; /* * Attempt to guess from the packet data, the VPI, and the VCI * information about the type of traffic. */ if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) { atm_guess_traffic_type(data_ptr, packet_size, &wth->pseudo_header); } return TRUE; }
int netmon_open(wtap *wth, int *err, gchar **err_info) { int bytes_read; char magic[sizeof netmon_1_x_magic]; struct netmon_hdr hdr; int file_type; static const int netmon_encap[] = { WTAP_ENCAP_UNKNOWN, WTAP_ENCAP_ETHERNET, WTAP_ENCAP_TOKEN_RING, WTAP_ENCAP_FDDI_BITSWAPPED, WTAP_ENCAP_ATM_PDUS, /* NDIS WAN - this is what's used for ATM */ WTAP_ENCAP_UNKNOWN, /* NDIS LocalTalk */ WTAP_ENCAP_UNKNOWN, /* NDIS "DIX" - should not occur */ WTAP_ENCAP_UNKNOWN, /* NDIS ARCNET raw */ WTAP_ENCAP_UNKNOWN, /* NDIS ARCNET 878.2 */ WTAP_ENCAP_UNKNOWN, /* NDIS ATM (no, this is NOT used for ATM) */ WTAP_ENCAP_UNKNOWN, /* NDIS Wireless WAN */ WTAP_ENCAP_UNKNOWN /* NDIS IrDA */ }; #define NUM_NETMON_ENCAPS (sizeof netmon_encap / sizeof netmon_encap[0]) struct tm tm; int frame_table_offset; guint32 frame_table_length; guint32 frame_table_size; guint32 *frame_table; #ifdef WORDS_BIGENDIAN unsigned int i; #endif netmon_t *netmon; /* Read in the string that should be at the start of a Network * Monitor file */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(magic, 1, sizeof magic, wth->fh); if (bytes_read != sizeof magic) { *err = file_error(wth->fh); if (*err != 0) return -1; return 0; } if (memcmp(magic, netmon_1_x_magic, sizeof netmon_1_x_magic) != 0 && memcmp(magic, netmon_2_x_magic, sizeof netmon_1_x_magic) != 0) { return 0; } /* Read the rest of the header. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh); if (bytes_read != sizeof hdr) { *err = file_error(wth->fh); if (*err != 0) return -1; return 0; } switch (hdr.ver_major) { case 1: file_type = WTAP_FILE_NETMON_1_x; break; case 2: file_type = WTAP_FILE_NETMON_2_x; break; default: *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("netmon: major version %u unsupported", hdr.ver_major); return -1; } hdr.network = pletohs(&hdr.network); if (hdr.network >= NUM_NETMON_ENCAPS || netmon_encap[hdr.network] == WTAP_ENCAP_UNKNOWN) { *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("netmon: network type %u unknown or unsupported", hdr.network); return -1; } /* This is a netmon file */ wth->file_type = file_type; netmon = (netmon_t *)g_malloc(sizeof(netmon_t)); wth->priv = (void *)netmon; wth->subtype_read = netmon_read; wth->subtype_seek_read = netmon_seek_read; wth->subtype_sequential_close = netmon_sequential_close; /* NetMon capture file formats v2.1+ use per-packet encapsulation types. NetMon 3 sets the value in * the header to 1 (Ethernet) for backwards compability. */ /* XXX - It would be better if we could set this to WTAP_ENCAP_PER_PACKET and show a message for * that, but the wtap_read() routine asserts on that value to catch errors. */ if((hdr.ver_major == 2 && hdr.ver_minor >= 1) || hdr.ver_major > 2) wth->file_encap = WTAP_ENCAP_UNKNOWN; else wth->file_encap = netmon_encap[hdr.network]; wth->snapshot_length = 0; /* not available in header */ /* * Convert the time stamp to a "time_t" and a number of * milliseconds. */ tm.tm_year = pletohs(&hdr.ts_year) - 1900; tm.tm_mon = pletohs(&hdr.ts_month) - 1; tm.tm_mday = pletohs(&hdr.ts_day); tm.tm_hour = pletohs(&hdr.ts_hour); tm.tm_min = pletohs(&hdr.ts_min); tm.tm_sec = pletohs(&hdr.ts_sec); tm.tm_isdst = -1; netmon->start_secs = mktime(&tm); /* * XXX - what if "secs" is -1? Unlikely, but if the capture was * done in a time zone that switches between standard and summer * time sometime other than when we do, and thus the time was one * that doesn't exist here because a switch from standard to summer * time zips over it, it could happen. * * On the other hand, if the capture was done in a different time * zone, this won't work right anyway; unfortunately, the time * zone isn't stored in the capture file (why the hell didn't * they stuff a FILETIME, which is the number of 100-nanosecond * intervals since 1601-01-01 00:00:00 "UTC", there, instead * of stuffing a SYSTEMTIME, which is time-zone-dependent, there?). */ netmon->start_usecs = pletohs(&hdr.ts_msec)*1000; netmon->version_major = hdr.ver_major; /* * Get the offset of the frame index table. */ frame_table_offset = pletohl(&hdr.frametableoffset); /* * It appears that some NetMon 2.x files don't have the * first packet starting exactly 128 bytes into the file. * * Furthermore, it also appears that there are "holes" in * the file, i.e. frame N+1 doesn't always follow immediately * after frame N. * * Therefore, we must read the frame table, and use the offsets * in it as the offsets of the frames. */ frame_table_length = pletohl(&hdr.frametablelength); frame_table_size = frame_table_length / (guint32)sizeof (guint32); if ((frame_table_size * sizeof (guint32)) != frame_table_length) { *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("netmon: frame table length is %u, which is not a multiple of the size of an entry", frame_table_length); g_free(netmon); return -1; } if (frame_table_size == 0) { *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("netmon: frame table length is %u, which means it's less than one entry in size", frame_table_length); g_free(netmon); return -1; } if (file_seek(wth->fh, frame_table_offset, SEEK_SET, err) == -1) { g_free(netmon); return -1; } frame_table = g_malloc(frame_table_length); errno = WTAP_ERR_CANT_READ; bytes_read = file_read(frame_table, 1, frame_table_length, wth->fh); if ((guint32)bytes_read != frame_table_length) { *err = file_error(wth->fh); if (*err == 0) *err = WTAP_ERR_SHORT_READ; g_free(frame_table); g_free(netmon); return -1; } netmon->frame_table_size = frame_table_size; netmon->frame_table = frame_table; #ifdef WORDS_BIGENDIAN /* * OK, now byte-swap the frame table. */ for (i = 0; i < frame_table_size; i++) frame_table[i] = pletohl(&frame_table[i]); #endif /* Set up to start reading at the first frame. */ netmon->current_frame = 0; wth->tsprecision = WTAP_FILE_TSPREC_USEC; return 1; }
/* Open a file for reading */ int visual_open(wtap *wth, int *err, gchar **err_info) { int bytes_read; char magic[sizeof visual_magic]; struct visual_file_hdr vfile_hdr; struct visual_read_info * visual; int encap; /* Check the magic string at the start of the file */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(magic, sizeof magic, wth->fh); if (bytes_read != sizeof magic) { *err = file_error(wth->fh, err_info); if (*err != 0 && *err != WTAP_ERR_SHORT_READ) return -1; return 0; } if (memcmp(magic, visual_magic, sizeof visual_magic) != 0) { return 0; } /* Read the rest of the file header. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&vfile_hdr, sizeof vfile_hdr, wth->fh); if (bytes_read != sizeof vfile_hdr) { *err = file_error(wth->fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return -1; } /* Verify the file version is known */ vfile_hdr.file_version = pletohs(&vfile_hdr.file_version); if (vfile_hdr.file_version != 1) { *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("visual: file version %u unsupported", vfile_hdr.file_version); return -1; } /* Translate the encapsulation type; these values are SNMP ifType values, as found in http://www.iana.org/assignments/smi-numbers. Note that a file with media type 22 ("propPointToPointSerial") may contain Cisco HDLC or PPP over HDLC. This will get sorted out after the first packet is read. XXX - should we use WTAP_ENCAP_PER_PACKET for that? */ switch (pletohs(&vfile_hdr.media_type)) { case 6: /* ethernet-csmacd */ encap = WTAP_ENCAP_ETHERNET; break; case 9: /* IEEE802.5 */ encap = WTAP_ENCAP_TOKEN_RING; break; case 16: /* lapb */ encap = WTAP_ENCAP_LAPB; break; case 22: /* propPointToPointSerial */ case 118: /* HDLC */ encap = WTAP_ENCAP_CHDLC_WITH_PHDR; break; case 32: /* frame-relay */ encap = WTAP_ENCAP_FRELAY_WITH_PHDR; break; case 37: /* ATM */ encap = WTAP_ENCAP_ATM_PDUS; break; default: *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("visual: network type %u unknown or unsupported", vfile_hdr.media_type); return -1; } /* Fill in the wiretap struct with data from the file header */ wth->file_type = WTAP_FILE_VISUAL_NETWORKS; wth->file_encap = encap; wth->snapshot_length = pletohs(&vfile_hdr.max_length); /* Set up the pointers to the handlers for this file type */ wth->subtype_read = visual_read; wth->subtype_seek_read = visual_seek_read; wth->tsprecision = WTAP_FILE_TSPREC_USEC; /* Add Visual-specific information to the wiretap struct for later use. */ visual = (struct visual_read_info *)g_malloc(sizeof(struct visual_read_info)); wth->priv = (void *)visual; visual->num_pkts = pletohl(&vfile_hdr.num_pkts); visual->start_time = ((double) pletohl(&vfile_hdr.start_time)) * 1000000; visual->current_pkt = 1; return 1; }
/* Read the next packet */ static gboolean _5views_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { t_5VW_TimeStamped_Header TimeStamped_Header; int bytes_read; guint packet_size; guint orig_size; do { bytes_read = _5views_read_header(wth, wth->fh, &TimeStamped_Header, err, err_info); if (bytes_read == -1) { /* * We failed to read the header. */ return FALSE; } TimeStamped_Header.Key = pletohl(&TimeStamped_Header.Key); if(TimeStamped_Header.Key != CST_5VW_RECORDS_HEADER_KEY) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("5views: Time-stamped header has bad key value 0x%08X", TimeStamped_Header.Key); return FALSE; } TimeStamped_Header.RecSubType = pletohl(&TimeStamped_Header.RecSubType); TimeStamped_Header.RecSize = pletohl(&TimeStamped_Header.RecSize); if(TimeStamped_Header.RecSubType != CST_5VW_FRAME_RECORD) { if (file_seek(wth->fh, TimeStamped_Header.RecSize, SEEK_CUR, err) == -1) return FALSE; } else break; } while (1); packet_size = TimeStamped_Header.RecSize; orig_size = TimeStamped_Header.RecSize; if (packet_size > WTAP_MAX_PACKET_SIZE) { /* * Probably a corrupt capture file; don't blow up trying * to allocate space for an immensely-large packet. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("5views: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return FALSE; } *data_offset = file_tell(wth->fh); buffer_assure_space(wth->frame_buffer, packet_size); if (!_5views_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), packet_size, err, err_info)) return FALSE; /* Read error */ TimeStamped_Header.Utc = pletohl(&TimeStamped_Header.Utc); TimeStamped_Header.NanoSecondes = pletohl(&TimeStamped_Header.NanoSecondes); wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; wth->phdr.ts.secs = TimeStamped_Header.Utc; wth->phdr.ts.nsecs = TimeStamped_Header.NanoSecondes; wth->phdr.caplen = packet_size; wth->phdr.len = orig_size; switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* We assume there's no FCS in this frame. */ wth->phdr.pseudo_header.eth.fcs_len = 0; break; } return TRUE; }
static void visual_set_pseudo_header(int encap, struct visual_pkt_hdr *vpkt_hdr, struct visual_atm_hdr *vatm_hdr, union wtap_pseudo_header *pseudo_header) { guint32 packet_status; /* Set status flags. The only status currently supported for all encapsulations is direction. This either goes in the p2p or the X.25 pseudo header. It would probably be better to move this up into the phdr. */ packet_status = pletohl(&vpkt_hdr->status); switch (encap) { case WTAP_ENCAP_ETHERNET: /* XXX - is there an FCS in the frame? */ pseudo_header->eth.fcs_len = -1; break; case WTAP_ENCAP_CHDLC_WITH_PHDR: case WTAP_ENCAP_PPP_WITH_PHDR: pseudo_header->p2p.sent = (packet_status & PS_SENT) ? TRUE : FALSE; break; case WTAP_ENCAP_FRELAY_WITH_PHDR: case WTAP_ENCAP_LAPB: pseudo_header->x25.flags = (packet_status & PS_SENT) ? 0x00 : FROM_DCE; break; case WTAP_ENCAP_ATM_PDUS: /* Set defaults */ pseudo_header->atm.type = TRAF_UNKNOWN; pseudo_header->atm.subtype = TRAF_ST_UNKNOWN; pseudo_header->atm.aal5t_len = 0; /* Next two items not supported. Defaulting to zero */ pseudo_header->atm.aal5t_u2u = 0; pseudo_header->atm.aal5t_chksum = 0; /* Flags appear only to convey that packet is a raw cell. Set to 0 */ pseudo_header->atm.flags = 0; /* Not supported. Defaulting to zero */ pseudo_header->atm.aal2_cid = 0; switch(vatm_hdr->category & VN_CAT_TYPE_MASK ) { case VN_AAL1: pseudo_header->atm.aal = AAL_1; break; case VN_AAL2: pseudo_header->atm.aal = AAL_2; break; case VN_AAL34: pseudo_header->atm.aal = AAL_3_4; break; case VN_AAL5: pseudo_header->atm.aal = AAL_5; pseudo_header->atm.type = TRAF_LLCMX; pseudo_header->atm.aal5t_len = pntohl(&vatm_hdr->data_length); break; case VN_OAM: /* Marking next 3 as OAM versus unknown */ case VN_O191: case VN_IDLE: case VN_RM: pseudo_header->atm.aal = AAL_OAMCELL; break; case VN_UNKNOWN: default: pseudo_header->atm.aal = AAL_UNKNOWN; break; } pseudo_header->atm.vpi = pntohs(&vatm_hdr->vpi) & 0x0FFF; pseudo_header->atm.vci = pntohs(&vatm_hdr->vci); pseudo_header->atm.cells = pntohs(&vatm_hdr->cell_count); /* Using bit value of 1 (DCE -> DTE) to indicate From Network */ pseudo_header->atm.channel = vatm_hdr->info & FROM_NETWORK; break; } }
static gboolean radcom_read_rec(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { struct radcomrec_hdr hdr; int bytes_read; guint16 data_length, real_length, length; guint32 sec; struct tm tm; guint8 atmhdr[8]; errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&hdr, sizeof hdr, fh); if (bytes_read != sizeof hdr) { *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } data_length = pletohs(&hdr.data_length); if (data_length == 0) { /* * The last record appears to have 0 in its "data_length" * field, but non-zero values in other fields, so we * check for that and treat it as an EOF indication. */ *err = 0; return FALSE; } length = pletohs(&hdr.length); real_length = pletohs(&hdr.real_length); phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; tm.tm_year = pletohs(&hdr.date.year)-1900; tm.tm_mon = (hdr.date.month&0x0f)-1; tm.tm_mday = hdr.date.day; sec = pletohl(&hdr.date.sec); tm.tm_hour = sec/3600; tm.tm_min = (sec%3600)/60; tm.tm_sec = sec%60; tm.tm_isdst = -1; phdr->ts.secs = mktime(&tm); phdr->ts.nsecs = pletohl(&hdr.date.usec) * 1000; switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* XXX - is there an FCS? */ phdr->pseudo_header.eth.fcs_len = -1; break; case WTAP_ENCAP_LAPB: phdr->pseudo_header.x25.flags = (hdr.dce & 0x1) ? 0x00 : FROM_DCE; length -= 2; /* FCS */ real_length -= 2; break; case WTAP_ENCAP_ATM_RFC1483: /* * XXX - is this stuff a pseudo-header? * The direction appears to be in the "hdr.dce" field. */ if (!radcom_read_rec_data(wth->fh, atmhdr, sizeof atmhdr, err, err_info)) return FALSE; /* Read error */ length -= 8; real_length -= 8; break; } phdr->len = real_length; phdr->caplen = length; /* * Read the packet data. */ if (!wtap_read_packet_bytes(fh, buf, length, err, err_info)) return FALSE; /* Read error */ return TRUE; }
void capture_radiotap(const guchar *pd, int offset, int len, packet_counts *ld) { guint16 it_len; guint32 present; guint8 rflags; if(!BYTES_ARE_IN_FRAME(offset, len, RADIOTAP_MIN_HEADER_LEN)) { ld->other ++; return; } it_len = pletohs(&pd[RADIOTAP_LENGTH_OFFSET]); if(!BYTES_ARE_IN_FRAME(offset, len, it_len)) { ld->other ++; return; } if(it_len > len) { /* Header length is bigger than total packet length */ ld->other ++; return; } if(it_len < RADIOTAP_MIN_HEADER_LEN) { /* Header length is shorter than fixed-length portion of header */ ld->other ++; return; } present = pletohl(&pd[RADIOTAP_PRESENT_OFFSET]); offset += RADIOTAP_MIN_HEADER_LEN; it_len -= RADIOTAP_MIN_HEADER_LEN; rflags = 0; /* * IEEE80211_RADIOTAP_TSFT is the lowest-order bit. */ if (present & BIT(IEEE80211_RADIOTAP_TSFT)) { if (it_len < 8) { /* No room in header for this field. */ ld->other ++; return; } /* That field is present, and it's 8 bits long. */ offset += 8; it_len -= 8; } /* * IEEE80211_RADIOTAP_FLAGS is the next bit. */ if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) { if (it_len < 1) { /* No room in header for this field. */ ld->other ++; return; } /* That field is present; fetch it. */ if(!BYTES_ARE_IN_FRAME(offset, len, 1)) { ld->other ++; return; } rflags = pd[offset]; } /* 802.11 header follows */ if (rflags & IEEE80211_RADIOTAP_F_DATAPAD) capture_ieee80211_datapad(pd, offset + it_len, len, ld); else capture_ieee80211(pd, offset + it_len, len, ld); }
int radcom_open(wtap *wth, int *err, gchar **err_info) { int bytes_read; guint8 r_magic[8], t_magic[11], search_encap[7]; struct frame_date start_date; #if 0 guint32 sec; struct tm tm; #endif /* Read in the string that should be at the start of a RADCOM file */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(r_magic, 8, wth->fh); if (bytes_read != 8) { *err = file_error(wth->fh, err_info); if (*err != 0 && *err != WTAP_ERR_SHORT_READ) return -1; return 0; } /* XXX: bytes 2 and 3 of the "magic" header seem to be different in some * captures. We force them to our standard value so that the test * succeeds (until we find if they have a special meaning, perhaps a * version number ?) */ r_magic[1] = 0xD2; r_magic[2] = 0x00; if (memcmp(r_magic, radcom_magic, 8) != 0) { return 0; } /* Look for the "Active Time" string. The "frame_date" structure should * be located 32 bytes before the beginning of this string */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(t_magic, 11, wth->fh); if (bytes_read != 11) { *err = file_error(wth->fh, err_info); if (*err != 0 && *err != WTAP_ERR_SHORT_READ) return -1; return 0; } while (memcmp(t_magic, active_time_magic, 11) != 0) { if (file_seek(wth->fh, -10, SEEK_CUR, err) == -1) return -1; errno = WTAP_ERR_CANT_READ; bytes_read = file_read(t_magic, 11, wth->fh); if (bytes_read != 11) { *err = file_error(wth->fh, err_info); if (*err != 0 && *err != WTAP_ERR_SHORT_READ) return -1; return 0; } } if (file_seek(wth->fh, -43, SEEK_CUR, err) == -1) return -1; /* Get capture start time */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&start_date, sizeof(struct frame_date), wth->fh); if (bytes_read != sizeof(struct frame_date)) { *err = file_error(wth->fh, err_info); if (*err != 0 && *err != WTAP_ERR_SHORT_READ) return -1; return 0; } /* This is a radcom file */ wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_RADCOM; wth->subtype_read = radcom_read; wth->subtype_seek_read = radcom_seek_read; wth->snapshot_length = 0; /* not available in header, only in frame */ wth->tsprecision = WTAP_FILE_TSPREC_USEC; #if 0 tm.tm_year = pletohs(&start_date.year)-1900; tm.tm_mon = start_date.month-1; tm.tm_mday = start_date.day; sec = pletohl(&start_date.sec); tm.tm_hour = sec/3600; tm.tm_min = (sec%3600)/60; tm.tm_sec = sec%60; tm.tm_isdst = -1; #endif if (file_seek(wth->fh, sizeof(struct frame_date), SEEK_CUR, err) == -1) return -1; errno = WTAP_ERR_CANT_READ; bytes_read = file_read(search_encap, 4, wth->fh); if (bytes_read != 4) { goto read_error; } while (memcmp(encap_magic, search_encap, 4)) { if (file_seek(wth->fh, -3, SEEK_CUR, err) == -1) return -1; errno = WTAP_ERR_CANT_READ; bytes_read = file_read(search_encap, 4, wth->fh); if (bytes_read != 4) { goto read_error; } } if (file_seek(wth->fh, 12, SEEK_CUR, err) == -1) return -1; errno = WTAP_ERR_CANT_READ; bytes_read = file_read(search_encap, 4, wth->fh); if (bytes_read != 4) { goto read_error; } if (memcmp(search_encap, "LAPB", 4) == 0) wth->file_encap = WTAP_ENCAP_LAPB; else if (memcmp(search_encap, "Ethe", 4) == 0) wth->file_encap = WTAP_ENCAP_ETHERNET; else if (memcmp(search_encap, "ATM/", 4) == 0) wth->file_encap = WTAP_ENCAP_ATM_RFC1483; else { *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("radcom: network type \"%.4s\" unknown", search_encap); return -1; } #if 0 bytes_read = file_read(&next_date, sizeof(struct frame_date), wth->fh); errno = WTAP_ERR_CANT_READ; if (bytes_read != sizeof(struct frame_date)) { goto read_error; } while (memcmp(&start_date, &next_date, 4)) { if (file_seek(wth->fh, 1-sizeof(struct frame_date), SEEK_CUR, err) == -1) return -1; errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&next_date, sizeof(struct frame_date), wth->fh); if (bytes_read != sizeof(struct frame_date)) { goto read_error; } } #endif if (wth->file_encap == WTAP_ENCAP_ETHERNET) { if (file_seek(wth->fh, 294, SEEK_CUR, err) == -1) return -1; } else if (wth->file_encap == WTAP_ENCAP_LAPB) { if (file_seek(wth->fh, 297, SEEK_CUR, err) == -1) return -1; } else if (wth->file_encap == WTAP_ENCAP_ATM_RFC1483) { if (file_seek(wth->fh, 504, SEEK_CUR, err) == -1) return -1; } return 1; read_error: *err = file_error(wth->fh, err_info); if (*err != 0) return -1; return 0; }
int netmon_open(wtap *wth, int *err, gchar **err_info) { int bytes_read; char magic[sizeof netmon_1_x_magic]; struct netmon_hdr hdr; int file_type; struct tm tm; guint32 frame_table_offset; guint32 frame_table_length; guint32 frame_table_size; guint32 *frame_table; #ifdef WORDS_BIGENDIAN unsigned int i; #endif netmon_t *netmon; /* Read in the string that should be at the start of a Network * Monitor file */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(magic, sizeof magic, wth->fh); if (bytes_read != sizeof magic) { *err = file_error(wth->fh, err_info); if (*err != 0) return -1; return 0; } if (memcmp(magic, netmon_1_x_magic, sizeof netmon_1_x_magic) != 0 && memcmp(magic, netmon_2_x_magic, sizeof netmon_1_x_magic) != 0) { return 0; } /* Read the rest of the header. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&hdr, sizeof hdr, wth->fh); if (bytes_read != sizeof hdr) { *err = file_error(wth->fh, err_info); if (*err != 0) return -1; return 0; } switch (hdr.ver_major) { case 1: file_type = WTAP_FILE_NETMON_1_x; break; case 2: file_type = WTAP_FILE_NETMON_2_x; break; default: *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("netmon: major version %u unsupported", hdr.ver_major); return -1; } hdr.network = pletohs(&hdr.network); if (hdr.network >= NUM_NETMON_ENCAPS || netmon_encap[hdr.network] == WTAP_ENCAP_UNKNOWN) { *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("netmon: network type %u unknown or unsupported", hdr.network); return -1; } /* This is a netmon file */ wth->file_type = file_type; netmon = (netmon_t *)g_malloc(sizeof(netmon_t)); wth->priv = (void *)netmon; wth->subtype_read = netmon_read; wth->subtype_seek_read = netmon_seek_read; wth->subtype_sequential_close = netmon_sequential_close; /* NetMon capture file formats v2.1+ use per-packet encapsulation types. NetMon 3 sets the value in * the header to 1 (Ethernet) for backwards compability. */ if((hdr.ver_major == 2 && hdr.ver_minor >= 1) || hdr.ver_major > 2) wth->file_encap = WTAP_ENCAP_PER_PACKET; else wth->file_encap = netmon_encap[hdr.network]; wth->snapshot_length = 0; /* not available in header */ /* * Convert the time stamp to a "time_t" and a number of * milliseconds. */ tm.tm_year = pletohs(&hdr.ts_year) - 1900; tm.tm_mon = pletohs(&hdr.ts_month) - 1; tm.tm_mday = pletohs(&hdr.ts_day); tm.tm_hour = pletohs(&hdr.ts_hour); tm.tm_min = pletohs(&hdr.ts_min); tm.tm_sec = pletohs(&hdr.ts_sec); tm.tm_isdst = -1; netmon->start_secs = mktime(&tm); /* * XXX - what if "secs" is -1? Unlikely, but if the capture was * done in a time zone that switches between standard and summer * time sometime other than when we do, and thus the time was one * that doesn't exist here because a switch from standard to summer * time zips over it, it could happen. * * On the other hand, if the capture was done in a different time * zone, this won't work right anyway; unfortunately, the time * zone isn't stored in the capture file (why the hell didn't * they stuff a FILETIME, which is the number of 100-nanosecond * intervals since 1601-01-01 00:00:00 "UTC", there, instead * of stuffing a SYSTEMTIME, which is time-zone-dependent, there?). */ netmon->start_nsecs = pletohs(&hdr.ts_msec)*1000000; netmon->version_major = hdr.ver_major; netmon->version_minor = hdr.ver_minor; /* * Get the offset of the frame index table. */ frame_table_offset = pletohl(&hdr.frametableoffset); /* * It appears that some NetMon 2.x files don't have the * first packet starting exactly 128 bytes into the file. * * Furthermore, it also appears that there are "holes" in * the file, i.e. frame N+1 doesn't always follow immediately * after frame N. * * Therefore, we must read the frame table, and use the offsets * in it as the offsets of the frames. */ frame_table_length = pletohl(&hdr.frametablelength); frame_table_size = frame_table_length / (guint32)sizeof (guint32); if ((frame_table_size * sizeof (guint32)) != frame_table_length) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("netmon: frame table length is %u, which is not a multiple of the size of an entry", frame_table_length); g_free(netmon); return -1; } if (frame_table_size == 0) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("netmon: frame table length is %u, which means it's less than one entry in size", frame_table_length); g_free(netmon); return -1; } /* * XXX - clamp the size of the frame table, so that we don't * attempt to allocate a huge frame table and fail. * * Given that file offsets in the frame table are 32-bit, * a NetMon file cannot be bigger than 2^32 bytes. * Given that a NetMon 1.x-format packet header is 8 bytes, * that means a NetMon file cannot have more than * 512*2^20 packets. We'll pick that as the limit for * now; it's 1/8th of a 32-bit address space, which is * probably not going to exhaust the address space all by * itself, and probably won't exhaust the backing store. */ if (frame_table_size > 512*1024*1024) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("netmon: frame table length is %u, which is larger than we support", frame_table_length); g_free(netmon); return -1; } if (file_seek(wth->fh, frame_table_offset, SEEK_SET, err) == -1) { g_free(netmon); return -1; } frame_table = g_malloc(frame_table_length); errno = WTAP_ERR_CANT_READ; bytes_read = file_read(frame_table, frame_table_length, wth->fh); if ((guint32)bytes_read != frame_table_length) { *err = file_error(wth->fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; g_free(frame_table); g_free(netmon); return -1; } netmon->frame_table_size = frame_table_size; netmon->frame_table = frame_table; #ifdef WORDS_BIGENDIAN /* * OK, now byte-swap the frame table. */ for (i = 0; i < frame_table_size; i++) frame_table[i] = pletohl(&frame_table[i]); #endif /* Set up to start reading at the first frame. */ netmon->current_frame = 0; switch (netmon->version_major) { case 1: /* * Version 1.x of the file format supports * millisecond precision. */ wth->tsprecision = WTAP_FILE_TSPREC_MSEC; break; case 2: /* * Version 1.x of the file format supports * 100-nanosecond precision; we don't * currently support that, so say * "nanosecond precision" for now. */ wth->tsprecision = WTAP_FILE_TSPREC_NSEC; break; } return 1; }
/* * Process the packet header. * * XXX - we should supply the additional radio information; * the pseudo-header should probably be supplied in a fashion * similar to the new BSD radio header, so that the 802.11 * dissector can determine which, if any, information items * are present. */ static int airopeekv9_process_header(FILE_T fh, hdr_info_t *hdr_info, int *err, gchar **err_info) { int header_len = 0; int bytes_read; guint8 tag_value[6]; guint16 tag; gboolean saw_length = FALSE; gboolean saw_timestamp_lower = FALSE; gboolean saw_timestamp_upper = FALSE; /* Extract the fields from the packet header */ do { /* Get the tag and value. XXX - this assumes all values are 4 bytes long. */ bytes_read = file_read(tag_value, 1, sizeof tag_value, fh); if (bytes_read != (int) sizeof tag_value) { *err = file_error(fh); if (*err == 0) { if (bytes_read > 0) *err = WTAP_ERR_SHORT_READ; else if (bytes_read == 0) { /* * Short read if we've read something already; * just an EOF if we haven't. */ if (header_len != 0) *err = WTAP_ERR_SHORT_READ; } } return 0; } header_len += (int) sizeof(tag_value); tag = pletohs(&tag_value[0]); switch (tag) { case TAG_AIROPEEK_V9_LENGTH: if (saw_length) { *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup("airopeekv9: record has two length fields"); return 0; } hdr_info->length = pletohl(&tag_value[2]); saw_length = TRUE; break; case TAG_AIROPEEK_V9_TIMESTAMP_LOWER: if (saw_timestamp_lower) { *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup("airopeekv9: record has two timestamp-lower fields"); return 0; } hdr_info->timestamp.lower = pletohl(&tag_value[2]); saw_timestamp_lower = TRUE; break; case TAG_AIROPEEK_V9_TIMESTAMP_UPPER: if (saw_timestamp_upper) { *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup("airopeekv9: record has two timestamp-upper fields"); return 0; } hdr_info->timestamp.upper = pletohl(&tag_value[2]); saw_timestamp_upper = TRUE; break; case TAG_AIROPEEK_V9_FLAGS_AND_STATUS: /* XXX - not used yet */ break; case TAG_AIROPEEK_V9_CHANNEL: hdr_info->ieee_802_11.channel = pletohl(&tag_value[2]); break; case TAG_AIROPEEK_V9_RATE: hdr_info->ieee_802_11.data_rate = pletohl(&tag_value[2]); break; case TAG_AIROPEEK_V9_SIGNAL_PERC: hdr_info->ieee_802_11.signal_level = pletohl(&tag_value[2]); break; case TAG_AIROPEEK_V9_SIGNAL_DBM: /* XXX - not used yet */ break; case TAG_AIROPEEK_V9_NOISE_PERC: /* XXX - not used yet */ break; case TAG_AIROPEEK_V9_NOISE_DBM: /* XXX - not used yet */ break; case TAG_AIROPEEK_V9_UNKNOWN_0x000D: /* XXX - seen in an EtherPeek capture; value unknown */ break; case TAG_AIROPEEK_V9_SLICE_LENGTH: hdr_info->sliceLength = pletohl(&tag_value[2]); break; default: break; } } while (tag != TAG_AIROPEEK_V9_SLICE_LENGTH); /* last tag */ if (!saw_length) { *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup("airopeekv9: record has no length field"); return 0; } if (!saw_timestamp_lower) { *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup("airopeekv9: record has no timestamp-lower field"); return 0; } if (!saw_timestamp_upper) { *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup("airopeekv9: record has no timestamp-upper field"); return 0; } return header_len; }
int pread_erf_live (struct timeval *ptime, int *plen, int *ptlen, void **pphys, int *pphystype, struct ip **ppip, void **pplast) { unsigned short ether_type = 0; erf_record_t *curr_erf = NULL; unsigned int len, old, new; Bool erftype_ok = FALSE; #ifdef HAVE_LONG_LONG unsigned long long ts; #endif int dagfd = erfbuf_ptr[0].dagfd; /* loop until isn't find an ERF of correct type (ETH, ATM, HDLC) * with IP packet inside */ while (!erftype_ok) { curr_erf = (erf_record_t *) dag_rx_stream_next_record (dagfd, 0); if (curr_erf) { len = ntohs (curr_erf->rlen); /* User processing here */ if (debug > 1) fprintf (fp_stderr, "Got a new packet from the buffer (len = %d)\n", len); if (debug > 2) print_erf_record (curr_erf); #ifdef HAVE_LONG_LONG ts = pletohll (&curr_erf->ts); ptime->tv_sec = ts >> 32; ts = ((ts & 0xffffffffULL) * 1000 * 1000); ts += (ts & 0x80000000ULL) << 1; /* rounding */ ptime->tv_usec = ts >> 32; if (ptime->tv_usec >= 1000000) { ptime->tv_usec -= 1000000; ptime->tv_sec += 1; } #else ptime->tv_sec = pletohl (&curr_erf->ts[1]); ptime->tv_usec = (unsigned long) ((pletohl (&curr_erf->ts[0]) * 1000000.0) / 0xffffffffUL); #endif switch (curr_erf->type) { case ERFT_ATM: erftype_ok = TRUE; *ptlen = ATM_SLEN (curr_erf); *plen = ATM_WLEN (curr_erf); *pphys = ð_header; ether_type = ntohs (((unsigned short *) &curr_erf->rec.atm.pload)[3]); *ppip = (struct ip *) &curr_erf->rec.atm.pload[8]; /* skip snap/llc */ *pplast = ((char *) *ppip) + *ptlen - 8 - 1; break; case ERFT_ETH: erftype_ok = TRUE; *ptlen = ETHERNET_SLEN (curr_erf); *plen = ETHERNET_WLEN (curr_erf); *pphys = &curr_erf->rec.eth.dst; ether_type = ntohs (curr_erf->rec.eth.etype); *ppip = (struct ip *) &curr_erf->rec.eth.pload[0]; *pplast = ((char *) *ppip) + *ptlen - sizeof (struct ether_header) - 1; break; case ERFT_HDLC_POS: erftype_ok = TRUE; *ptlen = HDLC_SLEN (curr_erf); *plen = HDLC_WLEN (curr_erf); *pphys = ð_header; /* Detect PPP and convert the Ethertype value */ if (ntohs (((unsigned short *) &curr_erf->rec.pos.hdlc)[0]) == 0xff03) { if (ntohs (((unsigned short *) &curr_erf->rec.pos.hdlc)[1]) == 0x0021) { ether_type = ETHERTYPE_IP; } } else { ether_type = ntohs (((unsigned short *) &curr_erf->rec.pos.hdlc)[1]); } *ppip = (struct ip *) &curr_erf->rec.pos.pload[0]; *pplast = ((char *) *ppip) + *ptlen - 4 - 1; break; default: fprintf (fp_stderr, "Unsupported ERF type: %d\n", curr_erf->type); } *pphystype = PHYS_ETHER; /* if it's not IP, then skip it */ if (ether_type != ETHERTYPE_IP && ether_type != ETHERTYPE_IPV6) { if (debug > 2) fprintf (fp_stderr, "pread_erf: not an IP packet\n"); erftype_ok = FALSE; } /* return 0 mean EOF */ return 1; } else { /* rec == NULL */ if (errno != EAGAIN) { fprintf (fp_stderr, "dag_get_next_record: %s\n", strerror (errno)); exit (1); } } }
/* ** Netscaler trace format read routines. */ gboolean nstrace_read_v10(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { nstrace_t *nstrace = (nstrace_t *)wth->priv; guint64 nsg_creltime = nstrace->nsg_creltime; gchar *nstrace_buf = nstrace->pnstrace_buf; gint32 nstrace_buf_offset = nstrace->nstrace_buf_offset; gint32 nstrace_buflen = nstrace->nstrace_buflen; nspr_pktracefull_v10_t *fp; nspr_pktracepart_v10_t *pp; *err = 0; *err_info = NULL; do { while ((nstrace_buf_offset < nstrace_buflen) && ((nstrace_buflen - nstrace_buf_offset) >= ((gint32)sizeof(fp->nsprRecordType)))) { fp = (nspr_pktracefull_v10_t *) &nstrace_buf[nstrace_buf_offset]; pp = (nspr_pktracepart_v10_t *) fp; switch (pletohs(&fp->nsprRecordType)) { case NSPR_PDPKTRACEFULLTX_V10: case NSPR_PDPKTRACEFULLTXB_V10: case NSPR_PDPKTRACEFULLRX_V10: nsg_creltime += ns_hrtime2nsec(pletohl(&fp->fp_RelTimeHr)); wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000); wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000); wth->phdr.len = pletohs(&fp->nsprRecordSize); wth->phdr.caplen = wth->phdr.len; TRACE_V10_REC_LEN_OFF(v10_full,fp,pktracefull_v10); buffer_assure_space(wth->frame_buffer, wth->phdr.caplen); memcpy(buffer_start_ptr(wth->frame_buffer), fp, wth->phdr.caplen); *data_offset = wth->data_offset + nstrace_buf_offset; nstrace->nstrace_buf_offset = nstrace_buf_offset + wth->phdr.len; nstrace->nstrace_buflen = nstrace_buflen; nstrace->nsg_creltime = nsg_creltime; return TRUE; case NSPR_PDPKTRACEPARTTX_V10: case NSPR_PDPKTRACEPARTTXB_V10: case NSPR_PDPKTRACEPARTRX_V10: nsg_creltime += ns_hrtime2nsec(pletohl(&pp->pp_RelTimeHr)); wth->phdr.ts.secs = nstrace->nspm_curtime + (guint32) (nsg_creltime / 1000000000); wth->phdr.ts.nsecs = (guint32) (nsg_creltime % 1000000000); wth->phdr.len = pletohs(&pp->pp_PktSizeOrg) + nspr_pktracepart_v10_s; wth->phdr.caplen = pletohs(&pp->nsprRecordSize); TRACE_V10_REC_LEN_OFF(v10_part,pp,pktracepart_v10); buffer_assure_space(wth->frame_buffer, wth->phdr.caplen); memcpy(buffer_start_ptr(wth->frame_buffer), pp, wth->phdr.caplen); *data_offset = wth->data_offset + nstrace_buf_offset; nstrace->nstrace_buf_offset = nstrace_buf_offset + wth->phdr.caplen; nstrace->nsg_creltime = nsg_creltime; nstrace->nstrace_buflen = nstrace_buflen; return TRUE; case NSPR_ABSTIME_V10: ns_setabstime(nstrace, pletohl(&((nspr_abstime_v10_t *) fp)->abs_Time), pletohl(&((nspr_abstime_v10_t *) fp)->abs_RelTime)); nstrace_buf_offset += pletohs(&fp->nsprRecordSize); break; case NSPR_RELTIME_V10: ns_setrelativetime(nstrace, ((nspr_abstime_v10_t *) fp)->abs_RelTime); nstrace_buf_offset += pletohs(&fp->nsprRecordSize); break; case NSPR_UNUSEDSPACE_V10: nstrace_buf_offset = nstrace_buflen; break; default: nstrace_buf_offset += pletohs(&fp->nsprRecordSize); break; } } nstrace_buf_offset = 0; wth->data_offset += nstrace_buflen; nstrace_buflen = GET_READ_PAGE_SIZE((nstrace->file_size - wth->data_offset)); }while((nstrace_buflen > 0) && (nstrace_buflen == (file_read(nstrace_buf, 1, nstrace_buflen, wth->fh)))); return FALSE; }