static gboolean parse_dbs_etherwatch_packet(struct wtap_pkthdr *phdr, FILE_T fh, Buffer* buf, int *err, gchar **err_info) { guint8 *pd; char line[DBS_ETHERWATCH_LINE_LENGTH]; int num_items_scanned; int eth_hdr_len, pkt_len, csec; int length_pos, length_from, length; struct tm tm; char mon[4] = "xxx"; gchar *p; static const gchar months[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"; int count, line_count; /* Make sure we have enough room for the packet */ buffer_assure_space(buf, DBS_ETHERWATCH_MAX_PACKET_LEN); pd = buffer_start_ptr(buf); eth_hdr_len = 0; memset(&tm, 0, sizeof(tm)); /* Our file pointer should be on the first line containing the * summary information for a packet. Read in that line and * extract the useful information */ if (file_gets(line, DBS_ETHERWATCH_LINE_LENGTH, fh) == NULL) { *err = file_error(fh, err_info); if (*err == 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } /* Get the destination address */ p = strstr(line, DEST_MAC_PREFIX); if(!p) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("dbs_etherwatch: destination address not found"); return FALSE; } p += strlen(DEST_MAC_PREFIX); if(parse_hex_dump(p, &pd[eth_hdr_len], HEX_HDR_SPR, HEX_HDR_END) != MAC_ADDR_LENGTH) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("dbs_etherwatch: destination address not valid"); return FALSE; } eth_hdr_len += MAC_ADDR_LENGTH; /* Get the source address */ /* * Since the first part of the line is already skipped in order to find * the start of the record we cannot index, just look for the first * 'HEX' character */ p = line; while(!isxdigit((guchar)*p)) { p++; } if(parse_hex_dump(p, &pd[eth_hdr_len], HEX_HDR_SPR, HEX_HDR_END) != MAC_ADDR_LENGTH) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("dbs_etherwatch: source address not valid"); return FALSE; } eth_hdr_len += MAC_ADDR_LENGTH; /* Read the next line of the record header */ if (file_gets(line, DBS_ETHERWATCH_LINE_LENGTH, fh) == NULL) { *err = file_error(fh, err_info); if (*err == 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } /* Check the lines is as least as long as the length position */ if(strlen(line) < LENGTH_POS) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("dbs_etherwatch: line too short"); return FALSE; } num_items_scanned = sscanf(line + LENGTH_POS, "%9d byte buffer at %2d-%3s-%4d %2d:%2d:%2d.%9d", &pkt_len, &tm.tm_mday, mon, &tm.tm_year, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &csec); if (num_items_scanned != 8) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("dbs_etherwatch: header line not valid"); return FALSE; } /* Determine whether it is Ethernet II or IEEE 802 */ if(strncmp(&line[ETH_II_CHECK_POS], ETH_II_CHECK_STR, strlen(ETH_II_CHECK_STR)) == 0) { /* Ethernet II */ /* Get the Protocol */ if(parse_hex_dump(&line[PROTOCOL_POS], &pd[eth_hdr_len], HEX_HDR_SPR, HEX_HDR_END) != PROTOCOL_LENGTH) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("dbs_etherwatch: Ethernet II protocol value not valid"); return FALSE; } eth_hdr_len += PROTOCOL_LENGTH; } else { /* IEEE 802 */ /* Remember where to put the length in the header */ length_pos = eth_hdr_len; /* Leave room in the header for the length */ eth_hdr_len += IEEE802_LEN_LEN; /* Remember how much of the header should not be added to the length */ length_from = eth_hdr_len; /* Get the DSAP + SSAP */ if(parse_hex_dump(&line[SAP_POS], &pd[eth_hdr_len], HEX_HDR_SPR, HEX_HDR_END) != SAP_LENGTH) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("dbs_etherwatch: 802.2 DSAP+SSAP value not valid"); return FALSE; } eth_hdr_len += SAP_LENGTH; /* Get the (first part of the) control field */ if(parse_hex_dump(&line[CTL_POS], &pd[eth_hdr_len], HEX_HDR_SPR, HEX_HDR_END) != CTL_UNNUMB_LENGTH) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("dbs_etherwatch: 802.2 control field first part not valid"); return FALSE; } /* Determine whether the control is numbered, and thus longer */ if((pd[eth_hdr_len] & CTL_UNNUMB_MASK) != CTL_UNNUMB_VALUE) { /* Get the rest of the control field, the first octet in the PID */ if(parse_hex_dump(&line[PID_POS], &pd[eth_hdr_len + CTL_UNNUMB_LENGTH], HEX_HDR_END, HEX_HDR_SPR) != CTL_NUMB_LENGTH - CTL_UNNUMB_LENGTH) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("dbs_etherwatch: 802.2 control field second part value not valid"); return FALSE; } eth_hdr_len += CTL_NUMB_LENGTH; } else { eth_hdr_len += CTL_UNNUMB_LENGTH; } /* Determine whether it is SNAP */ if(strncmp(&line[SNAP_CHECK_POS], SNAP_CHECK_STR, strlen(SNAP_CHECK_STR)) == 0) { /* Get the PID */ if(parse_hex_dump(&line[PID_POS], &pd[eth_hdr_len], HEX_HDR_SPR, HEX_PID_END) != PID_LENGTH) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("dbs_etherwatch: 802.2 PID value not valid"); return FALSE; } eth_hdr_len += PID_LENGTH; } /* Write the length in the header */ length = eth_hdr_len - length_from + pkt_len; pd[length_pos] = (length) >> 8; pd[length_pos+1] = (length) & 0xFF; } phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; p = strstr(months, mon); if (p) tm.tm_mon = (int)(p - months) / 3; tm.tm_year -= 1900; tm.tm_isdst = -1; phdr->ts.secs = mktime(&tm); phdr->ts.nsecs = csec * 10000000; phdr->caplen = eth_hdr_len + pkt_len; phdr->len = eth_hdr_len + pkt_len; /* * We don't have an FCS in this frame. */ phdr->pseudo_header.eth.fcs_len = 0; /* Parse the hex dump */ count = 0; while (count < pkt_len) { if (file_gets(line, DBS_ETHERWATCH_LINE_LENGTH, fh) == NULL) { *err = file_error(fh, err_info); if (*err == 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } if (!(line_count = parse_single_hex_dump_line(line, &pd[eth_hdr_len + count], count))) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("dbs_etherwatch: packet data value not valid"); return FALSE; } count += line_count; if (count > pkt_len) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("dbs_etherwatch: packet data value has too many bytes"); return FALSE; } } 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; }
/* Parses a packet record. */ static gboolean parse_vms_packet(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { char line[VMS_LINE_LENGTH + 1]; int num_items_scanned; int pkt_len = 0; int pktnum; int csec = 101; struct tm tm; char mon[4] = {'J', 'A', 'N', 0}; gchar *p; static const gchar months[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"; int i; int offset = 0; guint8 *pd; tm.tm_year = 1970; tm.tm_mon = 0; tm.tm_mday = 1; tm.tm_hour = 1; tm.tm_min = 1; tm.tm_sec = 1; /* Skip lines until one starts with a hex number */ do { if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) { *err = file_error(fh, err_info); if ((*err == 0) && (csec != 101)) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } line[VMS_LINE_LENGTH] = '\0'; if ((csec == 101) && (p = strstr(line, "packet ")) != NULL && (! strstr(line, "could not save "))) { /* Find text in line starting with "packet ". */ /* First look for the Format 1 type sequencing */ num_items_scanned = sscanf(p, "packet %9d at %2d-%3s-%4d %2d:%2d:%2d.%9d", &pktnum, &tm.tm_mday, mon, &tm.tm_year, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &csec); /* Next look for the Format 2 type sequencing */ if (num_items_scanned != 8) { num_items_scanned = sscanf(p, "packet seq # = %9d at %2d-%3s-%4d %2d:%2d:%2d.%9d", &pktnum, &tm.tm_mday, mon, &tm.tm_year, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &csec); } /* if unknown format then exit with error */ /* We will need to add code to handle new format */ if (num_items_scanned != 8) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("vms: header line not valid"); return FALSE; } } if ( (! pkt_len) && (p = strstr(line, "Length"))) { p += sizeof("Length "); while (*p && ! isdigit((guchar)*p)) p++; if ( !*p ) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("vms: Length field not valid"); return FALSE; } pkt_len = atoi(p); break; } } while (! isdumpline(line)); p = strstr(months, mon); if (p) tm.tm_mon = (int) (p - months) / 3; tm.tm_year -= 1900; tm.tm_isdst = -1; phdr->presence_flags = WTAP_HAS_TS; phdr->ts.secs = mktime(&tm); phdr->ts.nsecs = csec * 10000000; phdr->caplen = pkt_len; phdr->len = pkt_len; /* Make sure we have enough room for the packet */ buffer_assure_space(buf, pkt_len); pd = buffer_start_ptr(buf); /* Convert the ASCII hex dump to binary data */ for (i = 0; i < pkt_len; i += 16) { if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) { *err = file_error(fh, err_info); if (*err == 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } line[VMS_LINE_LENGTH] = '\0'; if (i == 0) { while (! isdumpline(line)) { /* advance to start of hex data */ if (file_gets(line, VMS_LINE_LENGTH, fh) == NULL) { *err = file_error(fh, err_info); if (*err == 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } line[VMS_LINE_LENGTH] = '\0'; } while (line[offset] && !isxdigit((guchar)line[offset])) offset++; } if (!parse_single_hex_dump_line(line, pd, i, offset, pkt_len - i)) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("vms: hex dump not valid"); return FALSE; } } /* Avoid TCPIPTRACE-W-BUFFERSFUL, TCPIPtrace could not save n packets. * errors. * * XXX - when we support packet drop report information in the * Wiretap API, we should parse those lines and return "n" as * a packet drop count. */ if (!file_gets(line, VMS_LINE_LENGTH, fh)) { *err = file_error(fh, err_info); if (*err == 0) { /* There is no next line, so there's no "TCPIPtrace could not * save n packets" line; not an error. */ return TRUE; } return FALSE; } return TRUE; }
/* Read the next packet */ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { struct pcaprec_ss990915_hdr hdr; guint packet_size; guint orig_size; int bytes_read; guint8 fddi_padding[3]; int phdr_len; libpcap_t *libpcap; bytes_read = libpcap_read_header(wth, err, err_info, &hdr); if (bytes_read == -1) { /* * We failed to read the header. */ return FALSE; } wth->data_offset += bytes_read; packet_size = hdr.hdr.incl_len; orig_size = hdr.hdr.orig_len; /* * AIX appears to put 3 bytes of padding in front of FDDI * frames; strip that crap off. */ if (wth->file_type == WTAP_FILE_PCAP_AIX && (wth->file_encap == WTAP_ENCAP_FDDI || wth->file_encap == WTAP_ENCAP_FDDI_BITSWAPPED)) { /* * The packet size is really a record size and includes * the padding. */ packet_size -= 3; orig_size -= 3; wth->data_offset += 3; /* * Read the padding. */ if (!libpcap_read_rec_data(wth->fh, fddi_padding, 3, err, err_info)) return FALSE; /* Read error */ } *data_offset = wth->data_offset; libpcap = (libpcap_t *)wth->priv; phdr_len = pcap_process_pseudo_header(wth->fh, wth->file_type, wth->file_encap, packet_size, TRUE, &wth->phdr, &wth->pseudo_header, err, err_info); if (phdr_len < 0) return FALSE; /* error */ /* * Don't count any pseudo-header as part of the packet. */ orig_size -= phdr_len; packet_size -= phdr_len; wth->data_offset += phdr_len; buffer_assure_space(wth->frame_buffer, packet_size); if (!libpcap_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), packet_size, err, err_info)) return FALSE; /* Read error */ wth->data_offset += packet_size; wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; /* Update the Timestamp, if not already done */ if (wth->file_encap != WTAP_ENCAP_ERF) { wth->phdr.ts.secs = hdr.hdr.ts_sec; if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) { wth->phdr.ts.nsecs = hdr.hdr.ts_usec; } else { wth->phdr.ts.nsecs = hdr.hdr.ts_usec * 1000; } } wth->phdr.caplen = packet_size; wth->phdr.len = orig_size; pcap_read_post_process(wth->file_type, wth->file_encap, &wth->pseudo_header, buffer_start_ptr(wth->frame_buffer), wth->phdr.caplen, libpcap->byte_swapped, -1); return TRUE; }
static gboolean airopeekv9_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { airopeek9_t *airopeek9 = (airopeek9_t *)wth->priv; hdr_info_t hdr_info; int hdrlen; double t; *data_offset = wth->data_offset; /* Process the packet header. */ hdrlen = airopeekv9_process_header(wth->fh, &hdr_info, err, err_info); if (hdrlen == 0) return FALSE; wth->data_offset += hdrlen; /* force sliceLength to be the actual length of the packet */ if (hdr_info.sliceLength == 0) hdr_info.sliceLength = hdr_info.length; /* fill in packet header length values before slicelength may be adjusted */ wth->phdr.len = hdr_info.length; wth->phdr.caplen = hdr_info.sliceLength; /* read the frame data */ buffer_assure_space(wth->frame_buffer, hdr_info.sliceLength); wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer), hdr_info.sliceLength, wth->fh, err); wth->data_offset += hdr_info.sliceLength; /* recalculate and fill in packet time stamp */ t = (double) hdr_info.timestamp.lower + (double) hdr_info.timestamp.upper * 4294967296.0; t *= 1.0e-9; t -= TIME_FIXUP_CONSTANT; wth->phdr.ts.secs = (time_t) t; wth->phdr.ts.nsecs = (guint32) ((t - wth->phdr.ts.secs)*1000000000); switch (wth->file_encap) { case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: /* * The last 4 bytes sometimes contains the FCS but on a lot of * interfaces these are zero. Is there some way to determine * from the packet header whether it's an FCS or not? * * For now, we just discard those bytes; if we can determine * whether it's an FCS or not, we should use that to determine * whether to supply it as an FCS or discard it. */ wth->pseudo_header.ieee_802_11 = hdr_info.ieee_802_11; if (airopeek9->has_fcs) wth->pseudo_header.ieee_802_11.fcs_len = 4; else { wth->pseudo_header.ieee_802_11.fcs_len = 0; wth->phdr.len -= 4; wth->phdr.caplen -= 4; } break; case WTAP_ENCAP_ETHERNET: /* * The last 4 bytes appear to be 0 in the captures I've seen; * are there any captures where it's an FCS? */ wth->pseudo_header.eth.fcs_len = 0; wth->phdr.len -= 4; wth->phdr.caplen -= 4; break; } 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; 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 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 (file_tell(wth->fh) != rec_offset) { if (file_seek(wth->fh, rec_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; } 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 = file_tell(wth->fh); /* * 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->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; } 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 */ 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 */ if (wth->phdr.pkt_encap == 0) goto again; netmon_set_pseudo_header_info(wth->phdr.pkt_encap, &wth->phdr.pseudo_header, data_ptr, packet_size); } else { netmon_set_pseudo_header_info(wth->file_encap, &wth->phdr.pseudo_header, data_ptr, packet_size); } return TRUE; }
static int snoop_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { struct snooprec_hdr hdr; int bytes_read; guint32 rec_size; guint32 packet_size; guint32 orig_size; int header_size; /* 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 -1; } rec_size = g_ntohl(hdr.rec_len); orig_size = g_ntohl(hdr.orig_len); packet_size = g_ntohl(hdr.incl_len); if (orig_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("snoop: File has %u-byte original length, bigger than maximum of %u", orig_size, WTAP_MAX_PACKET_SIZE); return -1; } 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("snoop: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return -1; } if (packet_size > rec_size) { /* * Probably a corrupt capture file. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("snoop: File has %u-byte packet, bigger than record size %u", packet_size, rec_size); return -1; } switch (wth->file_encap) { case WTAP_ENCAP_ATM_PDUS: /* * This is an ATM packet, so the first four bytes are * the direction of the packet (transmit/receive), the * VPI, and the VCI; read them and generate the * pseudo-header from them. */ if (packet_size < sizeof (struct snoop_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("snoop: atmsnoop file has a %u-byte packet, too small to have even an ATM pseudo-header", packet_size); return -1; } if (!snoop_read_atm_pseudoheader(fh, &phdr->pseudo_header, err, err_info)) return -1; /* Read error */ /* * Don't count the pseudo-header as part of the packet. */ rec_size -= (guint32)sizeof (struct snoop_atm_hdr); orig_size -= (guint32)sizeof (struct snoop_atm_hdr); packet_size -= (guint32)sizeof (struct snoop_atm_hdr); break; case WTAP_ENCAP_ETHERNET: /* * If this is a snoop file, we assume there's no FCS in * this frame; if this is a Shomit file, we assume there * is. (XXX - or should we treat it a "maybe"?) */ if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_SHOMITI) phdr->pseudo_header.eth.fcs_len = 4; else phdr->pseudo_header.eth.fcs_len = 0; break; case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: if (packet_size < sizeof (shomiti_wireless_header)) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("snoop: Shomiti wireless file has a %u-byte packet, too small to have even a wireless pseudo-header", packet_size); return -1; } if (!snoop_read_shomiti_wireless_pseudoheader(fh, &phdr->pseudo_header, err, err_info, &header_size)) return -1; /* Read error */ /* * Don't count the pseudo-header as part of the packet. */ rec_size -= header_size; orig_size -= header_size; packet_size -= header_size; break; } phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; phdr->ts.secs = g_ntohl(hdr.ts_sec); phdr->ts.nsecs = g_ntohl(hdr.ts_usec) * 1000; phdr->caplen = packet_size; phdr->len = orig_size; if (rec_size < (sizeof hdr + packet_size)) { /* * What, *negative* padding? Bogus. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("snoop: File has %u-byte record with packet size of %u", rec_size, packet_size); return -1; } /* * Read the packet data. */ if (!wtap_read_packet_bytes(fh, buf, packet_size, err, err_info)) return -1; /* failed */ /* * If this is ATM LANE traffic, try to guess what type of LANE * traffic it is based on the packet contents. */ if (wth->file_encap == WTAP_ENCAP_ATM_PDUS && phdr->pseudo_header.atm.type == TRAF_LANE) { atm_guess_lane_type(phdr, buffer_start_ptr(buf)); } return rec_size - ((guint)sizeof hdr + packet_size); }
static gboolean btsnoop_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { guint32 packet_size; guint32 flags; guint32 orig_size; int bytes_read; struct btsnooprec_hdr hdr; gint64 ts; /* As the send/receive flag is stored in the middle of the capture header but needs to go in the pseudo header for wiretap, the header needs to be reread in the seek_read function*/ *data_offset = wth->data_offset; /* Read record 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 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } wth->data_offset += sizeof hdr; packet_size = g_ntohl(hdr.incl_len); orig_size = g_ntohl(hdr.orig_len); flags = g_ntohl(hdr.flags); 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("btsnoop: 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); if (!snoop_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), packet_size, err, err_info)) { return FALSE; /* Read error */ } wth->data_offset += packet_size; ts = GINT64_FROM_BE(hdr.ts_usec); ts -= KUnixTimeBase; wth->phdr.ts.secs = (guint)(ts / 1000000); wth->phdr.ts.nsecs = (guint)((ts % 1000000) * 1000); wth->phdr.caplen = packet_size; wth->phdr.len = orig_size; if(wth->file_encap == WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR) { wth->pseudo_header.p2p.sent = (flags & KHciLoggerControllerToHost) ? FALSE : TRUE; } else if(wth->file_encap == WTAP_ENCAP_BLUETOOTH_HCI) { wth->pseudo_header.bthci.sent = (flags & KHciLoggerControllerToHost) ? FALSE : TRUE; if(flags & KHciLoggerCommandOrEvent) { if(wth->pseudo_header.bthci.sent) { wth->pseudo_header.bthci.channel = BTHCI_CHANNEL_COMMAND; } else { wth->pseudo_header.bthci.channel = BTHCI_CHANNEL_EVENT; } } else { wth->pseudo_header.bthci.channel = BTHCI_CHANNEL_ACL; } } return TRUE; }
/* Read the next packet */ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { struct pcaprec_ss990915_hdr hdr; guint packet_size; guint orig_size; int bytes_read; guchar fddi_padding[3]; int phdr_len; libpcap_t *libpcap; bytes_read = libpcap_read_header(wth, err, err_info, &hdr); if (bytes_read == -1) { /* * We failed to read the header. */ return FALSE; } wth->data_offset += bytes_read; packet_size = hdr.hdr.incl_len; orig_size = hdr.hdr.orig_len; /* * AIX appears to put 3 bytes of padding in front of FDDI * frames; strip that crap off. */ if (wth->file_type == WTAP_FILE_PCAP_AIX && (wth->file_encap == WTAP_ENCAP_FDDI || wth->file_encap == WTAP_ENCAP_FDDI_BITSWAPPED)) { /* * The packet size is really a record size and includes * the padding. */ packet_size -= 3; orig_size -= 3; wth->data_offset += 3; /* * Read the padding. */ if (!libpcap_read_rec_data(wth->fh, fddi_padding, 3, err)) return FALSE; /* Read error */ } *data_offset = wth->data_offset; libpcap = (libpcap_t *)wth->priv; phdr_len = pcap_process_pseudo_header(wth->fh, wth->file_type, wth->file_encap, libpcap->byte_swapped, packet_size, TRUE, &wth->phdr, &wth->pseudo_header, err, err_info); if (phdr_len < 0) return FALSE; /* error */ /* * Don't count any pseudo-header as part of the packet. */ orig_size -= phdr_len; packet_size -= phdr_len; wth->data_offset += phdr_len; buffer_assure_space(wth->frame_buffer, packet_size); if (!libpcap_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), packet_size, err)) return FALSE; /* Read error */ wth->data_offset += packet_size; /* Update the Timestamp, if not already done */ if (wth->file_encap != WTAP_ENCAP_ERF) { wth->phdr.ts.secs = hdr.hdr.ts_sec; if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) { wth->phdr.ts.nsecs = hdr.hdr.ts_usec; } else { wth->phdr.ts.nsecs = hdr.hdr.ts_usec * 1000; } } wth->phdr.caplen = packet_size; wth->phdr.len = orig_size; if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) { if (wth->file_type == WTAP_FILE_PCAP_NOKIA) { /* * Nokia IPSO ATM. * * Guess the traffic type based on the packet * contents. */ atm_guess_traffic_type(buffer_start_ptr(wth->frame_buffer), wth->phdr.caplen, &wth->pseudo_header); } else { /* * SunATM. * * If this is ATM LANE traffic, try to guess what * type of LANE traffic it is based on the packet * contents. */ if (wth->pseudo_header.atm.type == TRAF_LANE) { atm_guess_lane_type(buffer_start_ptr(wth->frame_buffer), wth->phdr.caplen, &wth->pseudo_header); } } } 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; }
/* ** 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; }
static gboolean dct3trace_get_packet(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { char line[1024]; guint8 databuf[MAX_PACKET_LEN], *bufp; gboolean have_data = FALSE; int len = 0; bufp = &databuf[0]; while (file_gets(line, sizeof(line), fh) != NULL) { if( memcmp(dct3trace_magic_end, line, strlen(dct3trace_magic_end)) == 0 ) { /* Return on end of file </dump> */ *err = 0; return FALSE; } else if( memcmp(dct3trace_magic_record_end, line, strlen(dct3trace_magic_record_end)) == 0 ) { /* Return on end of record </l1> */ if( have_data ) { /* We've got a full packet! */ phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = 0; /* no time stamp, no separate "on the wire" length */ phdr->ts.secs = 0; phdr->ts.nsecs = 0; phdr->caplen = len; phdr->len = len; *err = 0; /* Make sure we have enough room for the packet */ buffer_assure_space(buf, phdr->caplen); memcpy( buffer_start_ptr(buf), databuf, phdr->caplen ); return TRUE; } else { /* If not got any data return error */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("dct3trace: record without data"); return FALSE; } } else if( memcmp(dct3trace_magic_record_start, line, strlen(dct3trace_magic_record_start)) == 0 ) { /* Parse L1 header <l1 ...>*/ int channel, tmp; char *ptr; phdr->pseudo_header.gsm_um.uplink = !strstr(line, "direction=\"down\""); if (xml_get_int(&channel, line, "logicalchannel") != 0) goto baddata; /* Parse downlink only fields */ if( !phdr->pseudo_header.gsm_um.uplink ) { if (xml_get_int(&tmp, line, "physicalchannel") != 0) goto baddata; phdr->pseudo_header.gsm_um.arfcn = tmp; if (xml_get_int(&tmp, line, "sequence") != 0) goto baddata; phdr->pseudo_header.gsm_um.tdma_frame = tmp; if (xml_get_int(&tmp, line, "bsic") != 0) goto baddata; phdr->pseudo_header.gsm_um.bsic = tmp; if (xml_get_int(&tmp, line, "error") != 0) goto baddata; phdr->pseudo_header.gsm_um.error = tmp; if (xml_get_int(&tmp, line, "timeshift") != 0) goto baddata; phdr->pseudo_header.gsm_um.timeshift = tmp; } switch( channel ) { case 128: phdr->pseudo_header.gsm_um.channel = GSM_UM_CHANNEL_SDCCH; break; case 112: phdr->pseudo_header.gsm_um.channel = GSM_UM_CHANNEL_SACCH; break; case 176: phdr->pseudo_header.gsm_um.channel = GSM_UM_CHANNEL_FACCH; break; case 96: phdr->pseudo_header.gsm_um.channel = GSM_UM_CHANNEL_CCCH; break; case 80: phdr->pseudo_header.gsm_um.channel = GSM_UM_CHANNEL_BCCH; break; default: phdr->pseudo_header.gsm_um.channel = GSM_UM_CHANNEL_UNKNOWN; break; } /* Read data (if have it) into databuf */ ptr = strstr(line, "data=\""); if( ptr ) { have_data = TRUE; /* If has data... */ len = hex2bin(bufp, &databuf[MAX_PACKET_LEN], ptr+6); if (len == -1) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("dct3trace: record length %d too long", phdr->caplen); return FALSE; } } } else if( !have_data && memcmp(dct3trace_magic_l2_start, line, strlen(dct3trace_magic_l2_start)) == 0 ) { /* For uplink packets we might not get the raw L1, so have to recreate it from the L2 */ /* Parse L2 header if didn't get data from L1 <l2 ...> */ int data_len; char *ptr = strstr(line, "data=\""); if( !ptr ) { continue; } have_data = TRUE; /* * We know we have no data already, so we know * we have enough room for the header. */ if( phdr->pseudo_header.gsm_um.channel == GSM_UM_CHANNEL_SACCH || phdr->pseudo_header.gsm_um.channel == GSM_UM_CHANNEL_FACCH || phdr->pseudo_header.gsm_um.channel == GSM_UM_CHANNEL_SDCCH ) { /* Add LAPDm B header */ memset(bufp, 0x1, 2); len = 3; } else { /* Add LAPDm Bbis header */ len = 1; } bufp += len; data_len = hex2bin(bufp, &databuf[MAX_PACKET_LEN], ptr+6); if (data_len == -1) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("dct3trace: record length %d too long", phdr->caplen); return FALSE; } len += data_len; /* Add LAPDm length byte */ *(bufp - 1) = data_len << 2 | 0x1; } } *err = file_error(fh, err_info); if (*err == 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; baddata: *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("dct3trace: record missing mandatory attributes"); return FALSE; }
static gboolean etherpeek_read_v56(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { etherpeek_t *etherpeek = (etherpeek_t *)wth->priv; guint8 ep_pkt[ETHERPEEK_V56_PKT_SIZE]; guint16 length; guint16 sliceLength; #if 0 guint8 flags; guint8 status; #endif guint32 timestamp; #if 0 guint16 destNum; guint16 srcNum; #endif guint16 protoNum; char protoStr[8]; unsigned int i; /* * XXX - in order to figure out whether this packet is an * Ethernet packet or not, we have to look at the packet * header, so we have to remember the address of the header, * not the address of the data, for random access. * * If we can determine that from the file header, rather than * the packet header, we can remember the offset of the data, * and not have the seek_read routine read the header. */ *data_offset = file_tell(wth->fh); wtap_file_read_expected_bytes(ep_pkt, sizeof(ep_pkt), wth->fh, err, err_info); /* Extract the fields from the packet */ length = pntohs(&ep_pkt[ETHERPEEK_V56_LENGTH_OFFSET]); sliceLength = pntohs(&ep_pkt[ETHERPEEK_V56_SLICE_LENGTH_OFFSET]); #if 0 flags = ep_pkt[ETHERPEEK_V56_FLAGS_OFFSET]; status = ep_pkt[ETHERPEEK_V56_STATUS_OFFSET]; #endif timestamp = pntohl(&ep_pkt[ETHERPEEK_V56_TIMESTAMP_OFFSET]); #if 0 destNum = pntohs(&ep_pkt[ETHERPEEK_V56_DESTNUM_OFFSET]); srcNum = pntohs(&ep_pkt[ETHERPEEK_V56_SRCNUM_OFFSET]); #endif protoNum = pntohs(&ep_pkt[ETHERPEEK_V56_PROTONUM_OFFSET]); memcpy(protoStr, &ep_pkt[ETHERPEEK_V56_PROTOSTR_OFFSET], sizeof protoStr); /* * XXX - is the captured packet data padded to a multiple * of 2 bytes? */ /* force sliceLength to be the actual length of the packet */ if (0 == sliceLength) { sliceLength = length; } /* read the frame data */ buffer_assure_space(wth->frame_buffer, sliceLength); wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer), sliceLength, wth->fh, err, err_info); /* fill in packet header values */ wth->phdr.len = length; wth->phdr.caplen = sliceLength; /* timestamp is in milliseconds since reference_time */ wth->phdr.ts.secs = etherpeek->reference_time.tv_sec + (timestamp / 1000); wth->phdr.ts.nsecs = 1000 * (timestamp % 1000) * 1000; wth->phdr.pkt_encap = WTAP_ENCAP_UNKNOWN; for (i=0; i<NUM_ETHERPEEK_ENCAPS; i++) { if (etherpeek_encap[i].protoNum == protoNum) { wth->phdr.pkt_encap = etherpeek_encap[i].encap; } } switch (wth->phdr.pkt_encap) { case WTAP_ENCAP_ETHERNET: /* We assume there's no FCS in this frame. */ wth->pseudo_header.eth.fcs_len = 0; break; } return TRUE; }
static gboolean nettl_read_rec(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header; nettl_t *nettl = (nettl_t *)wth->priv; gboolean fddihack = FALSE; int bytes_read; struct nettlrec_hdr rec_hdr; guint16 hdr_len; struct nettlrec_ns_ls_drv_eth_hdr drv_eth_hdr; guint32 length, caplen; int subsys; guint padlen; int datalen; guint8 dummyc[16]; int bytes_to_read; guint8 *pd; guint8 dummy[3]; errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&rec_hdr.hdr_len, sizeof rec_hdr.hdr_len, fh); if (bytes_read != sizeof rec_hdr.hdr_len) { *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } hdr_len = g_ntohs(rec_hdr.hdr_len); if (hdr_len < NETTL_REC_HDR_LEN) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("nettl: record header length %u too short", hdr_len); return FALSE; } bytes_read = file_read(&rec_hdr.subsys, NETTL_REC_HDR_LEN - 2, fh); if (bytes_read != NETTL_REC_HDR_LEN - 2) { *err = file_error(fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } subsys = g_ntohs(rec_hdr.subsys); hdr_len -= NETTL_REC_HDR_LEN; if (file_seek(fh, hdr_len, SEEK_CUR, err) == -1) return FALSE; if ( (pntoh32(&rec_hdr.kind) & NETTL_HDR_PDU_MASK) == 0 ) { /* not actually a data packet (PDU) trace record */ phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_IP; length = pntoh32(&rec_hdr.length); caplen = pntoh32(&rec_hdr.caplen); padlen = 0; } else switch (subsys) { case NETTL_SUBSYS_LAN100 : case NETTL_SUBSYS_EISA100BT : case NETTL_SUBSYS_BASE100 : case NETTL_SUBSYS_GSC100BT : case NETTL_SUBSYS_PCI100BT : case NETTL_SUBSYS_SPP100BT : case NETTL_SUBSYS_100VG : case NETTL_SUBSYS_GELAN : case NETTL_SUBSYS_BTLAN : case NETTL_SUBSYS_INTL100 : case NETTL_SUBSYS_IGELAN : case NETTL_SUBSYS_IETHER : case NETTL_SUBSYS_IXGBE : case NETTL_SUBSYS_HSSN : case NETTL_SUBSYS_IGSSN : case NETTL_SUBSYS_ICXGBE : case NETTL_SUBSYS_IEXGBE : case NETTL_SUBSYS_IOCXGBE : case NETTL_SUBSYS_IQXGBE : case NETTL_SUBSYS_HPPB_FDDI : case NETTL_SUBSYS_EISA_FDDI : case NETTL_SUBSYS_PCI_FDDI : case NETTL_SUBSYS_HSC_FDDI : case NETTL_SUBSYS_TOKEN : case NETTL_SUBSYS_PCI_TR : case NETTL_SUBSYS_NS_LS_IP : case NETTL_SUBSYS_NS_LS_LOOPBACK : case NETTL_SUBSYS_NS_LS_TCP : case NETTL_SUBSYS_NS_LS_UDP : case NETTL_SUBSYS_HP_APAPORT : case NETTL_SUBSYS_HP_APALACP : case NETTL_SUBSYS_NS_LS_IPV6 : case NETTL_SUBSYS_NS_LS_ICMPV6 : case NETTL_SUBSYS_NS_LS_ICMP : case NETTL_SUBSYS_NS_LS_TELNET : case NETTL_SUBSYS_NS_LS_SCTP : if( (subsys == NETTL_SUBSYS_NS_LS_IP) || (subsys == NETTL_SUBSYS_NS_LS_LOOPBACK) || (subsys == NETTL_SUBSYS_NS_LS_UDP) || (subsys == NETTL_SUBSYS_NS_LS_TCP) || (subsys == NETTL_SUBSYS_NS_LS_SCTP) || (subsys == NETTL_SUBSYS_NS_LS_IPV6)) { phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_IP; } else if (subsys == NETTL_SUBSYS_NS_LS_ICMP) { phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMP; } else if (subsys == NETTL_SUBSYS_NS_LS_ICMPV6) { phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMPV6; } else if (subsys == NETTL_SUBSYS_NS_LS_TELNET) { phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_TELNET; } else if( (subsys == NETTL_SUBSYS_HPPB_FDDI) || (subsys == NETTL_SUBSYS_EISA_FDDI) || (subsys == NETTL_SUBSYS_PCI_FDDI) || (subsys == NETTL_SUBSYS_HSC_FDDI) ) { phdr->pkt_encap = WTAP_ENCAP_NETTL_FDDI; } else if( (subsys == NETTL_SUBSYS_PCI_TR) || (subsys == NETTL_SUBSYS_TOKEN) ) { phdr->pkt_encap = WTAP_ENCAP_NETTL_TOKEN_RING; } else { phdr->pkt_encap = WTAP_ENCAP_NETTL_ETHERNET; } length = pntoh32(&rec_hdr.length); caplen = pntoh32(&rec_hdr.caplen); /* HPPB FDDI has different inbound vs outbound trace records */ if (subsys == NETTL_SUBSYS_HPPB_FDDI) { if (pntoh32(&rec_hdr.kind) == NETTL_HDR_PDUIN) { /* inbound is very strange... there are an extra 3 bytes after the DSAP and SSAP for SNAP frames ??? */ fddihack=TRUE; padlen = 0; } else { /* outbound appears to have variable padding */ bytes_read = file_read(dummyc, 9, fh); if (bytes_read != 9) { *err = file_error(fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } /* padding is usually either a total 11 or 16 bytes??? */ padlen = (int)dummyc[8]; if (file_seek(fh, padlen, SEEK_CUR, err) == -1) return FALSE; padlen += 9; } } else if ( (subsys == NETTL_SUBSYS_PCI_FDDI) || (subsys == NETTL_SUBSYS_EISA_FDDI) || (subsys == NETTL_SUBSYS_HSC_FDDI) ) { /* other flavor FDDI cards have an extra 3 bytes of padding */ if (file_seek(fh, 3, SEEK_CUR, err) == -1) return FALSE; padlen = 3; } else if (subsys == NETTL_SUBSYS_NS_LS_LOOPBACK) { /* LOOPBACK has an extra 26 bytes of padding */ if (file_seek(fh, 26, SEEK_CUR, err) == -1) return FALSE; padlen = 26; } else if (subsys == NETTL_SUBSYS_NS_LS_SCTP) { /* * SCTP 8 byte header that we will ignore... * 32 bit integer defines format * 1 = Log * 2 = ASCII * 3 = Binary (PDUs should be Binary format) * 32 bit integer defines type * 1 = Inbound * 2 = Outbound */ if (file_seek(fh, 8, SEEK_CUR, err) == -1) return FALSE; padlen = 8; } else { padlen = 0; } break; case NETTL_SUBSYS_NS_LS_DRIVER : /* XXX we dont know how to identify this as ethernet frames, so we assumes everything is. We will crash and burn for anything else */ /* for encapsulated 100baseT we do this */ phdr->pkt_encap = WTAP_ENCAP_NETTL_ETHERNET; bytes_read = file_read(&drv_eth_hdr, NS_LS_DRV_ETH_HDR_LEN, fh); if (bytes_read != NS_LS_DRV_ETH_HDR_LEN) { *err = file_error(fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } length = pntoh16(&drv_eth_hdr.length); caplen = pntoh16(&drv_eth_hdr.caplen); /* * XXX - is there a length field that would give the length * of this header, so that we don't have to check for * nettl files from HP-UX 11? * * And what are the extra two bytes? */ if (nettl->is_hpux_11) { if (file_seek(fh, 2, SEEK_CUR, err) == -1) return FALSE; } padlen = 0; break; case NETTL_SUBSYS_SX25L2: case NETTL_SUBSYS_SX25L3: /* * XXX - is the 24-byte padding actually a header with * packet lengths, time stamps, etc., just as is the case * for NETTL_SUBSYS_NS_LS_DRIVER? It might be * * guint8 caplen[2]; * guint8 length[2]; * guint8 xxc[4]; * guint8 sec[4]; * guint8 usec[4]; * guint8 xxd[4]; * * or something such as that - if it has 4 bytes before that * (making it 24 bytes), it'd be like struct * nettlrec_ns_ls_drv_eth_hdr but with 2 more bytes at the end. * * And is "from_dce" at xxa[0] in the nettlrec_hdr structure? */ phdr->pkt_encap = WTAP_ENCAP_NETTL_X25; length = pntoh32(&rec_hdr.length); caplen = pntoh32(&rec_hdr.caplen); padlen = 24; /* sizeof (struct nettlrec_sx25l2_hdr) - NETTL_REC_HDR_LEN + 4 */ if (file_seek(fh, padlen, SEEK_CUR, err) == -1) return FALSE; break; default: /* We're going to assume it's ethernet if we don't recognize the subsystem -- We'll probably spew junks and core if it isn't... */ wth->file_encap = WTAP_ENCAP_PER_PACKET; phdr->pkt_encap = WTAP_ENCAP_NETTL_ETHERNET; length = pntoh32(&rec_hdr.length); caplen = pntoh32(&rec_hdr.caplen); padlen = 0; break; } if (length < padlen) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("nettl: packet length %u in record header too short, less than %u", length, padlen); return FALSE; } phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; phdr->len = length - padlen; if (caplen < padlen) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("nettl: captured length %u in record header too short, less than %u", caplen, padlen); return FALSE; } datalen = caplen - padlen; phdr->caplen = datalen; phdr->ts.secs = pntoh32(&rec_hdr.sec); phdr->ts.nsecs = pntoh32(&rec_hdr.usec) * 1000; pseudo_header->nettl.subsys = subsys; pseudo_header->nettl.devid = pntoh32(&rec_hdr.devid); pseudo_header->nettl.kind = pntoh32(&rec_hdr.kind); pseudo_header->nettl.pid = pntoh32(&rec_hdr.pid); pseudo_header->nettl.uid = pntoh16(&rec_hdr.uid); if (phdr->caplen > 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("nettl: File has %u-byte packet, bigger than maximum of %u", phdr->caplen, WTAP_MAX_PACKET_SIZE); return FALSE; } /* * Read the packet data. */ buffer_assure_space(buf, datalen); pd = buffer_start_ptr(buf); errno = WTAP_ERR_CANT_READ; if (fddihack) { /* read in FC, dest, src, DSAP and SSAP */ bytes_to_read = 15; if (bytes_to_read > datalen) bytes_to_read = datalen; bytes_read = file_read(pd, bytes_to_read, fh); if (bytes_read != bytes_to_read) { if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } datalen -= bytes_read; if (datalen == 0) { /* There's nothing past the FC, dest, src, DSAP and SSAP */ return TRUE; } if (pd[13] == 0xAA) { /* it's SNAP, have to eat 3 bytes??? */ bytes_to_read = 3; if (bytes_to_read > datalen) bytes_to_read = datalen; bytes_read = file_read(dummy, bytes_to_read, fh); if (bytes_read != bytes_to_read) { if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } datalen -= bytes_read; if (datalen == 0) { /* There's nothing past the FC, dest, src, DSAP, SSAP, and 3 bytes to eat */ return TRUE; } } bytes_read = file_read(pd + 15, datalen, fh); } else bytes_read = file_read(pd, datalen, fh); if (bytes_read != datalen) { *err = file_error(fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } return TRUE; }
/* Convert packet data from ASCII hex string to binary in place, * sanity-check its length against what we assume is the packet length field, * and copy it into a Buffer */ static gboolean daintree_sna_process_hex_data(struct wtap_pkthdr *phdr, Buffer *buf, char *readData, int *err, gchar **err_info) { guchar *str = (guchar *)readData; guint bytes; guint8 *p; p = str; /* overlay source buffer */ bytes = 0; /* convert hex string to guint8 */ while(*str) { /* most significant nibble */ if (!isxdigit((guchar)*str)) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("daintree_sna: non-hex digit in hex data"); return FALSE; } if(isdigit((guchar)*str)) { *p = (*str - '0') << 4; } else { *p = ((tolower(*str) - 'a') + 10) << 4; } str++; /* least significant nibble */ if (!isxdigit((guchar)*str)) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("daintree_sna: non-hex digit in hex data"); return FALSE; } if(isdigit((guchar)*str)) { *p += *str - '0'; } else { *p += (tolower(*str) - 'a') + 10; } str++; /* next byte in buffer */ p++; bytes++; } /* Daintree doesn't store the FCS, but pads end of packet with 0xffff, which we toss */ if (bytes <= FCS_LENGTH) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("daintree_sna: Only %u bytes of packet data", bytes); return FALSE; } bytes -= FCS_LENGTH; if (bytes > phdr->len) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("daintree_sna: capture length (%u) > packet length (%u)", bytes, phdr->len); return FALSE; } phdr->caplen = bytes; buffer_assure_space(buf, bytes); memcpy(buffer_start_ptr(buf), readData, bytes); return TRUE; }
/* Read the next packet */ static gboolean iptrace_read_2_0(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { int ret; guint32 packet_size; guint8 header[IPTRACE_2_0_PHDR_SIZE]; guint8 *data_ptr; iptrace_2_0_phdr pkt_hdr; guint8 fddi_padding[3]; /* Read the descriptor data */ *data_offset = wth->data_offset; ret = iptrace_read_rec_header(wth->fh, header, IPTRACE_2_0_PHDR_SIZE, err, err_info); if (ret <= 0) { /* Read error or EOF */ return FALSE; } wth->data_offset += IPTRACE_2_0_PHDR_SIZE; /* * Byte 28 of the frame header appears to be a BSD-style IFT_xxx * value giving the type of the interface. Check out the * <net/if_types.h> header file. */ pkt_hdr.if_type = header[28]; wth->phdr.pkt_encap = wtap_encap_ift(pkt_hdr.if_type); /* Read the packet data */ packet_size = pntohl(&header[0]); if (packet_size < IPTRACE_2_0_PDATA_SIZE) { /* * Uh-oh, the record isn't big enough to even have a * packet meta-data header. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header", packet_size); return FALSE; } packet_size -= IPTRACE_2_0_PDATA_SIZE; /* * AIX appears to put 3 bytes of padding in front of FDDI * frames; strip that crap off. */ if (wth->phdr.pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) { /* * The packet size is really a record size and includes * the padding. */ if (packet_size < 3) { /* * Uh-oh, the record isn't big enough to even have * the padding. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header", packet_size + IPTRACE_2_0_PDATA_SIZE); return FALSE; } packet_size -= 3; wth->data_offset += 3; /* * Read the padding. */ if (!iptrace_read_rec_data(wth->fh, fddi_padding, 3, err, err_info)) return FALSE; /* Read error */ } 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("iptrace: 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_ptr = buffer_start_ptr( wth->frame_buffer ); if (!iptrace_read_rec_data(wth->fh, data_ptr, packet_size, err, err_info)) return FALSE; /* Read error */ wth->data_offset += packet_size; wth->phdr.presence_flags = WTAP_HAS_TS; wth->phdr.len = packet_size; wth->phdr.caplen = packet_size; wth->phdr.ts.secs = pntohl(&header[32]); wth->phdr.ts.nsecs = pntohl(&header[36]); if (wth->phdr.pkt_encap == WTAP_ENCAP_UNKNOWN) { *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported", pkt_hdr.if_type); return FALSE; } /* Fill in the pseudo-header. */ fill_in_pseudo_header(wth->phdr.pkt_encap, data_ptr, wth->phdr.caplen, &wth->pseudo_header, header); /* If the per-file encapsulation isn't known, set it to this packet's encapsulation. If it *is* known, and it isn't this packet's encapsulation, set it to WTAP_ENCAP_PER_PACKET, as this file doesn't have a single encapsulation for all packets in the file. */ if (wth->file_encap == WTAP_ENCAP_UNKNOWN) wth->file_encap = wth->phdr.pkt_encap; else { if (wth->file_encap != wth->phdr.pkt_encap) wth->file_encap = WTAP_ENCAP_PER_PACKET; } 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->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; }
/* 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; }
/* reads the next packet */ static gboolean observer_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { int offset; packet_entry_header packet_header; /* * Skip records other than data records. */ for (;;) { *data_offset = wth->data_offset; /* process the packet header, including TLVs */ offset = read_packet_header(wth->fh, &packet_header, err, err_info); if (offset <= 0) return FALSE; /* EOF or error */ wth->data_offset += offset; if (packet_header.packet_type == PACKET_TYPE_DATA_PACKET) break; /* skip to next packet */ packet_header.offset_to_next_packet = GUINT16_FROM_LE(packet_header.offset_to_next_packet); if (!skip_to_next_packet(wth, offset, packet_header.offset_to_next_packet, err, err_info)) return FALSE; /* EOF or error */ } /* set-up the packet header */ packet_header.network_size = GUINT16_FROM_LE(packet_header.network_size); /* neglect frame markers for wiretap */ if (packet_header.network_size < 4) { *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup_printf("Observer: bad record: Packet length %u < 4", packet_header.network_size); return FALSE; } packet_header.network_size -= 4; packet_header.captured_size = GUINT16_FROM_LE(packet_header.captured_size); wth->phdr.pkt_encap = observer_encap[packet_header.network_type]; wth->phdr.len = packet_header.network_size; wth->phdr.caplen = MIN(packet_header.captured_size, wth->phdr.len); packet_header.nano_seconds_since_2000 = GUINT64_FROM_LE(packet_header.nano_seconds_since_2000); wth->phdr.ts.secs = (time_t) (packet_header.nano_seconds_since_2000/1000000000 + seconds1970to2000); wth->phdr.ts.nsecs = (int) (packet_header.nano_seconds_since_2000%1000000000); /* set-up the packet buffer */ buffer_assure_space(wth->frame_buffer, packet_header.captured_size); /* read data */ if (!read_packet_data(wth->fh, packet_header.offset_to_frame, offset, buffer_start_ptr(wth->frame_buffer), packet_header.captured_size, err, err_info)) return FALSE; wth->data_offset += packet_header.captured_size; offset += packet_header.captured_size; /* update the pseudo header */ switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* There is no FCS in the frame */ wth->pseudo_header.eth.fcs_len = 0; break; } return TRUE; }
/* Read the next packet */ static gboolean lanalyzer_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { int packet_size = 0; int bytes_read; char LE_record_type[2]; char LE_record_length[2]; guint16 record_type, record_length; gchar descriptor[DESCRIPTOR_LEN]; guint16 time_low, time_med, time_high, true_size; guint64 t; time_t tsecs; lanalyzer_t *lanalyzer; /* read the record type and length. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(LE_record_type, 2, wth->fh); if (bytes_read != 2) { *err = file_error(wth->fh, err_info); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } bytes_read = file_read(LE_record_length, 2, wth->fh); if (bytes_read != 2) { *err = file_error(wth->fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } record_type = pletohs(LE_record_type); record_length = pletohs(LE_record_length); /* Only Trace Packet Data Records should occur now that we're in * the middle of reading packets. If any other record type exists * after a Trace Packet Data Record, mark it as an error. */ if (record_type != RT_PacketData) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("lanalyzer: record type %u seen after trace summary record", record_type); return FALSE; } else { if (record_length < DESCRIPTOR_LEN) { /* * Uh-oh, the record isn't big enough to even have a * descriptor. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("lanalyzer: file has a %u-byte record, too small to have even a packet descriptor", record_length); return FALSE; } packet_size = record_length - DESCRIPTOR_LEN; } /* Read the descriptor data */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(descriptor, DESCRIPTOR_LEN, wth->fh); if (bytes_read != DESCRIPTOR_LEN) { *err = file_error(wth->fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } /* Read the packet data */ 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 != packet_size) { *err = file_error(wth->fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } true_size = pletohs(&descriptor[4]); packet_size = pletohs(&descriptor[6]); /* * OK, is the frame data size greater than than what's left of the * record? */ if (packet_size > record_length - DESCRIPTOR_LEN) { /* * Yes - treat this as an error. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("lanalyzer: Record length is less than packet size"); return FALSE; } wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; time_low = pletohs(&descriptor[8]); time_med = pletohs(&descriptor[10]); time_high = pletohs(&descriptor[12]); t = (((guint64)time_low) << 0) + (((guint64)time_med) << 16) + (((guint64)time_high) << 32); tsecs = (time_t) (t/2000000); lanalyzer = (lanalyzer_t *)wth->priv; wth->phdr.ts.secs = tsecs + lanalyzer->start; wth->phdr.ts.nsecs = ((guint32) (t - tsecs*2000000)) * 500; if (true_size - 4 >= packet_size) { /* * It appears that the "true size" includes the FCS; * make it reflect the non-FCS size (the "packet size" * appears never to include the FCS, even if no slicing * is done). */ true_size -= 4; } wth->phdr.len = true_size; wth->phdr.caplen = packet_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 gboolean commview_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { commview_header_t cv_hdr; struct tm tm; int bytes_read; *data_offset = wth->data_offset; if(!commview_read_header(&cv_hdr, wth->fh, err, err_info)) return FALSE; wth->data_offset += COMMVIEW_HEADER_SIZE; switch(cv_hdr.flags & FLAGS_MEDIUM) { case MEDIUM_ETHERNET : wth->phdr.pkt_encap = WTAP_ENCAP_ETHERNET; break; case MEDIUM_WIFI : wth->phdr.pkt_encap = WTAP_ENCAP_IEEE_802_11_WITH_RADIO; break; case MEDIUM_TOKEN_RING : wth->phdr.pkt_encap = WTAP_ENCAP_TOKEN_RING; break; default : *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("commview: unsupported encap: %u", cv_hdr.flags & FLAGS_MEDIUM); return FALSE; } commview_set_pseudo_header(&cv_hdr, &wth->pseudo_header); buffer_assure_space(wth->frame_buffer, cv_hdr.data_len); bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), cv_hdr.data_len, wth->fh); if(bytes_read != cv_hdr.data_len) { *err = file_error(wth->fh, err_info); if(*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } tm.tm_year = cv_hdr.year - 1900; tm.tm_mon = cv_hdr.month - 1; tm.tm_mday = cv_hdr.day; tm.tm_hour = cv_hdr.hours; tm.tm_min = cv_hdr.minutes; tm.tm_sec = cv_hdr.seconds; tm.tm_isdst = -1; wth->data_offset += cv_hdr.data_len; wth->phdr.presence_flags = WTAP_HAS_TS; wth->phdr.len = cv_hdr.data_len; wth->phdr.caplen = cv_hdr.data_len; wth->phdr.ts.secs = mktime(&tm); wth->phdr.ts.nsecs = cv_hdr.usecs * 1000; return TRUE; }
/* Read the next packet */ static gboolean snoop_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { guint32 rec_size; guint32 packet_size; guint32 orig_size; int bytes_read; struct snooprec_hdr hdr; char padbuf[4]; guint padbytes; int bytes_to_read; int header_size; /* Read record 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 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } rec_size = g_ntohl(hdr.rec_len); orig_size = g_ntohl(hdr.orig_len); packet_size = g_ntohl(hdr.incl_len); if (orig_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("snoop: File has %u-byte original length, bigger than maximum of %u", orig_size, WTAP_MAX_PACKET_SIZE); return FALSE; } 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("snoop: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return FALSE; } if (packet_size > rec_size) { /* * Probably a corrupt capture file. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("snoop: File has %u-byte packet, bigger than record size %u", packet_size, rec_size); return FALSE; } *data_offset = file_tell(wth->fh); /* * If this is an ATM packet, the first four bytes are the * direction of the packet (transmit/receive), the VPI, and * the VCI; read them and generate the pseudo-header from * them. */ switch (wth->file_encap) { case WTAP_ENCAP_ATM_PDUS: if (packet_size < sizeof (struct snoop_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("snoop: atmsnoop file has a %u-byte packet, too small to have even an ATM pseudo-header", packet_size); return FALSE; } if (!snoop_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. */ rec_size -= (guint32)sizeof (struct snoop_atm_hdr); orig_size -= (guint32)sizeof (struct snoop_atm_hdr); packet_size -= (guint32)sizeof (struct snoop_atm_hdr); break; case WTAP_ENCAP_ETHERNET: /* * If this is a snoop file, we assume there's no FCS in * this frame; if this is a Shomit file, we assume there * is. (XXX - or should we treat it a "maybe"?) */ if (wth->file_type == WTAP_FILE_SHOMITI) wth->pseudo_header.eth.fcs_len = 4; else wth->pseudo_header.eth.fcs_len = 0; break; case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: if (packet_size < sizeof (shomiti_wireless_header)) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("snoop: Shomiti wireless file has a %u-byte packet, too small to have even a wireless pseudo-header", packet_size); return FALSE; } if (!snoop_read_shomiti_wireless_pseudoheader(wth->fh, &wth->pseudo_header, err, err_info, &header_size)) return FALSE; /* Read error */ /* * Don't count the pseudo-header as part of the packet. */ rec_size -= header_size; orig_size -= header_size; packet_size -= header_size; break; } buffer_assure_space(wth->frame_buffer, packet_size); if (!snoop_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), packet_size, err, err_info)) return FALSE; /* Read error */ wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; wth->phdr.ts.secs = g_ntohl(hdr.ts_sec); wth->phdr.ts.nsecs = g_ntohl(hdr.ts_usec) * 1000; wth->phdr.caplen = packet_size; wth->phdr.len = orig_size; /* * If this is ATM LANE traffic, try to guess what type of LANE * traffic it is based on the packet contents. */ if (wth->file_encap == WTAP_ENCAP_ATM_PDUS && wth->pseudo_header.atm.type == TRAF_LANE) { atm_guess_lane_type(buffer_start_ptr(wth->frame_buffer), wth->phdr.caplen, &wth->pseudo_header); } /* * Skip over the padding (don't "fseek()", as the standard * I/O library on some platforms discards buffered data if * you do that, which means it does a lot more reads). * There's probably not much padding (it's probably padded only * to a 4-byte boundary), so we probably need only do one read. */ if (rec_size < (sizeof hdr + packet_size)) { /* * What, *negative* padding? Bogus. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("snoop: File has %u-byte record with packet size of %u", rec_size, packet_size); return FALSE; } padbytes = rec_size - ((guint)sizeof hdr + packet_size); while (padbytes != 0) { bytes_to_read = padbytes; if ((unsigned)bytes_to_read > sizeof padbuf) bytes_to_read = sizeof padbuf; errno = WTAP_ERR_CANT_READ; bytes_read = file_read(padbuf, bytes_to_read, wth->fh); if (bytes_read != bytes_to_read) { *err = file_error(wth->fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } padbytes -= bytes_read; } return TRUE; }
/* Parses a packet. */ static gboolean iseries_parse_packet (wtap * wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { iseries_t *iseries = (iseries_t *)wth->priv; gint64 cur_off; gboolean isValid, isCurrentPacket; int num_items_scanned, line, pktline, buflen; int pkt_len, pktnum, hr, min, sec; char direction[2], destmac[13], srcmac[13], type[5], csec[9+1]; char data[ISERIES_LINE_LENGTH * 2]; int offset; char *ascii_buf; int ascii_offset; struct tm tm; /* * Check for packet headers in first 3 lines this should handle page breaks * situations and the header lines output at each page throw and ensure we * read both the captured and packet lengths. */ isValid = FALSE; for (line = 1; line < ISERIES_PKT_LINES_TO_CHECK; line++) { if (file_gets (data, ISERIES_LINE_LENGTH, fh) == NULL) { *err = file_error (fh, err_info); return FALSE; } /* Convert UNICODE data to ASCII */ if (iseries->format == ISERIES_FORMAT_UNICODE) { iseries_UNICODE_to_ASCII ((guint8 *)data, ISERIES_LINE_LENGTH); } ascii_strup_inplace (data); num_items_scanned = sscanf (data, "%*[ \n\t]%6d%*[ *\n\t]%1s%*[ \n\t]%6d%*[ \n\t]%2d:%2d:%2d.%9[0-9]%*[ \n\t]" "%12s%*[ \n\t]%12s%*[ \n\t]ETHV2%*[ \n\t]TYPE:%*[ \n\t]%4s", &pktnum, direction, &pkt_len, &hr, &min, &sec, csec, destmac, srcmac, type); if (num_items_scanned == 10) { /* OK! We found the packet header line */ isValid = TRUE; /* * XXX - The Capture length returned by the iSeries trace doesn't * seem to include the Ethernet header, so we add its length here. */ pkt_len += 14; break; } } /* * If no packet header found we exit at this point and inform the user. */ if (!isValid) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup ("iseries: packet header isn't valid"); return FALSE; } phdr->presence_flags = WTAP_HAS_CAP_LEN; /* * If we have Wiretap Header then populate it here * * Timer resolution on the iSeries is hardware dependent. We determine * the resolution based on how many digits we see. */ if (iseries->have_date) { phdr->presence_flags |= WTAP_HAS_TS; tm.tm_year = 100 + iseries->year; tm.tm_mon = iseries->month - 1; tm.tm_mday = iseries->day; tm.tm_hour = hr; tm.tm_min = min; tm.tm_sec = sec; tm.tm_isdst = -1; phdr->ts.secs = mktime (&tm); csec[sizeof(csec) - 1] = '\0'; switch (strlen(csec)) { case 0: phdr->ts.nsecs = 0; break; case 1: phdr->ts.nsecs = atoi(csec) * 100000000; break; case 2: phdr->ts.nsecs = atoi(csec) * 10000000; break; case 3: phdr->ts.nsecs = atoi(csec) * 1000000; break; case 4: phdr->ts.nsecs = atoi(csec) * 100000; break; case 5: phdr->ts.nsecs = atoi(csec) * 10000; break; case 6: phdr->ts.nsecs = atoi(csec) * 1000; break; case 7: phdr->ts.nsecs = atoi(csec) * 100; break; case 8: phdr->ts.nsecs = atoi(csec) * 10; break; case 9: phdr->ts.nsecs = atoi(csec); break; } } phdr->len = pkt_len; phdr->pkt_encap = WTAP_ENCAP_ETHERNET; phdr->pseudo_header.eth.fcs_len = -1; ascii_buf = (char *)g_malloc (ISERIES_PKT_ALLOC_SIZE); g_snprintf(ascii_buf, ISERIES_PKT_ALLOC_SIZE, "%s%s%s", destmac, srcmac, type); ascii_offset = 14*2; /* 14-byte Ethernet header, 2 characters per byte */ /* * Start reading packet contents */ isCurrentPacket = TRUE; /* loop through packet lines and breakout when the next packet header is read */ pktline = 0; while (isCurrentPacket) { pktline++; /* Read the next line */ if (file_gets (data, ISERIES_LINE_LENGTH, fh) == NULL) { *err = file_error (fh, err_info); if (*err == 0) { /* Hit the EOF without an error */ break; } goto errxit; } /* Convert UNICODE data to ASCII and determine line length */ if (iseries->format == ISERIES_FORMAT_UNICODE) { buflen = iseries_UNICODE_to_ASCII ((guint8 *)data, ISERIES_LINE_LENGTH); } else { /* Else bytes to rewind is just length of ASCII string */ buflen = (int) strlen (data); } /* * Skip leading white space. */ for (offset = 0; isspace(data[offset]); offset++) ; /* * The higher-level header information starts at an offset of * 22 characters. The header tags are 14 characters long. * * XXX - for IPv6, if the next header isn't the last header, * the intermediate headers do *NOT* appear to be shown in * the dump file *at all*, so the packet *cannot* be * reconstructed! */ if (offset == 22) { if (strncmp(data + 22, "IP Header : ", 14) == 0 || strncmp(data + 22, "IPv6 Header: ", 14) == 0 || strncmp(data + 22, "ARP Header : ", 14) == 0 || strncmp(data + 22, "TCP Header : ", 14) == 0 || strncmp(data + 22, "UDP Header : ", 14) == 0 || strncmp(data + 22, "ICMP Header: ", 14) == 0 || strncmp(data + 22, "ICMPv6 Hdr: ", 14) == 0 || strncmp(data + 22, "Option Hdr: ", 14) == 0) { ascii_offset = append_hex_digits(ascii_buf, ascii_offset, ISERIES_PKT_ALLOC_SIZE - 1, data + 22 + 14, err, err_info); if (ascii_offset == -1) { /* Bad line. */ return FALSE; } continue; } } /* * Is this a data line? * * The "Data" starts at an offset of 8. */ if (offset == 9) { if (strncmp(data + 9, "Data . . . . . : ", 18) == 0) { ascii_offset = append_hex_digits(ascii_buf, ascii_offset, ISERIES_PKT_ALLOC_SIZE - 1, data + 9 + 18, err, err_info); if (ascii_offset == -1) { /* Bad line. */ return FALSE; } continue; } } /* * Is this a continuation of a previous header or data line? * That's blanks followed by hex digits; first try the * "no column separators" form. * * Continuations of header lines begin at an offset of 36; * continuations of data lines begin at an offset of 27. */ if (offset == 36 || offset == 27) { ascii_offset = append_hex_digits(ascii_buf, ascii_offset, ISERIES_PKT_ALLOC_SIZE - 1, data + offset, err, err_info); if (ascii_offset == -1) { /* Bad line. */ return FALSE; } continue; } /* * If we see the identifier for the next packet then rewind and set * isCurrentPacket FALSE */ ascii_strup_inplace (data); /* If packet header found return the offset */ num_items_scanned = sscanf (data+78, "%*[ \n\t]ETHV2%*[ .:\n\t]TYPE%*[ .:\n\t]%4s",type); if ((num_items_scanned == 1) && pktline > 1) { isCurrentPacket = FALSE; cur_off = file_tell( fh); if (cur_off == -1) { /* Error. */ *err = file_error (fh, err_info); goto errxit; } if (file_seek (fh, cur_off - buflen, SEEK_SET, err) == -1) { /* XXX: need to set err_info ?? */ goto errxit; } } } ascii_buf[ascii_offset] = '\0'; /* * Make the captured length be the amount of bytes we've read (which * is half the number of characters of hex dump we have). * * XXX - this can happen for IPv6 packets if the next header isn't the * last header. */ phdr->caplen = ((guint32) strlen (ascii_buf))/2; /* Make sure we have enough room for the packet. */ buffer_assure_space (buf, ISERIES_MAX_PACKET_LEN); /* Convert ascii data to binary and return in the frame buffer */ iseries_parse_hex_string (ascii_buf, buffer_start_ptr (buf), strlen (ascii_buf)); /* free buffer allocs and return */ *err = 0; g_free (ascii_buf); return TRUE; errxit: g_free (ascii_buf); return FALSE; }
/* Reads the next packet. */ static gboolean observer_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { int header_bytes_consumed; int data_bytes_consumed; packet_entry_header packet_header; /* skip records other than data records */ for (;;) { *data_offset = file_tell(wth->fh); /* process the packet header, including TLVs */ header_bytes_consumed = read_packet_header(wth->fh, &wth->phdr.pseudo_header, &packet_header, err, err_info); if (header_bytes_consumed <= 0) return FALSE; /* EOF or error */ if (packet_header.packet_type == PACKET_TYPE_DATA_PACKET) break; /* skip to next packet */ if (!skip_to_next_packet(wth, packet_header.offset_to_next_packet, header_bytes_consumed, err, err_info)) { return FALSE; /* EOF or error */ } } /* neglect frame markers for wiretap */ if (packet_header.network_size < 4) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("Observer: bad record: Packet length %u < 4", packet_header.network_size); return FALSE; } /* set the wiretap packet header fields */ wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; wth->phdr.pkt_encap = observer_to_wtap_encap(packet_header.network_type); if(wth->file_encap == WTAP_ENCAP_FIBRE_CHANNEL_FC2_WITH_FRAME_DELIMS) { wth->phdr.len = packet_header.network_size; wth->phdr.caplen = packet_header.captured_size; } else { wth->phdr.len = packet_header.network_size - 4; wth->phdr.caplen = MIN(packet_header.captured_size, wth->phdr.len); } /* set the wiretap timestamp, assuming for the moment that Observer encoded it in GMT */ wth->phdr.ts.secs = (time_t) ((packet_header.nano_seconds_since_2000 / 1000000000) + ansi_to_observer_epoch_offset); wth->phdr.ts.nsecs = (int) (packet_header.nano_seconds_since_2000 % 1000000000); /* adjust to local time, if necessary, also accounting for DST if the frame was captured while it was in effect */ if (((observer_dump_private_state*)wth->priv)->time_format == TIME_INFO_LOCAL) { struct tm daylight_tm; struct tm standard_tm; time_t dst_offset; /* the Observer timestamp was encoded as local time, so add a correction from local time to GMT */ wth->phdr.ts.secs += gmt_to_localtime_offset; /* perform a DST adjustment if necessary */ standard_tm = *localtime(&wth->phdr.ts.secs); if (standard_tm.tm_isdst > 0) { daylight_tm = standard_tm; standard_tm.tm_isdst = 0; dst_offset = mktime(&standard_tm) - mktime(&daylight_tm); wth->phdr.ts.secs -= dst_offset; } } /* update the pseudo header */ switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* There is no FCS in the frame */ wth->phdr.pseudo_header.eth.fcs_len = 0; break; case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: /* Updated in read_packet_header */ break; } /* set-up the packet buffer */ buffer_assure_space(wth->frame_buffer, packet_header.captured_size); /* read the frame data */ data_bytes_consumed = read_packet_data(wth->fh, packet_header.offset_to_frame, header_bytes_consumed, buffer_start_ptr(wth->frame_buffer), packet_header.captured_size, err, err_info); if (data_bytes_consumed < 0) { return FALSE; } /* skip over any extra bytes following the frame data */ if (!skip_to_next_packet(wth, packet_header.offset_to_next_packet, header_bytes_consumed + data_bytes_consumed, err, err_info)) { return FALSE; } return TRUE; }
void buffer_append_buffer(Buffer* buffer, Buffer* src_buffer) { buffer_append(buffer, buffer_start_ptr(src_buffer), buffer_length(src_buffer)); }
static gboolean etherpeek_read_v7(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { guint8 ep_pkt[ETHERPEEK_V7_PKT_SIZE]; #if 0 guint16 protoNum; #endif guint16 length; guint16 sliceLength; #if 0 guint8 flags; #endif guint8 status; guint64 timestamp; time_t tsecs; guint32 tusecs; *data_offset = file_tell(wth->fh); wtap_file_read_expected_bytes(ep_pkt, sizeof(ep_pkt), wth->fh, err, err_info); /* Extract the fields from the packet */ #if 0 protoNum = pntohs(&ep_pkt[ETHERPEEK_V7_PROTONUM_OFFSET]); #endif length = pntohs(&ep_pkt[ETHERPEEK_V7_LENGTH_OFFSET]); sliceLength = pntohs(&ep_pkt[ETHERPEEK_V7_SLICE_LENGTH_OFFSET]); #if 0 flags = ep_pkt[ETHERPEEK_V7_FLAGS_OFFSET]; #endif status = ep_pkt[ETHERPEEK_V7_STATUS_OFFSET]; timestamp = pntohll(&ep_pkt[ETHERPEEK_V7_TIMESTAMP_OFFSET]); /* force sliceLength to be the actual length of the packet */ if (0 == sliceLength) { sliceLength = length; } wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; /* fill in packet header length values before slicelength may be adjusted */ wth->phdr.len = length; wth->phdr.caplen = sliceLength; if (sliceLength % 2) /* packets are padded to an even length */ sliceLength++; switch (wth->file_encap) { case WTAP_ENCAP_IEEE_802_11_AIROPEEK: wth->pseudo_header.ieee_802_11.fcs_len = 0; /* no FCS */ break; case WTAP_ENCAP_ETHERNET: /* XXX - it appears that if the low-order bit of "status" is 0, there's an FCS in this frame, and if it's 1, there's 4 bytes of 0. */ wth->pseudo_header.eth.fcs_len = (status & 0x01) ? 0 : 4; break; } /* read the frame data */ buffer_assure_space(wth->frame_buffer, sliceLength); wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer), sliceLength, wth->fh, err, err_info); /* fill in packet header values */ tsecs = (time_t) (timestamp/1000000); tusecs = (guint32) (timestamp - tsecs*1000000); wth->phdr.ts.secs = tsecs - mac2unix; wth->phdr.ts.nsecs = tusecs * 1000; if (wth->file_encap == WTAP_ENCAP_IEEE_802_11_AIROPEEK) { /* * The last 4 bytes appear to be random data - the length * might include the FCS - so we reduce the length by 4. * * Or maybe this is just the same kind of random 4 bytes * of junk at the end you get in Wireless Sniffer * captures. */ wth->phdr.len -= 4; wth->phdr.caplen -= 4; } return TRUE; }
/* 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; }
/* Find the next packet and parse it; called from wtap_read(). */ static gboolean netscreen_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { gint64 offset; guint8 *buf; int pkt_len, caplen; char line[NETSCREEN_LINE_LENGTH]; char cap_int[NETSCREEN_MAX_INT_NAME_LENGTH]; gboolean cap_dir; char cap_dst[13]; gchar dststr[13]; /* Find the next packet */ offset = netscreen_seek_next_packet(wth, err, err_info, line); if (offset < 0) return FALSE; wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; /* Parse the header */ pkt_len = parse_netscreen_rec_hdr(wth, line, cap_int, &cap_dir, cap_dst, &wth->pseudo_header, err, err_info); if (pkt_len == -1) return FALSE; /* Make sure we have enough room for the packet */ buffer_assure_space(wth->frame_buffer, NETSCREEN_MAX_PACKET_LEN); buf = buffer_start_ptr(wth->frame_buffer); /* Convert the ASCII hex dump to binary data */ if ((caplen = parse_netscreen_hex_dump(wth->fh, pkt_len, buf, err, err_info)) == -1) { return FALSE; } /* * Determine the encapsulation type, based on the * first 4 characters of the interface name * * XXX convert this to a 'case' structure when adding more * (non-ethernet) interfacetypes */ if (strncmp(cap_int, "adsl", 4) == 0) { /* The ADSL interface can be bridged with or without * PPP encapsulation. Check whether the first six bytes * of the hex data are the same as the destination mac * address in the header. If they are, assume ethernet * LinkLayer or else PPP */ g_snprintf(dststr, 13, "%02x%02x%02x%02x%02x%02x", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); if (strncmp(dststr, cap_dst, 12) == 0) wth->phdr.pkt_encap = WTAP_ENCAP_ETHERNET; else wth->phdr.pkt_encap = WTAP_ENCAP_PPP; } else if (strncmp(cap_int, "seri", 4) == 0) wth->phdr.pkt_encap = WTAP_ENCAP_PPP; else wth->phdr.pkt_encap = WTAP_ENCAP_ETHERNET; /* * If the per-file encapsulation isn't known, set it to this * packet's encapsulation. * * If it *is* known, and it isn't this packet's encapsulation, * set it to WTAP_ENCAP_PER_PACKET, as this file doesn't * have a single encapsulation for all packets in the file. */ if (wth->file_encap == WTAP_ENCAP_UNKNOWN) wth->file_encap = wth->phdr.pkt_encap; else { if (wth->file_encap != wth->phdr.pkt_encap) wth->file_encap = WTAP_ENCAP_PER_PACKET; } wth->phdr.caplen = caplen; *data_offset = offset; return TRUE; }