/* Read IPFIX message header from file. Return true on success. Set *err to * 0 on EOF, any other value for "real" errors (EOF is ok, since return * value is still FALSE) */ static gboolean ipfix_read_message_header(ipfix_message_header_t *pfx_hdr, FILE_T fh, int *err, gchar **err_info) { if (!wtap_read_bytes_or_eof(fh, pfx_hdr, IPFIX_MSG_HDR_SIZE, err, err_info)) return FALSE; /* fix endianess, because IPFIX files are always big-endian */ pfx_hdr->version = g_ntohs(pfx_hdr->version); pfx_hdr->message_length = g_ntohs(pfx_hdr->message_length); pfx_hdr->export_time_secs = g_ntohl(pfx_hdr->export_time_secs); pfx_hdr->sequence_number = g_ntohl(pfx_hdr->sequence_number); pfx_hdr->observation_id = g_ntohl(pfx_hdr->observation_id); /* is the version number one we expect? */ if (pfx_hdr->version != IPFIX_VERSION) { /* Not an ipfix file. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("ipfix: wrong version %d", pfx_hdr->version); return FALSE; } if (pfx_hdr->message_length < 16) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("ipfix: message length %u is too short", pfx_hdr->message_length); return FALSE; } /* go back to before header */ if (file_seek(fh, 0 - IPFIX_MSG_HDR_SIZE, SEEK_CUR, err) == -1) { ipfix_debug("ipfix_read: couldn't go back in file before header"); return FALSE; } return TRUE; }
static gboolean hcidump_process_packet(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { struct dump_hdr dh; int packet_size; if (!wtap_read_bytes_or_eof(fh, &dh, DUMP_HDR_SIZE, err, err_info)) return FALSE; packet_size = GUINT16_FROM_LE(dh.len); 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("hcidump: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return FALSE; } phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS; phdr->ts.secs = GUINT32_FROM_LE(dh.ts_sec); phdr->ts.nsecs = GUINT32_FROM_LE(dh.ts_usec) * 1000; phdr->caplen = packet_size; phdr->len = packet_size; phdr->pseudo_header.p2p.sent = (dh.in ? FALSE : TRUE); return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info); }
static gboolean commview_read_header(commview_header_t *cv_hdr, FILE_T fh, int *err, gchar **err_info) { if (!wtap_read_bytes_or_eof(fh, &cv_hdr->data_len, 2, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->source_data_len, 2, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->version, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->year, 2, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->month, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->day, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->hours, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->minutes, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->seconds, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->usecs, 4, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->flags, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->signal_level_percent, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->rate, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->band, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->channel, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->direction, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->signal_level_dbm, 1, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, &cv_hdr->noise_level, 1, err, err_info)) return FALSE; /* Convert multi-byte values from little endian to host endian format */ cv_hdr->data_len = GUINT16_FROM_LE(cv_hdr->data_len); cv_hdr->source_data_len = GUINT16_FROM_LE(cv_hdr->source_data_len); cv_hdr->year = GUINT16_FROM_LE(cv_hdr->year); cv_hdr->usecs = GUINT32_FROM_LE(cv_hdr->usecs); return TRUE; }
static gboolean aethra_read_rec_header(wtap *wth, FILE_T fh, struct aethrarec_hdr *hdr, struct wtap_pkthdr *phdr, int *err, gchar **err_info) { aethra_t *aethra = (aethra_t *)wth->priv; guint32 rec_size; guint32 packet_size; guint32 msecs; /* Read record header. */ if (!wtap_read_bytes_or_eof(fh, hdr, sizeof *hdr, err, err_info)) return FALSE; rec_size = pletoh16(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; } if (rec_size > WTAP_MAX_PACKET_SIZE) { /* * Probably a corrupt capture file; return an error, * so that our caller doesn't blow up trying to allocate * space for an immensely-large packet. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("aethra: File has %u-byte packet, bigger than maximum of %u", rec_size, WTAP_MAX_PACKET_SIZE); return FALSE; } packet_size = rec_size - (guint32)(sizeof *hdr - sizeof hdr->rec_size); msecs = pletoh32(hdr->timestamp); phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS; phdr->ts.secs = aethra->start + (msecs / 1000); phdr->ts.nsecs = (msecs % 1000) * 1000000; phdr->caplen = packet_size; phdr->len = packet_size; phdr->pseudo_header.isdn.uton = (hdr->flags & AETHRA_U_TO_N); phdr->pseudo_header.isdn.channel = 0; /* XXX - D channel */ return TRUE; }
static gboolean csids_read_packet(FILE_T fh, csids_t *csids, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info) { struct csids_header hdr; guint8 *pd; if( !wtap_read_bytes_or_eof( fh, &hdr, sizeof( struct csids_header), err, err_info ) ) return FALSE; hdr.seconds = pntoh32(&hdr.seconds); hdr.caplen = pntoh16(&hdr.caplen); /* * The maximum value of hdr.caplen is 65535, which is less than * WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check * it. */ rec->rec_type = REC_TYPE_PACKET; rec->presence_flags = WTAP_HAS_TS; rec->rec_header.packet_header.len = hdr.caplen; rec->rec_header.packet_header.caplen = hdr.caplen; rec->ts.secs = hdr.seconds; rec->ts.nsecs = 0; if( !wtap_read_packet_bytes( fh, buf, rec->rec_header.packet_header.caplen, err, err_info ) ) return FALSE; pd = ws_buffer_start_ptr( buf ); if( csids->byteswapped ) { if( rec->rec_header.packet_header.caplen >= 2 ) { PBSWAP16(pd); /* the ip len */ if( rec->rec_header.packet_header.caplen >= 4 ) { PBSWAP16(pd+2); /* ip id */ if( rec->rec_header.packet_header.caplen >= 6 ) PBSWAP16(pd+4); /* ip flags and fragoff */ } } } return TRUE; }
/* Read the header of the next packet. Return TRUE on success, FALSE on error. */ static gboolean _5views_read_header(wtap *wth, FILE_T fh, t_5VW_TimeStamped_Header *hdr, wtap_rec *rec, int *err, gchar **err_info) { /* Read record header. */ if (!wtap_read_bytes_or_eof(fh, hdr, (unsigned int)sizeof(t_5VW_TimeStamped_Header), err, err_info)) return FALSE; hdr->Key = pletoh32(&hdr->Key); if (hdr->Key != CST_5VW_RECORDS_HEADER_KEY) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("5views: Time-stamped header has bad key value 0x%08X", hdr->Key); return FALSE; } hdr->RecSubType = pletoh32(&hdr->RecSubType); hdr->RecSize = pletoh32(&hdr->RecSize); hdr->Utc = pletoh32(&hdr->Utc); hdr->NanoSecondes = pletoh32(&hdr->NanoSecondes); rec->rec_type = REC_TYPE_PACKET; rec->presence_flags = WTAP_HAS_TS; rec->ts.secs = hdr->Utc; rec->ts.nsecs = hdr->NanoSecondes; rec->rec_header.packet_header.caplen = hdr->RecSize; rec->rec_header.packet_header.len = hdr->RecSize; switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* We assume there's no FCS in this frame. */ rec->rec_header.packet_header.pseudo_header.eth.fcs_len = 0; break; } return TRUE; }
/* * See * * http://www.opengroup.org/onlinepubs/9638599/apdxf.htm * * for the "dlpi.h" header file specified by The Open Group, which lists * the DL_ values for various protocols; Solaris 7 uses the same values. * * See * * http://www.iana.org/assignments/snoop-datalink-types/snoop-datalink-types.xml * * for the IETF list of snoop datalink types. * * The page at * * http://mrpink.lerc.nasa.gov/118x/support.html * * had links to modified versions of "tcpdump" and "libpcap" for SUNatm * DLPI support; they suggested that the 3.0 verson of SUNatm uses those * values. The Wayback Machine archived that page, but not the stuff * to which it linked, unfortunately. * * It also has a link to "convert.c", which is a program to convert files * from the format written by the "atmsnoop" program that comes with the * SunATM package to regular "snoop" format, claims that "SunATM 2.1 claimed * to be DL_FDDI (don't ask why). SunATM 3.0 claims to be DL_IPATM, which * is 0x12". * * It also says that "ATM Mac header is 12 bytes long.", and seems to imply * that in an "atmsnoop" file, the header contains 2 bytes (direction and * VPI?), 2 bytes of VCI, 6 bytes of something, and 2 bytes of Ethernet * type; if those 6 bytes are 2 bytes of DSAP, 2 bytes of LSAP, 1 byte * of LLC control, and 3 bytes of SNAP OUI, that'd mean that an ATM * pseudo-header in an "atmsnoop" file is probably 1 byte of direction, * 1 byte of VPI, and 2 bytes of VCI. * * The aforementioned page also has a link to some capture files from * "atmsnoop"; this version of "snoop.c" appears to be able to read them. * * Source to an "atmdump" package, which includes a modified version of * "libpcap" to handle SunATM DLPI and an ATM driver for FreeBSD, and * also includes "atmdump", which is a modified "tcpdump", was available * at * * ftp://ftp.cs.ndsu.nodak.edu/pub/freebsd/atm/atm-bpf.tgz * * (the host name is no longer valid) and that code also indicated that * DL_IPATM is used, and that an ATM packet handed up from the Sun driver * for the Sun SBus ATM card on Solaris 2.5.1 has 1 byte of direction, * 1 byte of VPI, 2 bytes of VCI, and then the ATM PDU, and suggests that * the direction flag is 0x80 for "transmitted" (presumably meaning * DTE->DCE) and presumably not 0x80 for "received" (presumably meaning * DCE->DTE). That code was used as the basis for the SunATM support in * later versions of libpcap and tcpdump, and it worked at the time the * development was done with the SunATM code on the system on which the * development was done. * * In fact, the "direction" byte appears to have some other stuff, perhaps * a traffic type, in the lower 7 bits, with the 8th bit indicating the * direction. That appears to be the case. * * I don't know what the encapsulation of any of the other types is, so I * leave them all as WTAP_ENCAP_UNKNOWN, except for those for which Brian * Ginsbach has supplied information about the way UNICOS/mp uses them. * I also don't know whether "snoop" can handle any of them (it presumably * can't handle ATM, otherwise Sun wouldn't have supplied "atmsnoop"; even * if it can't, this may be useful reference information for anybody doing * code to use DLPI to do raw packet captures on those network types. * * http://web.archive.org/web/20010906213807/http://www.shomiti.com/support/TNCapFileFormat.htm * * gives information on Shomiti's mutant flavor of snoop. For some unknown * reason, they decided not to just Go With The DLPI Flow, and instead used * the types unspecified in RFC 1461 for their own nefarious purposes, such * as distinguishing 10MB from 100MB from 1000MB Ethernet and distinguishing * 4MB from 16MB Token Ring, and distinguishing both of them from the * "Shomiti" versions of same. */ wtap_open_return_val snoop_open(wtap *wth, int *err, gchar **err_info) { char magic[sizeof snoop_magic]; struct snoop_hdr hdr; struct snooprec_hdr rec_hdr; guint padbytes; gboolean is_shomiti; static const int snoop_encap[] = { WTAP_ENCAP_ETHERNET, /* IEEE 802.3 */ WTAP_ENCAP_UNKNOWN, /* IEEE 802.4 Token Bus */ WTAP_ENCAP_TOKEN_RING, WTAP_ENCAP_UNKNOWN, /* IEEE 802.6 Metro Net */ WTAP_ENCAP_ETHERNET, WTAP_ENCAP_UNKNOWN, /* HDLC */ WTAP_ENCAP_UNKNOWN, /* Character Synchronous, e.g. bisync */ WTAP_ENCAP_UNKNOWN, /* IBM Channel-to-Channel */ WTAP_ENCAP_FDDI_BITSWAPPED, WTAP_ENCAP_NULL, /* Other */ WTAP_ENCAP_UNKNOWN, /* Frame Relay LAPF */ WTAP_ENCAP_UNKNOWN, /* Multi-protocol over Frame Relay */ WTAP_ENCAP_UNKNOWN, /* Character Async (e.g., SLIP and PPP?) */ WTAP_ENCAP_UNKNOWN, /* X.25 Classical IP */ WTAP_ENCAP_NULL, /* software loopback */ WTAP_ENCAP_UNKNOWN, /* not defined in "dlpi.h" */ WTAP_ENCAP_IP_OVER_FC, /* Fibre Channel */ WTAP_ENCAP_UNKNOWN, /* ATM */ WTAP_ENCAP_ATM_PDUS, /* ATM Classical IP */ WTAP_ENCAP_UNKNOWN, /* X.25 LAPB */ WTAP_ENCAP_UNKNOWN, /* ISDN */ WTAP_ENCAP_UNKNOWN, /* HIPPI */ WTAP_ENCAP_UNKNOWN, /* 100VG-AnyLAN Ethernet */ WTAP_ENCAP_UNKNOWN, /* 100VG-AnyLAN Token Ring */ WTAP_ENCAP_UNKNOWN, /* "ISO 8802/3 and Ethernet" */ WTAP_ENCAP_UNKNOWN, /* 100BaseT (but that's just Ethernet) */ WTAP_ENCAP_IP_OVER_IB, /* Infiniband */ }; #define NUM_SNOOP_ENCAPS (sizeof snoop_encap / sizeof snoop_encap[0]) #define SNOOP_PRIVATE_BIT 0x80000000 static const int snoop_private_encap[] = { WTAP_ENCAP_UNKNOWN, /* Not Used */ WTAP_ENCAP_UNKNOWN, /* IPv4 Tunnel Link */ WTAP_ENCAP_UNKNOWN, /* IPv6 Tunnel Link */ WTAP_ENCAP_UNKNOWN, /* Virtual network interface */ WTAP_ENCAP_UNKNOWN, /* IEEE 802.11 */ WTAP_ENCAP_IPNET, /* ipnet(7D) link */ WTAP_ENCAP_UNKNOWN, /* IPMP stub interface */ WTAP_ENCAP_UNKNOWN, /* 6to4 Tunnel Link */ }; #define NUM_SNOOP_PRIVATE_ENCAPS (sizeof snoop_private_encap / sizeof snoop_private_encap[0]) static const int shomiti_encap[] = { WTAP_ENCAP_ETHERNET, /* IEEE 802.3 */ WTAP_ENCAP_UNKNOWN, /* IEEE 802.4 Token Bus */ WTAP_ENCAP_TOKEN_RING, WTAP_ENCAP_UNKNOWN, /* IEEE 802.6 Metro Net */ WTAP_ENCAP_ETHERNET, WTAP_ENCAP_UNKNOWN, /* HDLC */ WTAP_ENCAP_UNKNOWN, /* Character Synchronous, e.g. bisync */ WTAP_ENCAP_UNKNOWN, /* IBM Channel-to-Channel */ WTAP_ENCAP_FDDI_BITSWAPPED, WTAP_ENCAP_UNKNOWN, /* Other */ WTAP_ENCAP_ETHERNET, /* Fast Ethernet */ WTAP_ENCAP_TOKEN_RING, /* 4MB 802.5 token ring */ WTAP_ENCAP_ETHERNET, /* Gigabit Ethernet */ WTAP_ENCAP_TOKEN_RING, /* "IEEE 802.5 Shomiti" */ WTAP_ENCAP_TOKEN_RING, /* "4MB IEEE 802.5 Shomiti" */ WTAP_ENCAP_UNKNOWN, /* Other */ WTAP_ENCAP_UNKNOWN, /* Other */ WTAP_ENCAP_UNKNOWN, /* Other */ WTAP_ENCAP_IEEE_802_11_WITH_RADIO, /* IEEE 802.11 with Radio Header */ WTAP_ENCAP_ETHERNET, /* 10 Gigabit Ethernet */ }; #define NUM_SHOMITI_ENCAPS (sizeof shomiti_encap / sizeof shomiti_encap[0]) int file_encap; gint64 saved_offset; /* Read in the string that should be at the start of a "snoop" file */ if (!wtap_read_bytes(wth->fh, magic, sizeof magic, err, err_info)) { if (*err != WTAP_ERR_SHORT_READ) return WTAP_OPEN_ERROR; return WTAP_OPEN_NOT_MINE; } if (memcmp(magic, snoop_magic, sizeof snoop_magic) != 0) { return WTAP_OPEN_NOT_MINE; } /* Read the rest of the header. */ if (!wtap_read_bytes(wth->fh, &hdr, sizeof hdr, err, err_info)) return WTAP_OPEN_ERROR; /* * Make sure it's a version we support. */ hdr.version = g_ntohl(hdr.version); switch (hdr.version) { case 2: /* Solaris 2.x and later snoop, and Shomiti Surveyor prior to 3.0, or 3.0 and later with NDIS card */ case 3: /* Surveyor 3.0 and later, with Shomiti CMM2 hardware */ case 4: /* Surveyor 3.0 and later, with Shomiti GAM hardware */ case 5: /* Surveyor 3.0 and later, with Shomiti THG hardware */ break; default: *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("snoop: version %u unsupported", hdr.version); return WTAP_OPEN_ERROR; } /* * Oh, this is lovely. * * I suppose Shomiti could give a bunch of lawyerly noise about * how "well, RFC 1761 said they were unassigned, and that's * the standard, not the DLPI header file, so it's perfectly OK * for us to use them, blah blah blah", but it's still irritating * as hell that they used the unassigned-in-RFC-1761 values for * their own purposes - especially given that Sun also used * one of them in atmsnoop. * * We can't determine whether it's a Shomiti capture based on * the version number, as, according to their documentation on * their capture file format, Shomiti uses a version number of 2 * if the data "was captured using an NDIS card", which presumably * means "captured with an ordinary boring network card via NDIS" * as opposed to "captured with our whizzo special capture * hardware". * * The only way I can see to determine that is to check how much * padding there is in the first packet - if there's enough * padding for a Shomiti trailer, it's probably a Shomiti * capture, and otherwise, it's probably from Snoop. */ /* * Start out assuming it's not a Shomiti capture. */ is_shomiti = FALSE; /* Read first record header. */ saved_offset = file_tell(wth->fh); if (!wtap_read_bytes_or_eof(wth->fh, &rec_hdr, sizeof rec_hdr, err, err_info)) { if (*err != 0) return WTAP_OPEN_ERROR; /* * The file ends after the record header, which means this * is a capture with no packets. * * We assume it's a snoop file; the actual type of file is * irrelevant, as there are no records in it, and thus no * extra information if it's a Shomiti capture, and no * link-layer headers whose type we have to know, and no * Ethernet frames that might have an FCS. */ } else { /* * Compute the number of bytes of padding in the * record. If it's at least the size of a Shomiti * trailer record, we assume this is a Shomiti * capture. (Some atmsnoop captures appear * to have 4 bytes of padding, and at least one * snoop capture appears to have 6 bytes of padding; * the Shomiti header is larger than either of those.) */ if (g_ntohl(rec_hdr.rec_len) > (sizeof rec_hdr + g_ntohl(rec_hdr.incl_len))) { /* * Well, we have padding; how much? */ padbytes = g_ntohl(rec_hdr.rec_len) - ((guint)sizeof rec_hdr + g_ntohl(rec_hdr.incl_len)); /* * Is it at least the size of a Shomiti trailer? */ is_shomiti = (padbytes >= sizeof (struct shomiti_trailer)); } } /* * Seek back to the beginning of the first record. */ if (file_seek(wth->fh, saved_offset, SEEK_SET, err) == -1) return WTAP_OPEN_ERROR; hdr.network = g_ntohl(hdr.network); if (is_shomiti) { if (hdr.network >= NUM_SHOMITI_ENCAPS || shomiti_encap[hdr.network] == WTAP_ENCAP_UNKNOWN) { *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("snoop: Shomiti network type %u unknown or unsupported", hdr.network); return WTAP_OPEN_ERROR; } file_encap = shomiti_encap[hdr.network]; /* This is a Shomiti file */ wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_SHOMITI; } else if (hdr.network & SNOOP_PRIVATE_BIT) { if ((hdr.network^SNOOP_PRIVATE_BIT) >= NUM_SNOOP_PRIVATE_ENCAPS || snoop_private_encap[hdr.network^SNOOP_PRIVATE_BIT] == WTAP_ENCAP_UNKNOWN) { *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("snoop: private network type %u unknown or unsupported", hdr.network); return WTAP_OPEN_ERROR; } file_encap = snoop_private_encap[hdr.network^SNOOP_PRIVATE_BIT]; /* This is a snoop file */ wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_SNOOP; } else { if (hdr.network >= NUM_SNOOP_ENCAPS || snoop_encap[hdr.network] == WTAP_ENCAP_UNKNOWN) { *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("snoop: network type %u unknown or unsupported", hdr.network); return WTAP_OPEN_ERROR; } file_encap = snoop_encap[hdr.network]; /* This is a snoop file */ wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_SNOOP; } /* * We don't currently use the extra information in Shomiti * records, so we use the same routines to read snoop and * Shomiti files. */ wth->subtype_read = snoop_read; wth->subtype_seek_read = snoop_seek_read; wth->file_encap = file_encap; wth->snapshot_length = 0; /* not available in header */ wth->file_tsprec = WTAP_TSPREC_USEC; return WTAP_OPEN_MINE; }
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; guint32 rec_size; guint32 packet_size; guint32 orig_size; int header_size; /* Read record header. */ if (!wtap_read_bytes_or_eof(fh, &hdr, sizeof hdr, err, err_info)) 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, ws_buffer_start_ptr(buf)); } return rec_size - ((guint)sizeof hdr + packet_size); }
static gboolean radcom_read_rec(wtap *wth, FILE_T fh, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info) { struct radcomrec_hdr hdr; guint16 data_length, real_length, length; guint32 sec; struct tm tm; guint8 atmhdr[8]; if (!wtap_read_bytes_or_eof(fh, &hdr, sizeof hdr, err, err_info)) return FALSE; data_length = pletoh16(&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 = pletoh16(&hdr.length); real_length = pletoh16(&hdr.real_length); /* * The maximum value of length is 65535, which is less than * WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't need to check * it. */ rec->rec_type = REC_TYPE_PACKET; rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; tm.tm_year = pletoh16(&hdr.date.year)-1900; tm.tm_mon = (hdr.date.month&0x0f)-1; tm.tm_mday = hdr.date.day; sec = pletoh32(&hdr.date.sec); tm.tm_hour = sec/3600; tm.tm_min = (sec%3600)/60; tm.tm_sec = sec%60; tm.tm_isdst = -1; rec->ts.secs = mktime(&tm); rec->ts.nsecs = pletoh32(&hdr.date.usec) * 1000; switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* XXX - is there an FCS? */ rec->rec_header.packet_header.pseudo_header.eth.fcs_len = -1; break; case WTAP_ENCAP_LAPB: rec->rec_header.packet_header.pseudo_header.dte_dce.flags = (hdr.dce & 0x1) ? 0x00 : FROM_DCE; length -= 2; /* FCS */ real_length -= 2; break; case WTAP_ENCAP_ATM_RFC1483: /* * XXX - is this stuff a pseudo-header? * The direction appears to be in the "hdr.dce" field. */ if (!wtap_read_bytes(fh, atmhdr, sizeof atmhdr, err, err_info)) return FALSE; /* Read error */ length -= 8; real_length -= 8; break; } rec->rec_header.packet_header.len = real_length; rec->rec_header.packet_header.caplen = length; /* * Read the packet data. */ if (!wtap_read_packet_bytes(fh, buf, length, err, err_info)) return FALSE; /* Read error */ return TRUE; }
/* * Read the packet. * * XXX - we should supply the additional radio information; * the pseudo-header should probably be supplied in a fashion * similar to the radiotap radio header, so that the 802.11 * dissector can determine which, if any, information items * are present. */ static int peektagged_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { peektagged_t *peektagged = (peektagged_t *)wth->priv; gboolean read_a_tag = FALSE; guint8 tag_value[6]; guint16 tag; gboolean saw_length = FALSE; guint32 length = 0; guint32 sliceLength = 0; gboolean saw_timestamp_lower = FALSE; gboolean saw_timestamp_upper = FALSE; peektagged_utime timestamp; guint32 ext_flags = 0; gboolean saw_data_rate_or_mcs_index = FALSE; guint32 data_rate_or_mcs_index = 0; struct ieee_802_11_phdr ieee_802_11; int skip_len = 0; double t; timestamp.upper = 0; timestamp.lower = 0; memset(&ieee_802_11, 0, sizeof ieee_802_11); /* Extract the fields from the packet header */ do { /* Get the tag and value. XXX - this assumes all values are 4 bytes long. */ if (!wtap_read_bytes_or_eof(fh, tag_value, sizeof tag_value, err, err_info)) { if (*err == 0) { /* * Short read if we've read something already; * just an EOF if we haven't. */ if (read_a_tag) *err = WTAP_ERR_SHORT_READ; } return -1; } read_a_tag = TRUE; tag = pletoh16(&tag_value[0]); switch (tag) { case TAG_PEEKTAGGED_LENGTH: if (saw_length) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: record has two length fields"); return -1; } length = pletoh32(&tag_value[2]); saw_length = TRUE; break; case TAG_PEEKTAGGED_TIMESTAMP_LOWER: if (saw_timestamp_lower) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: record has two timestamp-lower fields"); return -1; } timestamp.lower = pletoh32(&tag_value[2]); saw_timestamp_lower = TRUE; break; case TAG_PEEKTAGGED_TIMESTAMP_UPPER: if (saw_timestamp_upper) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: record has two timestamp-upper fields"); return -1; } timestamp.upper = pletoh32(&tag_value[2]); saw_timestamp_upper = TRUE; break; case TAG_PEEKTAGGED_FLAGS_AND_STATUS: /* XXX - not used yet */ break; case TAG_PEEKTAGGED_CHANNEL: ieee_802_11.presence_flags |= PHDR_802_11_HAS_CHANNEL; ieee_802_11.channel = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_DATA_RATE_OR_MCS_INDEX: data_rate_or_mcs_index = pletoh32(&tag_value[2]); saw_data_rate_or_mcs_index = TRUE; break; case TAG_PEEKTAGGED_SIGNAL_PERC: ieee_802_11.presence_flags |= PHDR_802_11_HAS_SIGNAL_PERCENT; ieee_802_11.signal_percent = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_SIGNAL_DBM: ieee_802_11.presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM; ieee_802_11.signal_dbm = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_NOISE_PERC: ieee_802_11.presence_flags |= PHDR_802_11_HAS_NOISE_PERCENT; ieee_802_11.noise_percent = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_NOISE_DBM: ieee_802_11.presence_flags |= PHDR_802_11_HAS_NOISE_DBM; ieee_802_11.noise_dbm = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_UNKNOWN_0x000A: /* XXX - seen in an OmniPeek 802.11n capture; value unknown */ break; case TAG_PEEKTAGGED_CENTER_FREQUENCY: /* XXX - also seen in an EtherPeek capture; value unknown */ ieee_802_11.presence_flags |= PHDR_802_11_HAS_FREQUENCY; ieee_802_11.frequency = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_UNKNOWN_0x000E: /* XXX - seen in an AiroPeek/OmniPeek capture; value unknown */ break; case TAG_PEEKTAGGED_UNKNOWN_0x000F: /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */ break; case TAG_PEEKTAGGED_UNKNOWN_0x0010: /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */ break; case TAG_PEEKTAGGED_UNKNOWN_0x0011: /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */ break; case TAG_PEEKTAGGED_UNKNOWN_0x0012: /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */ break; case TAG_PEEKTAGGED_UNKNOWN_0x0013: /* XXX - seen in an AiroPeek/OmniPeek capture; dBm value? */ break; case TAG_PEEKTAGGED_UNKNOWN_0x0014: /* XXX - seen in an AiroPeek/OmniPeek capture; value unknown */ break; case TAG_PEEKTAGGED_EXT_FLAGS: ext_flags = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_SLICE_LENGTH: sliceLength = pletoh32(&tag_value[2]); break; default: break; } } while (tag != TAG_PEEKTAGGED_SLICE_LENGTH); /* last tag */ if (!saw_length) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: record has no length field"); return -1; } if (!saw_timestamp_lower) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: record has no timestamp-lower field"); return -1; } if (!saw_timestamp_upper) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: record has no timestamp-upper field"); return -1; } /* * If sliceLength is 0, force it to be the actual length of the packet. */ if (sliceLength == 0) sliceLength = length; if (sliceLength > 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("peektagged: File has %u-byte packet, bigger than maximum of %u", sliceLength, WTAP_MAX_PACKET_SIZE); return -1; } phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; phdr->len = length; phdr->caplen = sliceLength; /* calculate and fill in packet time stamp */ t = (double) timestamp.lower + (double) timestamp.upper * 4294967296.0; t *= 1.0e-9; t -= TIME_FIXUP_CONSTANT; phdr->ts.secs = (time_t) t; phdr->ts.nsecs = (guint32) ((t - phdr->ts.secs)*1000000000); switch (wth->file_encap) { case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: if (saw_data_rate_or_mcs_index) { if (ext_flags & EXT_FLAG_MCS_INDEX_USED) { /* It's an MCS index. */ ieee_802_11.presence_flags |= PHDR_802_11_HAS_MCS_INDEX; ieee_802_11.mcs_index = data_rate_or_mcs_index; /* * Fill in other 802.11n information. */ switch (ext_flags & EXT_FLAGS_BANDWIDTH) { case 0: ieee_802_11.presence_flags |= PHDR_802_11_HAS_BANDWIDTH; ieee_802_11.bandwidth = PHDR_802_11_BANDWIDTH_20_MHZ; break; case EXT_FLAG_20_MHZ_LOWER: ieee_802_11.presence_flags |= PHDR_802_11_HAS_BANDWIDTH; ieee_802_11.bandwidth = PHDR_802_11_BANDWIDTH_20_20L; break; case EXT_FLAG_20_MHZ_UPPER: ieee_802_11.presence_flags |= PHDR_802_11_HAS_BANDWIDTH; ieee_802_11.bandwidth = PHDR_802_11_BANDWIDTH_20_20U; break; case EXT_FLAG_40_MHZ: ieee_802_11.presence_flags |= PHDR_802_11_HAS_BANDWIDTH; ieee_802_11.bandwidth = PHDR_802_11_BANDWIDTH_40_MHZ; break; default: /* Mutually exclusive flags set */ break; } switch (ext_flags & EXT_FLAGS_GI) { case EXT_FLAG_HALF_GI: ieee_802_11.presence_flags |= PHDR_802_11_HAS_SHORT_GI; ieee_802_11.short_gi = 1; break; case EXT_FLAG_FULL_GI: ieee_802_11.presence_flags |= PHDR_802_11_HAS_SHORT_GI; ieee_802_11.short_gi = 0; break; default: /* Mutually exclusive flags set */ break; } } else { /* It's a data rate */ ieee_802_11.presence_flags |= PHDR_802_11_HAS_DATA_RATE; ieee_802_11.data_rate = data_rate_or_mcs_index; } } phdr->pseudo_header.ieee_802_11 = ieee_802_11; if (peektagged->has_fcs) phdr->pseudo_header.ieee_802_11.fcs_len = 4; else { if (phdr->len < 4 || phdr->caplen < 4) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("peektagged: 802.11 packet has length < 4"); return FALSE; } phdr->pseudo_header.ieee_802_11.fcs_len = 0; phdr->len -= 4; phdr->caplen -= 4; skip_len = 4; } phdr->pseudo_header.ieee_802_11.decrypted = FALSE; 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? */ if (phdr->len < 4 || phdr->caplen < 4) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("peektagged: Ethernet packet has length < 4"); return FALSE; } phdr->pseudo_header.eth.fcs_len = 0; phdr->len -= 4; phdr->caplen -= 4; skip_len = 4; break; } /* Read the packet data. */ if (!wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info)) return -1; return skip_len; }
/* Read the header of the next packet. Return FALSE on an error, TRUE on success. */ static int libpcap_read_header(wtap *wth, FILE_T fh, int *err, gchar **err_info, struct pcaprec_ss990915_hdr *hdr) { int bytes_to_read; guint32 temp; libpcap_t *libpcap; switch (wth->file_type_subtype) { case WTAP_FILE_TYPE_SUBTYPE_PCAP: case WTAP_FILE_TYPE_SUBTYPE_PCAP_AIX: case WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC: bytes_to_read = sizeof (struct pcaprec_hdr); break; case WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990417: case WTAP_FILE_TYPE_SUBTYPE_PCAP_SS991029: bytes_to_read = sizeof (struct pcaprec_modified_hdr); break; case WTAP_FILE_TYPE_SUBTYPE_PCAP_SS990915: bytes_to_read = sizeof (struct pcaprec_ss990915_hdr); break; case WTAP_FILE_TYPE_SUBTYPE_PCAP_NOKIA: bytes_to_read = sizeof (struct pcaprec_nokia_hdr); break; default: g_assert_not_reached(); bytes_to_read = 0; } if (!wtap_read_bytes_or_eof(fh, hdr, bytes_to_read, err, err_info)) return FALSE; libpcap = (libpcap_t *)wth->priv; if (libpcap->byte_swapped) { /* Byte-swap the record header fields. */ hdr->hdr.ts_sec = GUINT32_SWAP_LE_BE(hdr->hdr.ts_sec); hdr->hdr.ts_usec = GUINT32_SWAP_LE_BE(hdr->hdr.ts_usec); hdr->hdr.incl_len = GUINT32_SWAP_LE_BE(hdr->hdr.incl_len); hdr->hdr.orig_len = GUINT32_SWAP_LE_BE(hdr->hdr.orig_len); } /* Swap the "incl_len" and "orig_len" fields, if necessary. */ switch (libpcap->lengths_swapped) { case NOT_SWAPPED: break; case MAYBE_SWAPPED: if (hdr->hdr.incl_len <= hdr->hdr.orig_len) { /* * The captured length is <= the actual length, * so presumably they weren't swapped. */ break; } /* FALLTHROUGH */ case SWAPPED: temp = hdr->hdr.orig_len; hdr->hdr.orig_len = hdr->hdr.incl_len; hdr->hdr.incl_len = temp; break; } return TRUE; }
static gboolean lanalyzer_read_trace_record(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { char LE_record_type[2]; char LE_record_length[2]; guint16 record_type, record_length; int record_data_size; int packet_size; gchar descriptor[DESCRIPTOR_LEN]; lanalyzer_t *lanalyzer; guint16 time_low, time_med, time_high, true_size; guint64 t; time_t tsecs; /* read the record type and length. */ if (!wtap_read_bytes_or_eof(fh, LE_record_type, 2, err, err_info)) return FALSE; if (!wtap_read_bytes(fh, LE_record_length, 2, err, err_info)) return FALSE; record_type = pletoh16(LE_record_type); record_length = pletoh16(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; } 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; } record_data_size = record_length - DESCRIPTOR_LEN; /* Read the descriptor data */ if (!wtap_read_bytes(fh, descriptor, DESCRIPTOR_LEN, err, err_info)) return FALSE; true_size = pletoh16(&descriptor[4]); packet_size = pletoh16(&descriptor[6]); /* * The maximum value of packet_size is 65535, which is less than * WTAP_MAX_PACKET_SIZE will ever be, so we don't need to check * it. */ /* * OK, is the frame data size greater than than what's left of the * record? */ if (packet_size > record_data_size) { /* * 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; } phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; time_low = pletoh16(&descriptor[8]); time_med = pletoh16(&descriptor[10]); time_high = pletoh16(&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; phdr->ts.secs = tsecs + lanalyzer->start; 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; } phdr->len = true_size; phdr->caplen = packet_size; switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* We assume there's no FCS in this frame. */ phdr->pseudo_header.eth.fcs_len = 0; break; } /* Read the packet data */ return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info); }
static gboolean stanag4607_read_file(wtap *wth, FILE_T fh, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info) { stanag4607_t *stanag4607 = (stanag4607_t *)wth->priv; guint32 millisecs, secs, nsecs; gint64 offset = 0; guint8 stanag_pkt_hdr[PKT_HDR_SIZE+SEG_HDR_SIZE]; guint32 packet_size; *err = 0; /* Combined packet header and segment header */ if (!wtap_read_bytes_or_eof(fh, stanag_pkt_hdr, sizeof stanag_pkt_hdr, err, err_info)) return FALSE; offset += sizeof stanag_pkt_hdr; if (!is_valid_id(pntoh16(&stanag_pkt_hdr[0]))) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("Bad version number"); return FALSE; } rec->rec_type = REC_TYPE_PACKET; /* The next 4 bytes are the packet length */ packet_size = pntoh32(&stanag_pkt_hdr[2]); if (packet_size > WTAP_MAX_PACKET_SIZE_STANDARD) { /* * 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("stanag4607: File has %" G_GUINT32_FORMAT "d-byte packet, " "bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE_STANDARD); return FALSE; } if (packet_size < PKT_HDR_SIZE+SEG_HDR_SIZE) { /* * Probably a corrupt capture file; don't, for example, loop * infinitely if the size is zero. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("stanag4607: File has %" G_GUINT32_FORMAT "d-byte packet, " "smaller than minimum of %u", packet_size, PKT_HDR_SIZE+SEG_HDR_SIZE); return FALSE; } rec->rec_header.packet_header.caplen = packet_size; rec->rec_header.packet_header.len = packet_size; /* Sadly, the header doesn't contain times; but some segments do */ /* So, get the segment header, which is just past the 32-byte header. */ rec->presence_flags = WTAP_HAS_TS; /* If no time specified, it's the last baseline time */ rec->ts.secs = stanag4607->base_secs; rec->ts.nsecs = 0; millisecs = 0; #define MISSION_SEGMENT 1 #define DWELL_SEGMENT 2 #define JOB_DEFINITION_SEGMENT 5 #define PLATFORM_LOCATION_SEGMENT 13 if (MISSION_SEGMENT == stanag_pkt_hdr[32]) { guint8 mseg[39]; struct tm tm; if (!wtap_read_bytes(fh, &mseg, sizeof mseg, err, err_info)) return FALSE; offset += sizeof mseg; tm.tm_year = pntoh16(&mseg[35]) - 1900; tm.tm_mon = mseg[37] - 1; tm.tm_mday = mseg[38]; tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = -1; stanag4607->base_secs = mktime(&tm); rec->ts.secs = stanag4607->base_secs; } else if (PLATFORM_LOCATION_SEGMENT == stanag_pkt_hdr[32]) { if (!wtap_read_bytes(fh, &millisecs, sizeof millisecs, err, err_info)) return FALSE; offset += sizeof millisecs; millisecs = g_ntohl(millisecs); } else if (DWELL_SEGMENT == stanag_pkt_hdr[32]) { guint8 dseg[19]; if (!wtap_read_bytes(fh, &dseg, sizeof dseg, err, err_info)) return FALSE; offset += sizeof dseg; millisecs = pntoh32(&dseg[15]); } if (0 != millisecs) { secs = millisecs/1000; nsecs = (millisecs - 1000 * secs) * 1000000; rec->ts.secs = stanag4607->base_secs + secs; rec->ts.nsecs = nsecs; } /* wind back to the start of the packet ... */ if (file_seek(fh, - offset, SEEK_CUR, err) == -1) return FALSE; return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info); }
/* * Read the packet. * * XXX - we should supply the additional radio information; * the pseudo-header should probably be supplied in a fashion * similar to the radiotap radio header, so that the 802.11 * dissector can determine which, if any, information items * are present. */ static int peektagged_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { peektagged_t *peektagged = (peektagged_t *)wth->priv; gboolean read_a_tag = FALSE; guint8 tag_value[6]; guint16 tag; gboolean saw_length = FALSE; guint32 length = 0; guint32 sliceLength = 0; gboolean saw_timestamp_lower = FALSE; gboolean saw_timestamp_upper = FALSE; peektagged_utime timestamp; guint32 ext_flags = 0; gboolean saw_data_rate_or_mcs_index = FALSE; guint32 data_rate_or_mcs_index = 0; gint channel; guint frequency; struct ieee_802_11_phdr ieee_802_11; guint i; int skip_len = 0; guint64 t; timestamp.upper = 0; timestamp.lower = 0; memset(&ieee_802_11, 0, sizeof ieee_802_11); ieee_802_11.fcs_len = -1; /* Unknown */ ieee_802_11.decrypted = FALSE; ieee_802_11.datapad = FALSE; ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN; /* Extract the fields from the packet header */ do { /* Get the tag and value. XXX - this assumes all values are 4 bytes long. */ if (!wtap_read_bytes_or_eof(fh, tag_value, sizeof tag_value, err, err_info)) { if (*err == 0) { /* * Short read if we've read something already; * just an EOF if we haven't. */ if (read_a_tag) *err = WTAP_ERR_SHORT_READ; } return -1; } read_a_tag = TRUE; tag = pletoh16(&tag_value[0]); switch (tag) { case TAG_PEEKTAGGED_LENGTH: if (saw_length) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: record has two length fields"); return -1; } length = pletoh32(&tag_value[2]); saw_length = TRUE; break; case TAG_PEEKTAGGED_TIMESTAMP_LOWER: if (saw_timestamp_lower) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: record has two timestamp-lower fields"); return -1; } timestamp.lower = pletoh32(&tag_value[2]); saw_timestamp_lower = TRUE; break; case TAG_PEEKTAGGED_TIMESTAMP_UPPER: if (saw_timestamp_upper) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: record has two timestamp-upper fields"); return -1; } timestamp.upper = pletoh32(&tag_value[2]); saw_timestamp_upper = TRUE; break; case TAG_PEEKTAGGED_FLAGS_AND_STATUS: /* XXX - not used yet */ break; case TAG_PEEKTAGGED_CHANNEL: ieee_802_11.has_channel = TRUE; ieee_802_11.channel = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_DATA_RATE_OR_MCS_INDEX: data_rate_or_mcs_index = pletoh32(&tag_value[2]); saw_data_rate_or_mcs_index = TRUE; break; case TAG_PEEKTAGGED_SIGNAL_PERC: ieee_802_11.has_signal_percent = TRUE; ieee_802_11.signal_percent = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_SIGNAL_DBM: ieee_802_11.has_signal_dbm = TRUE; ieee_802_11.signal_dbm = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_NOISE_PERC: ieee_802_11.has_noise_percent = TRUE; ieee_802_11.noise_percent = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_NOISE_DBM: ieee_802_11.has_noise_dbm = TRUE; ieee_802_11.noise_dbm = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_UNKNOWN_0x000A: /* * XXX - seen in some 802.11 captures. * Always seems to have the value 0 or 5. */ break; case TAG_PEEKTAGGED_CENTER_FREQUENCY: /* XXX - also seen in an EtherPeek capture; value unknown */ ieee_802_11.has_frequency = TRUE; ieee_802_11.frequency = pletoh32(&tag_value[2]); break; case TAG_PEEKTAGGED_UNKNOWN_0x000E: /* * XXX - seen in some 802.11 captures. * Usually has the value 4, but, in some packets, has the * values 6 or 302. * * Is this the mysterious "band" field that shows up in * some "Peek remote" protocol captures, with values in * the 30x or 40x ranges? It's not always associated * with the "extended flags" tag for HT/VHT information, * so it's probably not 11n/11ac-specific. Values other * than 4 appear, in my captures, only in packets with * the "extended flags" tag. 302 appeared in a packet * with EXT_FLAG_MCS_INDEX_USED; 6 appeared in packets * without EXT_FLAG_MCS_INDEX_USED. */ break; case TAG_PEEKTAGGED_UNKNOWN_0x000F: /* * XXX - seen in some 802.11 captures; dB or dBm value? * Multiple antennas? */ break; case TAG_PEEKTAGGED_UNKNOWN_0x0010: /* * XXX - seen in some 802.11 captures; dB or dBm value? * Multiple antennas? */ break; case TAG_PEEKTAGGED_UNKNOWN_0x0011: /* * XXX - seen in some 802.11 captures; dB or dBm value? * Multiple antennas? */ break; case TAG_PEEKTAGGED_UNKNOWN_0x0012: /* * XXX - seen in some 802.11 captures; dB or dBm value? * Multiple antennas? */ break; case TAG_PEEKTAGGED_UNKNOWN_0x0013: /* * XXX - seen in some 802.11 captures; dB or dBm value? * Multiple antennas? */ break; case TAG_PEEKTAGGED_UNKNOWN_0x0014: /* * XXX - seen in some 802.11 captures; dB or dBm value? * Multiple antennas? */ break; case TAG_PEEKTAGGED_EXT_FLAGS: /* * We assume this is present for HT and VHT frames and absent * for other frames. */ ext_flags = pletoh32(&tag_value[2]); if (ext_flags & EXT_FLAG_802_11ac) { ieee_802_11.phy = PHDR_802_11_PHY_11AC; /* * XXX - this probably has only one user, so only * one MCS index and only one NSS, but where's the * NSS? */ for (i = 0; i < 4; i++) ieee_802_11.phy_info.info_11ac.nss[i] = 0; switch (ext_flags & EXT_FLAGS_GI) { case EXT_FLAG_HALF_GI: ieee_802_11.phy_info.info_11ac.has_short_gi = TRUE; ieee_802_11.phy_info.info_11ac.short_gi = 1; break; case EXT_FLAG_FULL_GI: ieee_802_11.phy_info.info_11ac.has_short_gi = TRUE; ieee_802_11.phy_info.info_11ac.short_gi = 0; break; default: /* Mutually exclusive flags set or nothing set */ break; } } else { ieee_802_11.phy = PHDR_802_11_PHY_11N; switch (ext_flags & EXT_FLAGS_BANDWIDTH) { case 0: ieee_802_11.phy_info.info_11n.has_bandwidth = TRUE; ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_20_MHZ; break; case EXT_FLAG_20_MHZ_LOWER: ieee_802_11.phy_info.info_11n.has_bandwidth = TRUE; ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_20_20L; break; case EXT_FLAG_20_MHZ_UPPER: ieee_802_11.phy_info.info_11n.has_bandwidth = TRUE; ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_20_20U; break; case EXT_FLAG_40_MHZ: ieee_802_11.phy_info.info_11n.has_bandwidth = TRUE; ieee_802_11.phy_info.info_11n.bandwidth = PHDR_802_11_BANDWIDTH_40_MHZ; break; default: /* Mutually exclusive flags set */ break; } switch (ext_flags & EXT_FLAGS_GI) { case EXT_FLAG_HALF_GI: ieee_802_11.phy_info.info_11n.has_short_gi = TRUE; ieee_802_11.phy_info.info_11n.short_gi = 1; break; case EXT_FLAG_FULL_GI: ieee_802_11.phy_info.info_11n.has_short_gi = TRUE; ieee_802_11.phy_info.info_11n.short_gi = 0; break; default: /* Mutually exclusive flags set or nothing set */ break; } } break; case TAG_PEEKTAGGED_SLICE_LENGTH: sliceLength = pletoh32(&tag_value[2]); break; default: break; } } while (tag != TAG_PEEKTAGGED_SLICE_LENGTH); /* last tag */ if (!saw_length) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: record has no length field"); return -1; } if (!saw_timestamp_lower) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: record has no timestamp-lower field"); return -1; } if (!saw_timestamp_upper) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: record has no timestamp-upper field"); return -1; } /* * If sliceLength is 0, force it to be the actual length of the packet. */ if (sliceLength == 0) sliceLength = length; if (sliceLength > 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("peektagged: File has %u-byte packet, bigger than maximum of %u", sliceLength, WTAP_MAX_PACKET_SIZE); return -1; } phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; phdr->len = length; phdr->caplen = sliceLength; /* calculate and fill in packet time stamp */ t = (((guint64) timestamp.upper) << 32) + timestamp.lower; if (!nsfiletime_to_nstime(&phdr->ts, t)) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("peektagged: time stamp outside supported range"); return -1; } switch (wth->file_encap) { case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: if (saw_data_rate_or_mcs_index) { if (ext_flags & EXT_FLAG_MCS_INDEX_USED) { /* * It's an MCS index. * * XXX - what about 11ac? */ if (!(ext_flags & EXT_FLAG_802_11ac)) { ieee_802_11.phy_info.info_11n.has_mcs_index = TRUE; ieee_802_11.phy_info.info_11n.mcs_index = data_rate_or_mcs_index; } } else { /* It's a data rate. */ ieee_802_11.has_data_rate = TRUE; ieee_802_11.data_rate = data_rate_or_mcs_index; } } if (ieee_802_11.has_frequency && !ieee_802_11.has_channel) { /* Frequency, but no channel; try to calculate the channel. */ channel = ieee80211_mhz_to_chan(ieee_802_11.frequency); if (channel != -1) { ieee_802_11.has_channel = TRUE; ieee_802_11.channel = channel; } } else if (ieee_802_11.has_channel && !ieee_802_11.has_frequency) { /* * If it's 11 legacy DHSS, 11b, or 11g, it's 2.4 GHz, * so we can calculate the frequency. * * If it's 11a, it's 5 GHz, so we can calculate the * frequency. */ switch (ieee_802_11.phy) { case PHDR_802_11_PHY_11_DSSS: case PHDR_802_11_PHY_11B: case PHDR_802_11_PHY_11G: frequency = ieee80211_chan_to_mhz(ieee_802_11.channel, TRUE); break; case PHDR_802_11_PHY_11A: frequency = ieee80211_chan_to_mhz(ieee_802_11.channel, FALSE); break; default: /* We don't know the band. */ frequency = 0; break; } if (frequency != 0) { ieee_802_11.has_frequency = TRUE; ieee_802_11.frequency = frequency; } } phdr->pseudo_header.ieee_802_11 = ieee_802_11; if (peektagged->has_fcs) phdr->pseudo_header.ieee_802_11.fcs_len = 4; else { if (phdr->len < 4 || phdr->caplen < 4) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("peektagged: 802.11 packet has length < 4"); return FALSE; } phdr->pseudo_header.ieee_802_11.fcs_len = 0; phdr->len -= 4; phdr->caplen -= 4; skip_len = 4; } phdr->pseudo_header.ieee_802_11.decrypted = FALSE; phdr->pseudo_header.ieee_802_11.datapad = FALSE; 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? */ if (phdr->len < 4 || phdr->caplen < 4) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("peektagged: Ethernet packet has length < 4"); return FALSE; } phdr->pseudo_header.eth.fcs_len = 0; phdr->len -= 4; phdr->caplen -= 4; skip_len = 4; break; } /* Read the packet data. */ if (!wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info)) return -1; return skip_len; }
wtap_open_return_val nettl_open(wtap *wth, int *err, gchar **err_info) { struct nettl_file_hdr file_hdr; guint16 dummy[2]; int subsys; nettl_t *nettl; memset(&file_hdr, 0, sizeof(file_hdr)); /* Read in the string that should be at the start of a HP file */ if (!wtap_read_bytes(wth->fh, file_hdr.magic, MAGIC_SIZE, err, err_info)) { if (*err != WTAP_ERR_SHORT_READ) return WTAP_OPEN_ERROR; return WTAP_OPEN_NOT_MINE; } if (memcmp(file_hdr.magic, nettl_magic_hpux9, MAGIC_SIZE) && memcmp(file_hdr.magic, nettl_magic_hpux10, MAGIC_SIZE)) { return WTAP_OPEN_NOT_MINE; } /* Read the rest of the file header */ if (!wtap_read_bytes(wth->fh, file_hdr.file_name, FILE_HDR_SIZE - MAGIC_SIZE, err, err_info)) return WTAP_OPEN_ERROR; /* This is an nettl file */ wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_NETTL; nettl = g_new(nettl_t,1); wth->priv = (void *)nettl; if (file_hdr.os_vers[2] == '1' && file_hdr.os_vers[3] == '1') nettl->is_hpux_11 = TRUE; else nettl->is_hpux_11 = FALSE; wth->subtype_read = nettl_read; wth->subtype_seek_read = nettl_seek_read; wth->snapshot_length = 0; /* not available */ /* read the first header to take a guess at the file encap */ if (!wtap_read_bytes_or_eof(wth->fh, dummy, 4, err, err_info)) { if (*err == 0) { /* EOF, so no records */ return WTAP_OPEN_NOT_MINE; } return WTAP_OPEN_ERROR; } subsys = g_ntohs(dummy[1]); switch (subsys) { case NETTL_SUBSYS_HPPB_FDDI : case NETTL_SUBSYS_EISA_FDDI : case NETTL_SUBSYS_PCI_FDDI : case NETTL_SUBSYS_HSC_FDDI : wth->file_encap = WTAP_ENCAP_NETTL_FDDI; break; case NETTL_SUBSYS_TOKEN : case NETTL_SUBSYS_PCI_TR : wth->file_encap = WTAP_ENCAP_NETTL_TOKEN_RING; break; 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_NS_LS_IPV6 : wth->file_encap = WTAP_ENCAP_NETTL_RAW_IP; break; case NETTL_SUBSYS_NS_LS_ICMP : wth->file_encap = WTAP_ENCAP_NETTL_RAW_ICMP; break; case NETTL_SUBSYS_NS_LS_ICMPV6 : wth->file_encap = WTAP_ENCAP_NETTL_RAW_ICMPV6; break; case NETTL_SUBSYS_NS_LS_TELNET : wth->file_encap = WTAP_ENCAP_NETTL_RAW_TELNET; break; default: /* If this assumption is bad, the read will catch it */ wth->file_encap = WTAP_ENCAP_NETTL_ETHERNET; } if (file_seek(wth->fh, FILE_HDR_SIZE, SEEK_SET, err) == -1) { return WTAP_OPEN_ERROR; } wth->file_tsprec = WTAP_TSPREC_USEC; return WTAP_OPEN_MINE; }
static int peekclassic_read_packet_v7(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { guint8 ep_pkt[PEEKCLASSIC_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; guint8 radio_info[RADIO_INFO_SIZE]; if (!wtap_read_bytes_or_eof(fh, ep_pkt, sizeof(ep_pkt), err, err_info)) return -1; /* Extract the fields from the packet */ #if 0 protoNum = pntoh16(&ep_pkt[PEEKCLASSIC_V7_PROTONUM_OFFSET]); #endif length = pntoh16(&ep_pkt[PEEKCLASSIC_V7_LENGTH_OFFSET]); sliceLength = pntoh16(&ep_pkt[PEEKCLASSIC_V7_SLICE_LENGTH_OFFSET]); #if 0 flags = ep_pkt[PEEKCLASSIC_V7_FLAGS_OFFSET]; #endif status = ep_pkt[PEEKCLASSIC_V7_STATUS_OFFSET]; timestamp = pntoh64(&ep_pkt[PEEKCLASSIC_V7_TIMESTAMP_OFFSET]); /* force sliceLength to be the actual length of the packet */ if (0 == sliceLength) { sliceLength = length; } /* * The maximum value of sliceLength and length are 65535, which * are less than WTAP_MAX_PACKET_SIZE_STANDARD will ever be, so we don't * need to check them. */ /* fill in packet header values */ phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; tsecs = (time_t) (timestamp/1000000); tusecs = (guint32) (timestamp - tsecs*1000000); phdr->ts.secs = tsecs - mac2unix; phdr->ts.nsecs = tusecs * 1000; phdr->len = length; phdr->caplen = sliceLength; switch (wth->file_encap) { case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: memset(&phdr->pseudo_header.ieee_802_11, 0, sizeof(phdr->pseudo_header.ieee_802_11)); phdr->pseudo_header.ieee_802_11.fcs_len = 0; /* no FCS */ phdr->pseudo_header.ieee_802_11.decrypted = FALSE; phdr->pseudo_header.ieee_802_11.datapad = FALSE; phdr->pseudo_header.ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN; /* * Now process the radio information pseudo-header. * It's a 4-byte pseudo-header, consisting of: * * 1 byte of data rate, in units of 500 kb/s; * * 1 byte of channel number; * * 1 byte of signal strength as a percentage of * the maximum, i.e. (RXVECTOR RSSI/RXVECTOR RSSI_Max)*100, * or, at least, that's what I infer it is, given what * the WildPackets note "Converting Signal Strength * Percentage to dBm Values" says (it also says that * the conversion the percentage to a dBm value is * an adapter-dependent process, so, as we don't know * what type of adapter was used to do the capture, * we can't do the conversion); * * 1 byte of unknown content (padding?). */ if (phdr->len < RADIO_INFO_SIZE || phdr->caplen < RADIO_INFO_SIZE) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("peekclassic: 802.11 packet has length < 4"); return -1; } phdr->len -= RADIO_INFO_SIZE; phdr->caplen -= RADIO_INFO_SIZE; sliceLength -= RADIO_INFO_SIZE; /* read the pseudo-header */ if (!wtap_read_bytes(fh, radio_info, RADIO_INFO_SIZE, err, err_info)) return -1; phdr->pseudo_header.ieee_802_11.has_data_rate = TRUE; phdr->pseudo_header.ieee_802_11.data_rate = radio_info[0]; phdr->pseudo_header.ieee_802_11.has_channel = TRUE; phdr->pseudo_header.ieee_802_11.channel = radio_info[1]; phdr->pseudo_header.ieee_802_11.has_signal_percent = TRUE; phdr->pseudo_header.ieee_802_11.signal_percent = radio_info[2]; /* * 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. */ if (phdr->len < 4 || phdr->caplen < 4) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("peekclassic: 802.11 packet has length < 8"); return -1; } phdr->len -= 4; phdr->caplen -= 4; 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. */ phdr->pseudo_header.eth.fcs_len = (status & 0x01) ? 0 : 4; break; } /* read the packet data */ if (!wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info)) return -1; return sliceLength; }
static gboolean nettl_read_rec(wtap *wth, FILE_T fh, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info) { union wtap_pseudo_header *pseudo_header = &rec->rec_header.packet_header.pseudo_header; nettl_t *nettl = (nettl_t *)wth->priv; gboolean fddihack = FALSE; 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; if (!wtap_read_bytes_or_eof(fh, &rec_hdr.hdr_len, sizeof rec_hdr.hdr_len, err, err_info)) 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; } if (!wtap_read_bytes(fh, &rec_hdr.subsys, NETTL_REC_HDR_LEN - 2, err, err_info)) return FALSE; subsys = g_ntohs(rec_hdr.subsys); hdr_len -= NETTL_REC_HDR_LEN; /* Skip the rest of the header. */ if (!wtap_read_bytes(fh, NULL, hdr_len, err, err_info)) return FALSE; if ( (pntoh32(&rec_hdr.kind) & NETTL_HDR_PDU_MASK) == 0 ) { /* not actually a data packet (PDU) trace record */ rec->rec_header.packet_header.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)) { rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_RAW_IP; } else if (subsys == NETTL_SUBSYS_NS_LS_ICMP) { rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMP; } else if (subsys == NETTL_SUBSYS_NS_LS_ICMPV6) { rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMPV6; } else if (subsys == NETTL_SUBSYS_NS_LS_TELNET) { rec->rec_header.packet_header.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) ) { rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_FDDI; } else if( (subsys == NETTL_SUBSYS_PCI_TR) || (subsys == NETTL_SUBSYS_TOKEN) ) { rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_TOKEN_RING; } else { rec->rec_header.packet_header.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 */ if (!wtap_read_bytes(fh, dummyc, 9, err, err_info)) return FALSE; /* padding is usually either a total 11 or 16 bytes??? */ padlen = (int)dummyc[8]; if (!wtap_read_bytes(fh, NULL, padlen, err, err_info)) 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 (!wtap_read_bytes(fh, NULL, 3, err, err_info)) return FALSE; padlen = 3; } else if (subsys == NETTL_SUBSYS_NS_LS_LOOPBACK) { /* LOOPBACK has an extra 26 bytes of padding */ if (!wtap_read_bytes(fh, NULL, 26, err, err_info)) 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 (!wtap_read_bytes(fh, NULL, 8, err, err_info)) return FALSE; padlen = 8; } else { padlen = 0; } break; case NETTL_SUBSYS_NS_LS_DRIVER : /* XXX we don't know how to identify this as ethernet frames, so we assume everything is. We will crash and burn for anything else */ /* for encapsulated 100baseT we do this */ rec->rec_header.packet_header.pkt_encap = WTAP_ENCAP_NETTL_ETHERNET; if (!wtap_read_bytes(fh, &drv_eth_hdr, NS_LS_DRV_ETH_HDR_LEN, err, err_info)) 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 (!wtap_read_bytes(fh, NULL, 2, err, err_info)) 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? */ rec->rec_header.packet_header.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 (!wtap_read_bytes(fh, NULL, padlen, err, err_info)) 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; rec->rec_header.packet_header.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; } rec->rec_type = REC_TYPE_PACKET; rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; rec->rec_header.packet_header.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; rec->rec_header.packet_header.caplen = datalen; rec->ts.secs = pntoh32(&rec_hdr.sec); rec->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 (rec->rec_header.packet_header.caplen > WTAP_MAX_PACKET_SIZE_STANDARD) { /* * 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", rec->rec_header.packet_header.caplen, WTAP_MAX_PACKET_SIZE_STANDARD); return FALSE; } /* * Read the packet data. */ ws_buffer_assure_space(buf, datalen); pd = ws_buffer_start_ptr(buf); if (fddihack) { /* read in FC, dest, src, DSAP and SSAP */ bytes_to_read = 15; if (bytes_to_read > datalen) bytes_to_read = datalen; if (!wtap_read_bytes(fh, pd, bytes_to_read, err, err_info)) return FALSE; datalen -= bytes_to_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; if (!wtap_read_bytes(fh, NULL, bytes_to_read, err, err_info)) return FALSE; datalen -= bytes_to_read; if (datalen == 0) { /* There's nothing past the FC, dest, src, DSAP, SSAP, and 3 bytes to eat */ return TRUE; } } if (!wtap_read_bytes(fh, pd + 15, datalen, err, err_info)) return FALSE; } else { if (!wtap_read_bytes(fh, pd, datalen, err, err_info)) return FALSE; } return TRUE; }
static gboolean stanag4607_read_file(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { stanag4607_t *stanag4607 = (stanag4607_t *)wth->priv; guint32 millisecs, secs, nsecs; gint64 offset = 0; guint8 stanag_pkt_hdr[37]; guint32 packet_size; *err = 0; /* Combined packet header and segment header */ if (!wtap_read_bytes_or_eof(fh, stanag_pkt_hdr, sizeof stanag_pkt_hdr, err, err_info)) return FALSE; offset += sizeof stanag_pkt_hdr; if (!is_valid_id(pntoh16(&stanag_pkt_hdr[0]))) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("Bad version number"); return FALSE; } phdr->rec_type = REC_TYPE_PACKET; /* The next 4 bytes are the packet length */ packet_size = pntoh32(&stanag_pkt_hdr[2]); phdr->caplen = packet_size; phdr->len = packet_size; /* Sadly, the header doesn't contain times; but some segments do */ /* So, get the segment header, which is just past the 32-byte header. */ phdr->presence_flags = WTAP_HAS_TS; /* If no time specified, it's the last baseline time */ phdr->ts.secs = stanag4607->base_secs; phdr->ts.nsecs = 0; millisecs = 0; #define MISSION_SEGMENT 1 #define DWELL_SEGMENT 2 #define JOB_DEFINITION_SEGMENT 5 #define PLATFORM_LOCATION_SEGMENT 13 if (MISSION_SEGMENT == stanag_pkt_hdr[32]) { guint8 mseg[39]; struct tm tm; if (!wtap_read_bytes(fh, &mseg, sizeof mseg, err, err_info)) return FALSE; offset += sizeof mseg; tm.tm_year = pntoh16(&mseg[35]) - 1900; tm.tm_mon = mseg[37] - 1; tm.tm_mday = mseg[38]; tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = -1; stanag4607->base_secs = mktime(&tm); phdr->ts.secs = stanag4607->base_secs; } else if (PLATFORM_LOCATION_SEGMENT == stanag_pkt_hdr[32]) { if (!wtap_read_bytes(fh, &millisecs, sizeof millisecs, err, err_info)) return FALSE; offset += sizeof millisecs; millisecs = g_ntohl(millisecs); } else if (DWELL_SEGMENT == stanag_pkt_hdr[32]) { guint8 dseg[19]; if (!wtap_read_bytes(fh, &dseg, sizeof dseg, err, err_info)) return FALSE; offset += sizeof dseg; millisecs = pntoh32(&dseg[15]); } if (0 != millisecs) { secs = millisecs/1000; nsecs = (millisecs - 1000 * secs) * 1000000; phdr->ts.secs = stanag4607->base_secs + secs; phdr->ts.nsecs = nsecs; } /* wind back to the start of the packet ... */ if (file_seek(fh, - offset, SEEK_CUR, err) == -1) return FALSE; return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info); }
wtap_open_return_val network_instruments_open(wtap *wth, int *err, gchar **err_info) { guint offset; capture_file_header file_header; guint header_offset; guint i; tlv_header tlvh; guint seek_increment; packet_entry_header packet_header; observer_dump_private_state * private_state = NULL; offset = 0; /* read in the buffer file header */ if (!wtap_read_bytes(wth->fh, &file_header, sizeof file_header, err, err_info)) { if (*err != WTAP_ERR_SHORT_READ) return WTAP_OPEN_ERROR; return WTAP_OPEN_NOT_MINE; } offset += (guint)sizeof file_header; CAPTURE_FILE_HEADER_FROM_LE_IN_PLACE(file_header); /* check if version info is present */ if (memcmp(file_header.observer_version, network_instruments_magic, true_magic_length)!=0) { return WTAP_OPEN_NOT_MINE; } /* get the location of the first packet */ /* v15 and newer uses high byte offset, in previous versions it will be 0 */ header_offset = file_header.offset_to_first_packet + ((guint)(file_header.offset_to_first_packet_high_byte)<<16); if (offset > header_offset) { /* * The packet data begins before the file header ends. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("Observer: The first packet begins in the middle of the file header"); return WTAP_OPEN_ERROR; } /* initialize the private state */ private_state = (observer_dump_private_state *) g_malloc(sizeof(observer_dump_private_state)); private_state->time_format = TIME_INFO_LOCAL; wth->priv = (void *) private_state; /* process extra information */ for (i = 0; i < file_header.number_of_information_elements; i++) { guint tlv_data_length; /* * Make sure reading the TLV header won't put us in the middle * of the packet data. */ if (offset + (guint)sizeof tlvh > header_offset) { /* * We're at or past the point where the packet data begins, * but we have the IE header to read. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("Observer: TLVs run into the first packet data"); return WTAP_OPEN_ERROR; } /* read the TLV header */ if (!wtap_read_bytes(wth->fh, &tlvh, sizeof tlvh, err, err_info)) return WTAP_OPEN_ERROR; offset += (guint)sizeof tlvh; TLV_HEADER_FROM_LE_IN_PLACE(tlvh); if (tlvh.length < sizeof tlvh) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("Observer: bad record (TLV length %u < %lu)", tlvh.length, (unsigned long)sizeof tlvh); return WTAP_OPEN_ERROR; } tlv_data_length = tlvh.length - (guint)sizeof tlvh; /* * Make sure reading the TLV data won't put us in the middle * of the packet data. */ if (offset + tlv_data_length > header_offset) { /* * We're at or past the point where the packet data begins, * but we have the IE data to read. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("Observer: TLVs run into the first packet data"); return WTAP_OPEN_ERROR; } /* process (or skip over) the current TLV */ switch (tlvh.type) { case INFORMATION_TYPE_TIME_INFO: if (tlvh.length != sizeof tlvh + sizeof private_state->time_format) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("Observer: bad record (time information TLV length %u != %lu)", tlvh.length, (unsigned long)(sizeof tlvh + sizeof private_state->time_format)); return WTAP_OPEN_ERROR; } if (!wtap_read_bytes(wth->fh, &private_state->time_format, sizeof private_state->time_format, err, err_info)) return WTAP_OPEN_ERROR; private_state->time_format = GUINT32_FROM_LE(private_state->time_format); offset += (guint)sizeof private_state->time_format; break; default: tlv_data_length = tlvh.length - (guint)sizeof tlvh; if (tlv_data_length > 0) { if (!wtap_read_bytes(wth->fh, NULL, tlv_data_length, err, err_info)) return WTAP_OPEN_ERROR; } offset += tlv_data_length; } } /* get to the first packet */ seek_increment = header_offset - offset; if (seek_increment != 0) { if (!wtap_read_bytes(wth->fh, NULL, seek_increment, err, err_info)) return WTAP_OPEN_ERROR; } /* * We assume that all packets in a file have the same network type, * whether they're data or expert information packets, and thus * we can attempt to determine the network type by reading the * first packet. * * If that's *not* the case, we need to use WTAP_ENCAP_PER_PACKET. * * Read the packet header. Don't assume there *is* a packet; * if there isn't, report that as a bad file. (If we use * WTAP_ENCAP_PER_PACKET, we don't need to handle that case, as * we don't need to read the first packet. */ if (!wtap_read_bytes_or_eof(wth->fh, &packet_header, sizeof packet_header, err, err_info)) { if (*err == 0) { /* * EOF, so there *are* no records. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("Observer: No records in the file, so we can't determine the link-layer type"); } return WTAP_OPEN_ERROR; } PACKET_ENTRY_HEADER_FROM_LE_IN_PLACE(packet_header); /* check the packet's magic number */ if (packet_header.packet_magic != observer_packet_magic) { *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("Observer: unsupported packet version %ul", packet_header.packet_magic); return WTAP_OPEN_ERROR; } /* check the data link type */ if (observer_to_wtap_encap(packet_header.network_type) == WTAP_ENCAP_UNKNOWN) { *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("Observer: network type %u unknown or unsupported", packet_header.network_type); return WTAP_OPEN_ERROR; } wth->file_encap = observer_to_wtap_encap(packet_header.network_type); /* set up the rest of the capture parameters */ private_state->packet_count = 0; private_state->network_type = wtap_to_observer_encap(wth->file_encap); wth->subtype_read = observer_read; wth->subtype_seek_read = observer_seek_read; wth->subtype_close = NULL; wth->subtype_sequential_close = NULL; wth->snapshot_length = 0; /* not available in header */ wth->file_tsprec = WTAP_TSPREC_NSEC; wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_NETWORK_INSTRUMENTS; /* reset the pointer to the first packet */ if (file_seek(wth->fh, header_offset, SEEK_SET, err) == -1) return WTAP_OPEN_ERROR; if (init_gmt_to_localtime_offset() != NULL) { *err = WTAP_ERR_INTERNAL; /* * XXX - we should return the error string, so the caller * can report the details of the internal error, but that * would require plugin file readers to do so for internal * errors as well, which could break binary compatibility; * we'll do that in the next release. */ return WTAP_OPEN_ERROR; } return WTAP_OPEN_MINE; }
static gboolean i4b_read_rec(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { i4btrace_t *i4btrace = (i4btrace_t *)wth->priv; i4b_trace_hdr_t hdr; guint32 length; if (!wtap_read_bytes_or_eof(fh, &hdr, sizeof hdr, err, err_info)) return FALSE; if (i4btrace->byte_swapped) { /* * Byte-swap the header. */ hdr.length = GUINT32_SWAP_LE_BE(hdr.length); hdr.unit = GUINT32_SWAP_LE_BE(hdr.unit); hdr.type = GUINT32_SWAP_LE_BE(hdr.type); hdr.dir = GUINT32_SWAP_LE_BE(hdr.dir); hdr.trunc = GUINT32_SWAP_LE_BE(hdr.trunc); hdr.count = GUINT32_SWAP_LE_BE(hdr.count); hdr.ts_sec = GUINT32_SWAP_LE_BE(hdr.ts_sec); hdr.ts_usec = GUINT32_SWAP_LE_BE(hdr.ts_usec); } if (hdr.length < sizeof(hdr)) { *err = WTAP_ERR_BAD_FILE; /* record length < header! */ *err_info = g_strdup_printf("i4btrace: record length %u < header length %lu", hdr.length, (unsigned long)sizeof(hdr)); return FALSE; } length = hdr.length - (guint32)sizeof(hdr); if (length > WTAP_MAX_PACKET_SIZE_STANDARD) { /* * 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("i4btrace: File has %u-byte packet, bigger than maximum of %u", length, WTAP_MAX_PACKET_SIZE_STANDARD); return FALSE; } phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS; phdr->len = length; phdr->caplen = length; phdr->ts.secs = hdr.ts_sec; phdr->ts.nsecs = hdr.ts_usec * 1000; switch (hdr.type) { case TRC_CH_I: /* * XXX - what is it? It's probably not WTAP_ENCAP_NULL, * as that means it has a 4-byte AF_ type as the * encapsulation header. */ phdr->pkt_encap = WTAP_ENCAP_NULL; break; case TRC_CH_D: /* * D channel, so it's LAPD; set "p2p.sent". */ phdr->pkt_encap = WTAP_ENCAP_ISDN; phdr->pseudo_header.isdn.channel = 0; break; case TRC_CH_B1: /* * B channel 1. */ phdr->pkt_encap = WTAP_ENCAP_ISDN; phdr->pseudo_header.isdn.channel = 1; break; case TRC_CH_B2: /* * B channel 2. */ phdr->pkt_encap = WTAP_ENCAP_ISDN; phdr->pseudo_header.isdn.channel = 2; break; } phdr->pseudo_header.isdn.uton = (hdr.dir == FROM_TE); /* * Read the packet data. */ return wtap_read_packet_bytes(fh, buf, length, err, err_info); }
static int peekclassic_read_packet_v7(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { guint8 ep_pkt[PEEKCLASSIC_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; if (!wtap_read_bytes_or_eof(fh, ep_pkt, sizeof(ep_pkt), err, err_info)) return -1; /* Extract the fields from the packet */ #if 0 protoNum = pntoh16(&ep_pkt[PEEKCLASSIC_V7_PROTONUM_OFFSET]); #endif length = pntoh16(&ep_pkt[PEEKCLASSIC_V7_LENGTH_OFFSET]); sliceLength = pntoh16(&ep_pkt[PEEKCLASSIC_V7_SLICE_LENGTH_OFFSET]); #if 0 flags = ep_pkt[PEEKCLASSIC_V7_FLAGS_OFFSET]; #endif status = ep_pkt[PEEKCLASSIC_V7_STATUS_OFFSET]; timestamp = pntoh64(&ep_pkt[PEEKCLASSIC_V7_TIMESTAMP_OFFSET]); /* force sliceLength to be the actual length of the packet */ if (0 == sliceLength) { sliceLength = length; } /* fill in packet header values */ phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; tsecs = (time_t) (timestamp/1000000); tusecs = (guint32) (timestamp - tsecs*1000000); phdr->ts.secs = tsecs - mac2unix; phdr->ts.nsecs = tusecs * 1000; phdr->len = length; phdr->caplen = sliceLength; switch (wth->file_encap) { case WTAP_ENCAP_IEEE_802_11_AIROPEEK: phdr->pseudo_header.ieee_802_11.fcs_len = 0; /* no FCS */ phdr->pseudo_header.ieee_802_11.decrypted = FALSE; phdr->pseudo_header.ieee_802_11.datapad = FALSE; phdr->pseudo_header.ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN; phdr->pseudo_header.ieee_802_11.presence_flags = 0; /* not present */ /* * 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. */ if (phdr->len < 4 || phdr->caplen < 4) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("peekclassic: 802.11 packet has length < 4"); return -1; } phdr->len -= 4; phdr->caplen -= 4; 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. */ phdr->pseudo_header.eth.fcs_len = (status & 0x01) ? 0 : 4; break; } /* read the packet data */ if (!wtap_read_packet_bytes(fh, buf, phdr->caplen, err, err_info)) return -1; return sliceLength; }
wtap_open_return_val lanalyzer_open(wtap *wth, int *err, gchar **err_info) { LA_RecordHeader rec_header; char header_fixed[2]; char *comment; char summary[210]; guint16 board_type, mxslc; guint16 record_type, record_length; guint8 cr_day, cr_month; guint16 cr_year; struct tm tm; lanalyzer_t *lanalyzer; if (!wtap_read_bytes(wth->fh, &rec_header, LA_RecordHeaderSize, err, err_info)) { if (*err != WTAP_ERR_SHORT_READ) return WTAP_OPEN_ERROR; return WTAP_OPEN_NOT_MINE; } record_type = pletoh16(rec_header.record_type); record_length = pletoh16(rec_header.record_length); /* make sure to do this for while() loop */ if (record_type != RT_HeaderRegular && record_type != RT_HeaderCyclic) { return WTAP_OPEN_NOT_MINE; } /* Read the major and minor version numbers */ if (record_length < 2) { /* * Not enough room for the major and minor version numbers. * Just treat that as a "not a LANalyzer file" indication. */ return WTAP_OPEN_NOT_MINE; } if (!wtap_read_bytes(wth->fh, &header_fixed, sizeof header_fixed, err, err_info)) { if (*err != WTAP_ERR_SHORT_READ) return WTAP_OPEN_ERROR; return WTAP_OPEN_NOT_MINE; } record_length -= sizeof header_fixed; if (record_length != 0) { /* Read the rest of the record as a comment. */ comment = (char *)g_malloc(record_length + 1); if (!wtap_read_bytes(wth->fh, comment, record_length, err, err_info)) { if (*err != WTAP_ERR_SHORT_READ) { g_free(comment); return WTAP_OPEN_ERROR; } g_free(comment); return WTAP_OPEN_NOT_MINE; } wtap_optionblock_set_option_string(g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0), OPT_COMMENT, comment, record_length); g_free(comment); } /* If we made it this far, then the file is a LANAlyzer file. * Let's get some info from it. Note that we get wth->snapshot_length * from a record later in the file. */ wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_LANALYZER; lanalyzer = (lanalyzer_t *)g_malloc(sizeof(lanalyzer_t)); wth->priv = (void *)lanalyzer; wth->subtype_read = lanalyzer_read; wth->subtype_seek_read = lanalyzer_seek_read; wth->snapshot_length = 0; wth->file_tsprec = WTAP_TSPREC_NSEC; /* Read records until we find the start of packets */ while (1) { if (!wtap_read_bytes_or_eof(wth->fh, &rec_header, LA_RecordHeaderSize, err, err_info)) { if (*err == 0) { /* * End of file and no packets; * accept this file. */ return WTAP_OPEN_MINE; } return WTAP_OPEN_ERROR; } record_type = pletoh16(rec_header.record_type); record_length = pletoh16(rec_header.record_length); /*g_message("Record 0x%04X Length %d", record_type, record_length);*/ switch (record_type) { /* Trace Summary Record */ case RT_Summary: if (!wtap_read_bytes(wth->fh, summary, sizeof summary, err, err_info)) return WTAP_OPEN_ERROR; /* Assume that the date of the creation of the trace file * is the same date of the trace. Lanalyzer doesn't * store the creation date/time of the trace, but only of * the file. Unless you traced at 11:55 PM and saved at 00:05 * AM, the assumption that trace.date == file.date is true. */ cr_day = summary[0]; cr_month = summary[1]; cr_year = pletoh16(&summary[2]); /*g_message("Day %d Month %d Year %d (%04X)", cr_day, cr_month, cr_year, cr_year);*/ /* Get capture start time. I learned how to do * this from Guy's code in ngsniffer.c */ tm.tm_year = cr_year - 1900; tm.tm_mon = cr_month - 1; tm.tm_mday = cr_day; tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = -1; lanalyzer->start = mktime(&tm); /*g_message("Day %d Month %d Year %d", tm.tm_mday, tm.tm_mon, tm.tm_year);*/ mxslc = pletoh16(&summary[30]); wth->snapshot_length = mxslc; board_type = pletoh16(&summary[188]); switch (board_type) { case BOARD_325: wth->file_encap = WTAP_ENCAP_ETHERNET; break; case BOARD_325TR: wth->file_encap = WTAP_ENCAP_TOKEN_RING; break; default: *err = WTAP_ERR_UNSUPPORTED; *err_info = g_strdup_printf("lanalyzer: board type %u unknown", board_type); return WTAP_OPEN_ERROR; } break; /* Trace Packet Data Record */ case RT_PacketData: /* Go back header number of bytes so that lanalyzer_read * can read this header */ if (file_seek(wth->fh, -LA_RecordHeaderSize, SEEK_CUR, err) == -1) { return WTAP_OPEN_ERROR; } return WTAP_OPEN_MINE; default: if (file_seek(wth->fh, record_length, SEEK_CUR, err) == -1) { return WTAP_OPEN_ERROR; } break; } } }
static gboolean peekclassic_read_packet_v56(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { peekclassic_t *peekclassic = (peekclassic_t *)wth->priv; guint8 ep_pkt[PEEKCLASSIC_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; #if 0 char protoStr[8]; #endif unsigned int i; if (!wtap_read_bytes_or_eof(fh, ep_pkt, sizeof(ep_pkt), err, err_info)) return FALSE; /* Extract the fields from the packet */ length = pntoh16(&ep_pkt[PEEKCLASSIC_V56_LENGTH_OFFSET]); sliceLength = pntoh16(&ep_pkt[PEEKCLASSIC_V56_SLICE_LENGTH_OFFSET]); #if 0 flags = ep_pkt[PEEKCLASSIC_V56_FLAGS_OFFSET]; status = ep_pkt[PEEKCLASSIC_V56_STATUS_OFFSET]; #endif timestamp = pntoh32(&ep_pkt[PEEKCLASSIC_V56_TIMESTAMP_OFFSET]); #if 0 destNum = pntoh16(&ep_pkt[PEEKCLASSIC_V56_DESTNUM_OFFSET]); srcNum = pntoh16(&ep_pkt[PEEKCLASSIC_V56_SRCNUM_OFFSET]); #endif protoNum = pntoh16(&ep_pkt[PEEKCLASSIC_V56_PROTONUM_OFFSET]); #if 0 memcpy(protoStr, &ep_pkt[PEEKCLASSIC_V56_PROTOSTR_OFFSET], sizeof protoStr); #endif /* * 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; } /* fill in packet header values */ phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; /* timestamp is in milliseconds since reference_time */ phdr->ts.secs = peekclassic->reference_time + (timestamp / 1000); phdr->ts.nsecs = 1000 * (timestamp % 1000) * 1000; phdr->len = length; phdr->caplen = sliceLength; phdr->pkt_encap = WTAP_ENCAP_UNKNOWN; for (i=0; i<NUM_PEEKCLASSIC_ENCAPS; i++) { if (peekclassic_encap[i].protoNum == protoNum) { phdr->pkt_encap = peekclassic_encap[i].encap; } } switch (phdr->pkt_encap) { case WTAP_ENCAP_ETHERNET: /* We assume there's no FCS in this frame. */ phdr->pseudo_header.eth.fcs_len = 0; break; } /* read the packet data */ return wtap_read_packet_bytes(fh, buf, sliceLength, err, err_info); }
static int read_packet_header(wtap *wth, FILE_T fh, union wtap_pseudo_header *pseudo_header, packet_entry_header *packet_header, int *err, gchar **err_info) { int offset; guint i; tlv_header tlvh; int seek_increment; tlv_wireless_info wireless_header; offset = 0; /* pull off the packet header */ if (!wtap_read_bytes_or_eof(fh, packet_header, sizeof *packet_header, err, err_info)) { if (*err != 0) return -1; return 0; /* EOF */ } offset += (int)sizeof *packet_header; PACKET_ENTRY_HEADER_FROM_LE_IN_PLACE(*packet_header); /* check the packet's magic number */ if (packet_header->packet_magic != observer_packet_magic) { /* * Some files are zero-padded at the end. There is no warning of this * in the previous packet header information, such as setting * offset_to_next_packet to zero. So detect this situation by treating * an all-zero header as a sentinel. Return EOF when it is encountered, * rather than treat it as a bad record. */ for (i = 0; i < sizeof *packet_header; i++) { if (((guint8*) packet_header)[i] != 0) break; } if (i == sizeof *packet_header) { *err = 0; return 0; /* EOF */ } *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("Observer: bad record: Invalid magic number 0x%08x", packet_header->packet_magic); return -1; } /* initialize the pseudo header */ switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* There is no FCS in the frame */ pseudo_header->eth.fcs_len = 0; break; case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: memset(&pseudo_header->ieee_802_11, 0, sizeof(pseudo_header->ieee_802_11)); pseudo_header->ieee_802_11.fcs_len = 0; pseudo_header->ieee_802_11.decrypted = FALSE; pseudo_header->ieee_802_11.datapad = FALSE; pseudo_header->ieee_802_11.phy = PHDR_802_11_PHY_UNKNOWN; /* Updated below */ break; } /* process extra information */ for (i = 0; i < packet_header->number_of_information_elements; i++) { /* read the TLV header */ if (!wtap_read_bytes(fh, &tlvh, sizeof tlvh, err, err_info)) return -1; offset += (int)sizeof tlvh; TLV_HEADER_FROM_LE_IN_PLACE(tlvh); if (tlvh.length < sizeof tlvh) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("Observer: bad record (TLV length %u < %lu)", tlvh.length, (unsigned long)sizeof tlvh); return -1; } /* process (or skip over) the current TLV */ switch (tlvh.type) { case INFORMATION_TYPE_WIRELESS: if (!wtap_read_bytes(fh, &wireless_header, sizeof wireless_header, err, err_info)) return -1; /* set decryption status */ /* XXX - what other bits are there in conditions? */ pseudo_header->ieee_802_11.decrypted = (wireless_header.conditions & WIRELESS_WEP_SUCCESS) != 0; pseudo_header->ieee_802_11.has_channel = TRUE; pseudo_header->ieee_802_11.channel = wireless_header.frequency; pseudo_header->ieee_802_11.has_data_rate = TRUE; pseudo_header->ieee_802_11.data_rate = wireless_header.rate; pseudo_header->ieee_802_11.has_signal_percent = TRUE; pseudo_header->ieee_802_11.signal_percent = wireless_header.strengthPercent; offset += (int)sizeof wireless_header; break; default: /* skip the TLV data */ seek_increment = tlvh.length - (int)sizeof tlvh; if (seek_increment > 0) { if (file_seek(fh, seek_increment, SEEK_CUR, err) == -1) return -1; } offset += seek_increment; } } return offset; }
static int capsa_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { capsa_t *capsa = (capsa_t *)wth->priv; struct capsarec_hdr capsarec_hdr; struct pbrec_hdr pbrec_hdr; guint32 rec_size; guint32 packet_size; guint32 orig_size; guint32 header_size; #if 0 guint64 timestamp; #endif /* Read record header. */ switch (capsa->format_indicator) { case 1: if (!wtap_read_bytes_or_eof(fh, &capsarec_hdr, sizeof capsarec_hdr, err, err_info)) return -1; rec_size = GUINT16_FROM_LE(capsarec_hdr.rec_len); orig_size = GUINT16_FROM_LE(capsarec_hdr.orig_len); packet_size = GUINT16_FROM_LE(capsarec_hdr.incl_len); header_size = sizeof capsarec_hdr; #if 0 timestamp = (((guint64)GUINT32_FROM_LE(capsarec_hdr.timestamphi))<<32) + GUINT32_FROM_LE(capsarec_hdr.timestamplo); /* * XXX - this is not the correct time origin. */ timestamp -= G_GUINT64_CONSTANT(11644473600); #endif /* * OK, the rest of this is variable-length. * We skip: (count1+count2)*4 bytes. * XXX - what is that? Measured statistics? * Calculated statistics? */ if (!file_skip(fh, (capsarec_hdr.count1 + capsarec_hdr.count2)*4, err)) return -1; header_size += (capsarec_hdr.count1 + capsarec_hdr.count2)*4; break; case 2: if (!wtap_read_bytes_or_eof(fh, &pbrec_hdr, sizeof pbrec_hdr, err, err_info)) return -1; rec_size = GUINT16_FROM_LE(pbrec_hdr.rec_len); orig_size = GUINT16_FROM_LE(pbrec_hdr.orig_len); packet_size = GUINT16_FROM_LE(pbrec_hdr.incl_len); header_size = sizeof pbrec_hdr; #if 0 timestamp = (((guint64)GUINT32_FROM_LE(pbrec_hdr.timestamphi))<<32) + GUINT32_FROM_LE(pbrec_hdr.timestamplo); /* * XXX - from the results of some conversions between * Capsa format and pcap by Colasoft Packet Builder, * I do not trust its conversion of time stamps (at * least one of Colasoft's sample files, when * converted to pcap format, has, as its time stamps, * time stamps on the day after the conversion was * done, which seems like more than just coincidence). */ timestamp -= G_GUINT64_CONSTANT(485946753291483); #endif break; default: g_assert_not_reached(); *err = WTAP_ERR_INTERNAL; return -1; } 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("capsa: 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("capsa: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return -1; } if (header_size + packet_size > rec_size) { /* * Probably a corrupt capture file. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("capsa: File has %u-byte packet with %u-byte record header, bigger than record size %u", packet_size, header_size, rec_size); return -1; } /* * The "on the wire" record size always includes the CRC. * If it's greater than the "captured" size by 4, then * we subtract 4 from it, to reflect the way the "on the wire" * record size works for other file formats. */ if (orig_size == packet_size + 4) orig_size = packet_size; /* * We assume there's no FCS in this frame. * XXX - is there ever one? */ phdr->pseudo_header.eth.fcs_len = 0; phdr->rec_type = REC_TYPE_PACKET; phdr->caplen = packet_size; phdr->len = orig_size; #if 0 phdr->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_TS; phdr->ts.secs = (time_t)(timestamp / 1000000); phdr->ts.nsecs = ((int)(timestamp % 1000000))*1000; #else phdr->presence_flags = WTAP_HAS_CAP_LEN; #endif /* * Read the packet data. */ if (!wtap_read_packet_bytes(fh, buf, packet_size, err, err_info)) return -1; /* failed */ return rec_size - (header_size + packet_size); }