void sna_fid_to_str_buf(const address *addr, gchar *buf, int buf_len) { const guint8 *addrdata; struct sna_fid_type_4_addr sna_fid_type_4_addr; switch (addr->len) { case 1: addrdata = (guint8 *)addr->data; g_snprintf(buf, buf_len, "%04X", addrdata[0]); break; case 2: addrdata = (guint8 *)addr->data; g_snprintf(buf, buf_len, "%04X", pntoh16(&addrdata[0])); break; case SNA_FID_TYPE_4_ADDR_LEN: /* FID Type 4 */ memcpy(&sna_fid_type_4_addr, addr->data, SNA_FID_TYPE_4_ADDR_LEN); g_snprintf(buf, buf_len, "%08X.%04X", sna_fid_type_4_addr.saf, sna_fid_type_4_addr.ef); break; } }
static gboolean capture_chdlc( const guchar *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header) { if (!BYTES_ARE_IN_FRAME(offset, len, 4)) return FALSE; switch (pntoh16(&pd[offset + 2])) { case ETHERTYPE_IP: return call_capture_dissector(ip_cap_handle, pd, offset + 4, len, cpinfo, pseudo_header); } return FALSE; }
void capture_chdlc( const guchar *pd, int offset, int len, packet_counts *ld ) { if (!BYTES_ARE_IN_FRAME(offset, len, 4)) { ld->other++; return; } switch (pntoh16(&pd[offset + 2])) { case ETHERTYPE_IP: capture_ip(pd, offset + 4, len, ld); break; default: ld->other++; break; } }
static gboolean capture_ap1394(const guchar *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header) { guint16 etype; if (!BYTES_ARE_IN_FRAME(offset, len, 18)) { return FALSE; } /* Skip destination and source addresses */ offset += 16; etype = pntoh16(&pd[offset]); offset += 2; return try_capture_dissector("ethertype", etype, pd, offset, len, cpinfo, pseudo_header); }
void capture_snap(const guchar *pd, int offset, int len, packet_counts *ld) { guint32 oui; guint16 etype; if (!BYTES_ARE_IN_FRAME(offset, len, 5)) { ld->other++; return; } oui = pd[offset] << 16 | pd[offset+1] << 8 | pd[offset+2]; etype = pntoh16(&pd[offset+3]); switch (oui) { case OUI_ENCAP_ETHER: case OUI_CISCO_90: case OUI_APPLE_ATALK: /* No, I have no idea why Apple used one of their own OUIs, rather than OUI_ENCAP_ETHER, and an Ethernet packet type as protocol ID, for AppleTalk data packets - but used OUI_ENCAP_ETHER and an Ethernet packet type for AARP packets. */ capture_ethertype(etype, pd, offset+5, len, ld); break; case OUI_CISCO: capture_ethertype(etype, pd, offset+5, len, ld); break; case OUI_MARVELL: /* * OLPC packet. The PID is an Ethertype, but * there's a mesh header between the PID and * the payload. (We assume the header is * 5 bytes, for now). */ capture_ethertype(etype, pd, offset+5+5, len, ld); break; default: ld->other++; break; } }
void capture_ap1394(const guchar *pd, int offset, int len, packet_counts *ld) { guint16 etype; if (!BYTES_ARE_IN_FRAME(offset, len, 18)) { ld->other++; return; } /* Skip destination and source addresses */ offset += 16; etype = pntoh16(&pd[offset]); offset += 2; capture_ethertype(etype, pd, offset, len, ld); }
static gboolean csids_read_packet(FILE_T fh, csids_t *csids, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { struct csids_header hdr; int bytesRead = 0; guint8 *pd; bytesRead = file_read( &hdr, sizeof( struct csids_header), fh ); if( bytesRead != sizeof( struct csids_header) ) { *err = file_error( fh, err_info ); if (*err == 0 && bytesRead != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } hdr.seconds = pntoh32(&hdr.seconds); hdr.caplen = pntoh16(&hdr.caplen); phdr->presence_flags = WTAP_HAS_TS; phdr->len = hdr.caplen; phdr->caplen = hdr.caplen; phdr->ts.secs = hdr.seconds; phdr->ts.nsecs = 0; if( !wtap_read_packet_bytes( fh, buf, phdr->caplen, err, err_info ) ) return FALSE; pd = buffer_start_ptr( buf ); if( csids->byteswapped ) { if( phdr->caplen >= 2 ) { PBSWAP16(pd); /* the ip len */ if( phdr->caplen >= 4 ) { PBSWAP16(pd+2); /* ip id */ if( phdr->caplen >= 6 ) PBSWAP16(pd+4); /* ip flags and fragoff */ } } } 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; }
int k12_open(wtap *wth, int *err, gchar **err_info) { k12_src_desc_t* rec; guint8 header_buffer[0x200]; guint8* read_buffer; guint32 type; long offset; long len; guint32 rec_len; guint32 extra_len; guint32 name_len; guint32 stack_len; guint i; k12_t* file_data; #ifdef DEBUG_K12 gchar* env_level = getenv("K12_DEBUG_LEVEL"); env_file = getenv("K12_DEBUG_FILENAME"); if ( env_file ) { dbg_out = ws_fopen(env_file,"w"); if (dbg_out == NULL) { dbg_out = stderr; K12_DBG(1,("unable to open K12 DEBUG FILENAME for writing! Logging to standard error")); } } else dbg_out = stderr; if ( env_level ) debug_level = (unsigned int)strtoul(env_level,NULL,10); K12_DBG(1,("k12_open: ENTER debug_level=%u",debug_level)); #endif if ( file_read(header_buffer,0x200,wth->fh) != 0x200 ) { K12_DBG(1,("k12_open: FILE HEADER TOO SHORT OR READ ERROR")); *err = file_error(wth->fh, err_info); if (*err != 0 && *err != WTAP_ERR_SHORT_READ) { return -1; } return 0; } else { if ( memcmp(header_buffer,k12_file_magic,8) != 0 ) { K12_DBG(1,("k12_open: BAD MAGIC")); return 0; } } offset = 0x200; file_data = new_k12_file_data(); file_data->file_len = pntoh32( header_buffer + 0x8); file_data->num_of_records = pntoh32( header_buffer + 0xC ); K12_DBG(5,("k12_open: FILE_HEADER OK: offset=%x file_len=%i records=%i", offset, file_data->file_len, file_data->num_of_records )); do { len = get_record(file_data, wth->fh, offset, FALSE, err, err_info); if ( len < 0 ) { K12_DBG(1,("k12_open: BAD HEADER RECORD",len)); destroy_k12_file_data(file_data); return -1; } if (len == 0) { K12_DBG(1,("k12_open: BAD HEADER RECORD",len)); *err = WTAP_ERR_SHORT_READ; destroy_k12_file_data(file_data); return -1; } if (len == 0) { K12_DBG(1,("k12_open: BAD HEADER RECORD",len)); *err = WTAP_ERR_SHORT_READ; destroy_k12_file_data(file_data); return -1; } read_buffer = file_data->seq_read_buff; rec_len = pntoh32( read_buffer + K12_RECORD_LEN ); if (rec_len < K12_RECORD_TYPE + 4) { /* Record isn't long enough to have a type field */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: record length %u < %u", rec_len, K12_RECORD_TYPE + 4); return -1; } type = pntoh32( read_buffer + K12_RECORD_TYPE ); if ( (type & K12_MASK_PACKET) == K12_REC_PACKET || (type & K12_MASK_PACKET) == K12_REC_D0020) { /* * we are at the first packet record, rewind and leave. */ if (file_seek(wth->fh, offset, SEEK_SET, err) == -1) { destroy_k12_file_data(file_data); return -1; } K12_DBG(5,("k12_open: FIRST PACKET offset=%x",offset)); break; } else if (type == K12_REC_SRCDSC || type == K12_REC_SRCDSC2 ) { rec = g_new0(k12_src_desc_t,1); if (rec_len < K12_SRCDESC_STACKLEN + 2) { /* Record isn't long enough to have a stack length field */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u", rec_len, K12_SRCDESC_STACKLEN + 2); return -1; } extra_len = pntoh16( read_buffer + K12_SRCDESC_EXTRALEN ); name_len = pntoh16( read_buffer + K12_SRCDESC_NAMELEN ); stack_len = pntoh16( read_buffer + K12_SRCDESC_STACKLEN ); rec->input = pntoh32( read_buffer + K12_RECORD_SRC_ID ); K12_DBG(5,("k12_open: INTERFACE RECORD offset=%x interface=%x",offset,rec->input)); if (name_len == 0 || stack_len == 0 || 0x20 + extra_len + name_len + stack_len > rec_len ) { g_free(rec); K12_DBG(5,("k12_open: failed (name_len == 0 || stack_len == 0 " "|| 0x20 + extra_len + name_len + stack_len > rec_len) extra_len=%i name_len=%i stack_len=%i")); destroy_k12_file_data(file_data); return 0; } if (extra_len) { if (rec_len < K12_SRCDESC_EXTRATYPE + 4) { /* Record isn't long enough to have a source descriptor extra type field */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u", rec_len, K12_SRCDESC_EXTRATYPE + 4); return -1; } switch(( rec->input_type = pntoh32( read_buffer + K12_SRCDESC_EXTRATYPE ) )) { case K12_PORT_DS0S: if (rec_len < K12_SRCDESC_DS0_MASK + 32) { /* Record isn't long enough to have a source descriptor extra type field */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u", rec_len, K12_SRCDESC_DS0_MASK + 12); return -1; } rec->input_info.ds0mask = 0x00000000; for (i = 0; i < 32; i++) { rec->input_info.ds0mask |= ( *(read_buffer + K12_SRCDESC_DS0_MASK + i) == 0xff ) ? 0x1<<(31-i) : 0x0; } break; case K12_PORT_ATMPVC: if (rec_len < K12_SRCDESC_ATM_VCI + 2) { /* Record isn't long enough to have a source descriptor extra type field */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u", rec_len, K12_SRCDESC_DS0_MASK + 12); return -1; } rec->input_info.atm.vp = pntoh16( read_buffer + K12_SRCDESC_ATM_VPI ); rec->input_info.atm.vc = pntoh16( read_buffer + K12_SRCDESC_ATM_VCI ); break; default: break; } } else { /* Record viewer generated files don't have this information */ if (rec_len < K12_SRCDESC_PORT_TYPE + 1) { /* Record isn't long enough to have a source descriptor extra type field */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u", rec_len, K12_SRCDESC_DS0_MASK + 12); return -1; } if (read_buffer[K12_SRCDESC_PORT_TYPE] >= 0x14 && read_buffer[K12_SRCDESC_PORT_TYPE] <= 0x17) { /* For ATM2_E1DS1, ATM2_E3DS3, ATM2_STM1EL and ATM2_STM1OP */ rec->input_type = K12_PORT_ATMPVC; rec->input_info.atm.vp = 0; rec->input_info.atm.vc = 0; } } /* XXX - this is assumed, in a number of places (not just in the ascii_strdown_inplace() call below) to be null-terminated; is that guaranteed (even with a corrupt file)? Obviously not, as a corrupt file could contain anything here; the Tektronix document says the strings "must end with \0", but a bad file could fail to add the \0. */ if (rec_len < K12_SRCDESC_EXTRATYPE + extra_len + name_len + stack_len) { /* Record isn't long enough to have a source descriptor extra type field */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u", rec_len, K12_SRCDESC_EXTRATYPE + extra_len + name_len + stack_len); return -1; } rec->input_name = (gchar *)g_memdup(read_buffer + K12_SRCDESC_EXTRATYPE + extra_len, name_len); rec->stack_file = (gchar *)g_memdup(read_buffer + K12_SRCDESC_EXTRATYPE + extra_len + name_len, stack_len); ascii_strdown_inplace (rec->stack_file); g_hash_table_insert(file_data->src_by_id,GUINT_TO_POINTER(rec->input),rec); g_hash_table_insert(file_data->src_by_name,rec->stack_file,rec); offset += len; continue; } else if (type == K12_REC_STK_FILE) { K12_DBG(1,("k12_open: K12_REC_STK_FILE")); K12_DBG(1,("Field 1: 0x%08x",pntoh32( read_buffer + 0x08 ))); K12_DBG(1,("Field 2: 0x%08x",pntoh32( read_buffer + 0x0c ))); K12_ASCII_DUMP(1, read_buffer, rec_len, 0x10); offset += len; continue; } else { K12_DBG(1,("k12_open: RECORD TYPE 0x%08x",type)); offset += len; continue; } } while(1); wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_K12; wth->file_encap = WTAP_ENCAP_K12; wth->snapshot_length = 0; wth->subtype_read = k12_read; wth->subtype_seek_read = k12_seek_read; wth->subtype_close = k12_close; wth->priv = (void *)file_data; wth->tsprecision = WTAP_FILE_TSPREC_NSEC; return 1; }
void capture_eth(const guchar *pd, int offset, int len, packet_counts *ld) { guint16 etype, length; int ethhdr_type; /* the type of ethernet frame */ if (!BYTES_ARE_IN_FRAME(offset, len, ETH_HEADER_SIZE)) { ld->other++; return; } etype = pntoh16(&pd[offset+12]); if (etype <= IEEE_802_3_MAX_LEN) { /* Oh, yuck. Cisco ISL frames require special interpretation of the destination address field; fortunately, they can be recognized by checking the first 5 octets of the destination address, which are 01-00-0C-00-00 or 0C-00-0C-00-00 for ISL frames. */ if ((pd[offset] == 0x01 || pd[offset] == 0x0C) && pd[offset+1] == 0x00 && pd[offset+2] == 0x0C && pd[offset+3] == 0x00 && pd[offset+4] == 0x00) { capture_isl(pd, offset, len, ld); return; } } /* * If the type/length field is <= the maximum 802.3 length, * and is not zero, this is an 802.3 frame, and it's a length * field; it might be an Novell "raw 802.3" frame, with no * 802.2 LLC header, or it might be a frame with an 802.2 LLC * header. * * If the type/length field is >= the minimum Ethernet II length, * this is an Ethernet II frame, and it's a type field. * * If the type/length field is > maximum 802.3 length and < minimum * Ethernet II length, then this is an invalid packet. * * If the type/length field is zero (ETHERTYPE_UNK), this is * a frame used internally by the Cisco MDS switch to contain * Fibre Channel ("Vegas"). We treat that as an Ethernet II * frame; the dissector for those frames registers itself with * an ethernet type of ETHERTYPE_UNK. */ if (etype > IEEE_802_3_MAX_LEN && etype < ETHERNET_II_MIN_LEN) { ld->other++; return; } if (etype <= IEEE_802_3_MAX_LEN && etype != ETHERTYPE_UNK) { length = etype; /* Is there an 802.2 layer? I can tell by looking at the first 2 bytes after the 802.3 header. If they are 0xffff, then what follows the 802.3 header is an IPX payload, meaning no 802.2. (IPX/SPX is they only thing that can be contained inside a straight 802.3 packet). A non-0xffff value means that there's an 802.2 layer inside the 802.3 layer */ if (pd[offset+14] == 0xff && pd[offset+15] == 0xff) { ethhdr_type = ETHERNET_802_3; } else { ethhdr_type = ETHERNET_802_2; } /* Convert the LLC length from the 802.3 header to a total frame length, by adding in the size of any data that preceded the Ethernet header, and adding in the Ethernet header size, and set the payload and captured-payload lengths to the minima of the total length and the frame lengths. */ length += offset + ETH_HEADER_SIZE; if (len > length) len = length; } else { ethhdr_type = ETHERNET_II; } offset += ETH_HEADER_SIZE; switch (ethhdr_type) { case ETHERNET_802_3: capture_ipx(ld); break; case ETHERNET_802_2: capture_llc(pd, offset, len, ld); break; case ETHERNET_II: capture_ethertype(etype, pd, offset, len, ld); break; } }
static gboolean snoop_read_atm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info) { struct snoop_atm_hdr atm_phdr; int bytes_read; guint8 vpi; guint16 vci; errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&atm_phdr, sizeof (struct snoop_atm_hdr), fh); if (bytes_read != sizeof (struct snoop_atm_hdr)) { *err = file_error(fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } vpi = atm_phdr.vpi; vci = pntoh16(&atm_phdr.vci); /* * The lower 4 bits of the first byte of the header indicate * the type of traffic, as per the "atmioctl.h" header in * SunATM. */ switch (atm_phdr.flags & 0x0F) { case 0x01: /* LANE */ pseudo_header->atm.aal = AAL_5; pseudo_header->atm.type = TRAF_LANE; break; case 0x02: /* RFC 1483 LLC multiplexed traffic */ pseudo_header->atm.aal = AAL_5; pseudo_header->atm.type = TRAF_LLCMX; break; case 0x05: /* ILMI */ pseudo_header->atm.aal = AAL_5; pseudo_header->atm.type = TRAF_ILMI; break; case 0x06: /* Signalling AAL */ pseudo_header->atm.aal = AAL_SIGNALLING; pseudo_header->atm.type = TRAF_UNKNOWN; break; case 0x03: /* MARS (RFC 2022) */ pseudo_header->atm.aal = AAL_5; pseudo_header->atm.type = TRAF_UNKNOWN; break; case 0x04: /* IFMP (Ipsilon Flow Management Protocol; see RFC 1954) */ pseudo_header->atm.aal = AAL_5; pseudo_header->atm.type = TRAF_UNKNOWN; /* XXX - TRAF_IPSILON? */ break; default: /* * Assume it's AAL5, unless it's VPI 0 and VCI 5, in which * case assume it's AAL_SIGNALLING; we know nothing more * about it. * * XXX - is this necessary? Or are we guaranteed that * all signalling traffic has a type of 0x06? * * XXX - is this guaranteed to be AAL5? Or, if the type is * 0x00 ("raw"), might it be non-AAL5 traffic? */ if (vpi == 0 && vci == 5) pseudo_header->atm.aal = AAL_SIGNALLING; else pseudo_header->atm.aal = AAL_5; pseudo_header->atm.type = TRAF_UNKNOWN; break; } pseudo_header->atm.subtype = TRAF_ST_UNKNOWN; pseudo_header->atm.vpi = vpi; pseudo_header->atm.vci = vci; pseudo_header->atm.channel = (atm_phdr.flags & 0x80) ? 0 : 1; /* We don't have this information */ pseudo_header->atm.flags = 0; pseudo_header->atm.cells = 0; pseudo_header->atm.aal5t_u2u = 0; pseudo_header->atm.aal5t_len = 0; pseudo_header->atm.aal5t_chksum = 0; return TRUE; }
wtap_open_return_val k12_open(wtap *wth, int *err, gchar **err_info) { k12_src_desc_t* rec; guint8 header_buffer[K12_FILE_HDR_LEN]; guint8* read_buffer; guint32 type; long offset; long len; guint port_type; guint32 rec_len; guint32 hwpart_len; guint32 name_len; guint32 stack_len; guint i; k12_t* file_data; #ifdef DEBUG_K12 gchar* env_level = getenv("K12_DEBUG_LEVEL"); env_file = getenv("K12_DEBUG_FILENAME"); if ( env_file ) { dbg_out = ws_fopen(env_file,"w"); if (dbg_out == NULL) { dbg_out = stderr; K12_DBG(1,("unable to open K12 DEBUG FILENAME for writing! Logging to standard error")); } } else dbg_out = stderr; if ( env_level ) debug_level = (unsigned int)strtoul(env_level,NULL,10); K12_DBG(1,("k12_open: ENTER debug_level=%u",debug_level)); #endif if ( !wtap_read_bytes(wth->fh,header_buffer,K12_FILE_HDR_LEN,err,err_info) ) { K12_DBG(1,("k12_open: FILE HEADER TOO SHORT OR READ ERROR")); if (*err != WTAP_ERR_SHORT_READ) { return WTAP_OPEN_ERROR; } return WTAP_OPEN_NOT_MINE; } if ( memcmp(header_buffer,k12_file_magic,8) != 0 ) { K12_DBG(1,("k12_open: BAD MAGIC")); return WTAP_OPEN_NOT_MINE; } offset = K12_FILE_HDR_LEN; file_data = new_k12_file_data(); file_data->file_len = pntoh32( header_buffer + 0x8); if (memiszero(header_buffer + 0x10, K12_FILE_HDR_LEN - 0x10)) { /* * The rest of the file header is all zeroes. That means * this is a file written by the old Wireshark code, and * a count of records in the file is at an offset of 0x0C. */ file_data->num_of_records = pntoh32( header_buffer + 0x0C ); } else { /* * There's at least one non-zero byte in the rest of the * header. The value 8192 is at 0xC (page size?), and * what appears to be the number of records in the file * is at an offset of 0x24 and at an offset of 0x2c. * * If the two values are not the same, we fail; if that's * the case, we need to see the file to figure out which * of those two values, if any, is the count. */ file_data->num_of_records = pntoh32( header_buffer + K12_FILE_HDR_RECORD_COUNT_1 ); if ( file_data->num_of_records != pntoh32( header_buffer + K12_FILE_HDR_RECORD_COUNT_2 ) ) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12: two different record counts, %u at 0x%02x and %u at 0x%02x", file_data->num_of_records, K12_FILE_HDR_RECORD_COUNT_1, pntoh32( header_buffer + K12_FILE_HDR_RECORD_COUNT_2 ), K12_FILE_HDR_RECORD_COUNT_2 ); return WTAP_OPEN_ERROR; } } K12_DBG(5,("k12_open: FILE_HEADER OK: offset=%x file_len=%i records=%i", offset, file_data->file_len, file_data->num_of_records )); do { if ( file_data->num_of_records == 0 ) { *err = WTAP_ERR_SHORT_READ; destroy_k12_file_data(file_data); return WTAP_OPEN_ERROR; } len = get_record(file_data, wth->fh, offset, FALSE, err, err_info); if ( len < 0 ) { K12_DBG(1,("k12_open: BAD HEADER RECORD",len)); destroy_k12_file_data(file_data); return WTAP_OPEN_ERROR; } if ( len == 0 ) { K12_DBG(1,("k12_open: BAD HEADER RECORD",len)); *err = WTAP_ERR_SHORT_READ; destroy_k12_file_data(file_data); return WTAP_OPEN_ERROR; } read_buffer = file_data->seq_read_buff; rec_len = pntoh32( read_buffer + K12_RECORD_LEN ); if (rec_len < K12_RECORD_TYPE + 4) { /* Record isn't long enough to have a type field */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: record length %u < %u", rec_len, K12_RECORD_TYPE + 4); return WTAP_OPEN_ERROR; } type = pntoh32( read_buffer + K12_RECORD_TYPE ); if ( (type & K12_MASK_PACKET) == K12_REC_PACKET || (type & K12_MASK_PACKET) == K12_REC_D0020) { /* * we are at the first packet record, rewind and leave. */ if (file_seek(wth->fh, offset, SEEK_SET, err) == -1) { destroy_k12_file_data(file_data); return WTAP_OPEN_ERROR; } K12_DBG(5,("k12_open: FIRST PACKET offset=%x",offset)); break; } switch (type) { case K12_REC_SRCDSC: case K12_REC_SRCDSC2: rec = g_new0(k12_src_desc_t,1); if (rec_len < K12_SRCDESC_HWPART) { /* * Record isn't long enough to have the fixed-length portion * of the source descriptor field. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u", rec_len, K12_SRCDESC_HWPART); destroy_k12_file_data(file_data); g_free(rec); return WTAP_OPEN_ERROR; } port_type = read_buffer[K12_SRCDESC_PORT_TYPE]; hwpart_len = pntoh16( read_buffer + K12_SRCDESC_HWPARTLEN ); name_len = pntoh16( read_buffer + K12_SRCDESC_NAMELEN ); stack_len = pntoh16( read_buffer + K12_SRCDESC_STACKLEN ); rec->input = pntoh32( read_buffer + K12_RECORD_SRC_ID ); K12_DBG(5,("k12_open: INTERFACE RECORD offset=%x interface=%x",offset,rec->input)); if (name_len == 0) { K12_DBG(5,("k12_open: failed (name_len == 0 in source description")); destroy_k12_file_data(file_data); g_free(rec); return WTAP_OPEN_NOT_MINE; } if (stack_len == 0) { K12_DBG(5,("k12_open: failed (stack_len == 0 in source description")); destroy_k12_file_data(file_data); g_free(rec); return WTAP_OPEN_NOT_MINE; } if (rec_len < K12_SRCDESC_HWPART + hwpart_len + name_len + stack_len) { /* * Record isn't long enough to have the full source descriptor * field, including the variable-length parts. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u (%u + %u + %u + %u)", rec_len, K12_SRCDESC_HWPART + hwpart_len + name_len + stack_len, K12_SRCDESC_HWPART, hwpart_len, name_len, stack_len); destroy_k12_file_data(file_data); g_free(rec); return WTAP_OPEN_ERROR; } if (hwpart_len) { if (hwpart_len < 4) { /* Hardware part isn't long enough to have a type field */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor hardware part length %u < 4", hwpart_len); destroy_k12_file_data(file_data); g_free(rec); return WTAP_OPEN_ERROR; } switch(( rec->input_type = pntoh32( read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_HWPARTTYPE ) )) { case K12_PORT_DS0S: /* This appears to be variable-length */ rec->input_info.ds0mask = 0x00000000; if (hwpart_len > K12_SRCDESC_DS0_MASK) { for (i = 0; i < hwpart_len - K12_SRCDESC_DS0_MASK; i++) { rec->input_info.ds0mask |= ( *(read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_DS0_MASK + i) == 0xff ) ? 1U<<(31-i) : 0x0; } } break; case K12_PORT_ATMPVC: if (hwpart_len < K12_SRCDESC_ATM_VCI + 2) { /* Hardware part isn't long enough to have ATM information */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor hardware part length %u < %u", hwpart_len, K12_SRCDESC_ATM_VCI + 2); destroy_k12_file_data(file_data); g_free(rec); return WTAP_OPEN_ERROR; } rec->input_info.atm.vp = pntoh16( read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_ATM_VPI ); rec->input_info.atm.vc = pntoh16( read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_ATM_VCI ); break; default: break; } } else { /* Record viewer generated files don't have this information */ if (port_type >= 0x14 && port_type <= 0x17) { /* For ATM2_E1DS1, ATM2_E3DS3, ATM2_STM1EL and ATM2_STM1OP */ rec->input_type = K12_PORT_ATMPVC; rec->input_info.atm.vp = 0; rec->input_info.atm.vc = 0; } } if (read_buffer[K12_SRCDESC_HWPART + hwpart_len + name_len - 1] != '\0') { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("k12_open: source descriptor record contains non-null-terminated link-layer name"); destroy_k12_file_data(file_data); g_free(rec); return WTAP_OPEN_ERROR; } if (read_buffer[K12_SRCDESC_HWPART + hwpart_len + name_len + stack_len - 1] != '\0') { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("k12_open: source descriptor record contains non-null-terminated stack path"); destroy_k12_file_data(file_data); g_free(rec); return WTAP_OPEN_ERROR; } rec->input_name = (gchar *)g_memdup(read_buffer + K12_SRCDESC_HWPART + hwpart_len, name_len); rec->stack_file = (gchar *)g_memdup(read_buffer + K12_SRCDESC_HWPART + hwpart_len + name_len, stack_len); ascii_strdown_inplace (rec->stack_file); g_hash_table_insert(file_data->src_by_id,GUINT_TO_POINTER(rec->input),rec); g_hash_table_insert(file_data->src_by_name,rec->stack_file,rec); break; case K12_REC_STK_FILE: K12_DBG(1,("k12_open: K12_REC_STK_FILE")); K12_DBG(1,("Field 1: 0x%08x",pntoh32( read_buffer + 0x08 ))); K12_DBG(1,("Field 2: 0x%08x",pntoh32( read_buffer + 0x0c ))); K12_ASCII_DUMP(1, read_buffer, rec_len, 16); break; default: K12_DBG(1,("k12_open: RECORD TYPE 0x%08x",type)); break; } offset += len; file_data->num_of_records--; } while(1); wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_K12; wth->file_encap = WTAP_ENCAP_K12; wth->snapshot_length = 0; wth->subtype_read = k12_read; wth->subtype_seek_read = k12_seek_read; wth->subtype_close = k12_close; wth->priv = (void *)file_data; wth->file_tsprec = WTAP_TSPREC_NSEC; 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; 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; }
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); }
static gboolean process_packet_data(wtap_rec *rec, Buffer *target, guint8 *buffer, guint record_len, k12_t *k12, int *err, gchar **err_info) { guint32 type; guint buffer_offset; guint64 ts; guint32 length; guint32 extra_len; guint32 src_id; k12_src_desc_t* src_desc; type = pntoh32(buffer + K12_RECORD_TYPE); buffer_offset = (type == K12_REC_D0020) ? K12_PACKET_FRAME_D0020 : K12_PACKET_FRAME; if (buffer_offset > record_len) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12: Frame data offset %u > record length %u", buffer_offset, record_len); return FALSE; } length = pntoh32(buffer + K12_RECORD_FRAME_LEN) & 0x00001FFF; if (length > record_len - buffer_offset) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12: Frame length %u > record frame data %u", length, record_len - buffer_offset); return FALSE; } rec->rec_type = REC_TYPE_PACKET; rec->presence_flags = WTAP_HAS_TS; ts = pntoh64(buffer + K12_PACKET_TIMESTAMP); rec->ts.secs = (guint32) ((ts / 2000000) + 631152000); rec->ts.nsecs = (guint32) ( (ts % 2000000) * 500 ); rec->rec_header.packet_header.len = rec->rec_header.packet_header.caplen = length; ws_buffer_assure_space(target, length); memcpy(ws_buffer_start_ptr(target), buffer + buffer_offset, length); /* extra information need by some protocols */ extra_len = record_len - buffer_offset - length; ws_buffer_assure_space(&(k12->extra_info), extra_len); memcpy(ws_buffer_start_ptr(&(k12->extra_info)), buffer + buffer_offset + length, extra_len); rec->rec_header.packet_header.pseudo_header.k12.extra_info = (guint8*)ws_buffer_start_ptr(&(k12->extra_info)); rec->rec_header.packet_header.pseudo_header.k12.extra_length = extra_len; src_id = pntoh32(buffer + K12_RECORD_SRC_ID); K12_DBG(5,("process_packet_data: src_id=%.8x",src_id)); rec->rec_header.packet_header.pseudo_header.k12.input = src_id; if ( ! (src_desc = (k12_src_desc_t*)g_hash_table_lookup(k12->src_by_id,GUINT_TO_POINTER(src_id))) ) { /* * Some records from K15 files have a port ID of an undeclared * interface which happens to be the only one with the first byte changed. * It is still unknown how to recognize when this happens. * If the lookup of the interface record fails we'll mask it * and retry. */ src_desc = (k12_src_desc_t*)g_hash_table_lookup(k12->src_by_id,GUINT_TO_POINTER(src_id&K12_RECORD_SRC_ID_MASK)); } if (src_desc) { K12_DBG(5,("process_packet_data: input_name='%s' stack_file='%s' type=%x",src_desc->input_name,src_desc->stack_file,src_desc->input_type)); rec->rec_header.packet_header.pseudo_header.k12.input_name = src_desc->input_name; rec->rec_header.packet_header.pseudo_header.k12.stack_file = src_desc->stack_file; rec->rec_header.packet_header.pseudo_header.k12.input_type = src_desc->input_type; switch(src_desc->input_type) { case K12_PORT_ATMPVC: if (buffer_offset + length + K12_PACKET_OFFSET_CID < record_len) { rec->rec_header.packet_header.pseudo_header.k12.input_info.atm.vp = pntoh16(buffer + buffer_offset + length + K12_PACKET_OFFSET_VP); rec->rec_header.packet_header.pseudo_header.k12.input_info.atm.vc = pntoh16(buffer + buffer_offset + length + K12_PACKET_OFFSET_VC); rec->rec_header.packet_header.pseudo_header.k12.input_info.atm.cid = *((unsigned char*)(buffer + buffer_offset + length + K12_PACKET_OFFSET_CID)); break; } /* Fall through */ default: memcpy(&(rec->rec_header.packet_header.pseudo_header.k12.input_info),&(src_desc->input_info),sizeof(src_desc->input_info)); break; } } else { K12_DBG(5,("process_packet_data: NO SRC_RECORD FOUND")); memset(&(rec->rec_header.packet_header.pseudo_header.k12),0,sizeof(rec->rec_header.packet_header.pseudo_header.k12)); rec->rec_header.packet_header.pseudo_header.k12.input_name = "unknown port"; rec->rec_header.packet_header.pseudo_header.k12.stack_file = "unknown stack file"; } rec->rec_header.packet_header.pseudo_header.k12.input = src_id; rec->rec_header.packet_header.pseudo_header.k12.stuff = k12; return TRUE; }
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 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); }
/* Parses a record. */ static gboolean read_eyesdn_rec(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header; guint8 hdr[EYESDN_HDR_LENGTH]; time_t secs; int usecs; int pkt_len; guint8 channel, direction; int bytes_read; guint8 *pd; /* Our file pointer should be at the summary information header * for a packet. Read in that header and extract the useful * information. */ if (esc_read(hdr, EYESDN_HDR_LENGTH, fh) != EYESDN_HDR_LENGTH) { *err = file_error(fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } /* extract information from header */ usecs = pntoh24(&hdr[0]); #ifdef TV64BITS secs = hdr[3]; #else secs = 0; #endif secs = (secs << 8) | hdr[4]; secs = (secs << 8) | hdr[5]; secs = (secs << 8) | hdr[6]; secs = (secs << 8) | hdr[7]; channel = hdr[8]; direction = hdr[9]; pkt_len = pntoh16(&hdr[10]); switch(direction >> 1) { default: case EYESDN_ENCAP_ISDN: /* ISDN */ pseudo_header->isdn.uton = direction & 1; pseudo_header->isdn.channel = channel; if(channel) { /* bearer channels */ phdr->pkt_encap = WTAP_ENCAP_ISDN; /* recognises PPP */ pseudo_header->isdn.uton=!pseudo_header->isdn.uton; /* bug */ } else { /* D channel */ phdr->pkt_encap = WTAP_ENCAP_ISDN; } break; case EYESDN_ENCAP_MSG: /* Layer 1 message */ phdr->pkt_encap = WTAP_ENCAP_LAYER1_EVENT; pseudo_header->l1event.uton = (direction & 1); break; case EYESDN_ENCAP_LAPB: /* X.25 via LAPB */ phdr->pkt_encap = WTAP_ENCAP_LAPB; pseudo_header->x25.flags = (direction & 1) ? 0 : 0x80; break; case EYESDN_ENCAP_ATM: { /* ATM cells */ #define CELL_LEN 53 unsigned char cell[CELL_LEN]; gint64 cur_off; if(pkt_len != CELL_LEN) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf( "eyesdn: ATM cell has a length != 53 (%u)", pkt_len); return FALSE; } cur_off = file_tell(fh); if (esc_read(cell, CELL_LEN, fh) != CELL_LEN) { *err = file_error(fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } if (file_seek(fh, cur_off, SEEK_SET, err) == -1) return FALSE; phdr->pkt_encap = WTAP_ENCAP_ATM_PDUS_UNTRUNCATED; pseudo_header->atm.flags=ATM_RAW_CELL; pseudo_header->atm.aal=AAL_UNKNOWN; pseudo_header->atm.type=TRAF_UMTS_FP; pseudo_header->atm.subtype=TRAF_ST_UNKNOWN; pseudo_header->atm.vpi=((cell[0]&0xf)<<4) + (cell[0]&0xf); pseudo_header->atm.vci=((cell[0]&0xf)<<4) + cell[0]; /* from cell */ pseudo_header->atm.channel=direction & 1; } break; case EYESDN_ENCAP_MTP2: /* SS7 frames */ pseudo_header->mtp2.sent = direction & 1; pseudo_header->mtp2.annex_a_used = MTP2_ANNEX_A_USED_UNKNOWN; pseudo_header->mtp2.link_number = channel; phdr->pkt_encap = WTAP_ENCAP_MTP2_WITH_PHDR; break; case EYESDN_ENCAP_DPNSS: /* DPNSS */ pseudo_header->isdn.uton = direction & 1; pseudo_header->isdn.channel = channel; phdr->pkt_encap = WTAP_ENCAP_DPNSS; break; case EYESDN_ENCAP_DASS2: /* DASS2 frames */ pseudo_header->isdn.uton = direction & 1; pseudo_header->isdn.channel = channel; phdr->pkt_encap = WTAP_ENCAP_DPNSS; break; case EYESDN_ENCAP_BACNET: /* BACNET async over HDLC frames */ pseudo_header->isdn.uton = direction & 1; pseudo_header->isdn.channel = channel; phdr->pkt_encap = WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR; break; case EYESDN_ENCAP_V5_EF: /* V5EF */ pseudo_header->isdn.uton = direction & 1; pseudo_header->isdn.channel = channel; phdr->pkt_encap = WTAP_ENCAP_V5_EF; break; } if(pkt_len > EYESDN_MAX_PACKET_LEN) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("eyesdn: File has %u-byte packet, bigger than maximum of %u", pkt_len, EYESDN_MAX_PACKET_LEN); return FALSE; } phdr->presence_flags = WTAP_HAS_TS; phdr->ts.secs = secs; phdr->ts.nsecs = usecs * 1000; phdr->caplen = pkt_len; phdr->len = pkt_len; /* Make sure we have enough room for the packet */ buffer_assure_space(buf, EYESDN_MAX_PACKET_LEN); errno = WTAP_ERR_CANT_READ; pd = buffer_start_ptr(buf); bytes_read = esc_read(pd, pkt_len, fh); if (bytes_read != pkt_len) { if (bytes_read == -2) { *err = file_error(fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; } else if (bytes_read == -1) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("eyesdn: No flag character seen in frame"); } else *err = WTAP_ERR_SHORT_READ; return FALSE; } return TRUE; }
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 void process_packet_data(struct wtap_pkthdr *phdr, Buffer *target, guint8 *buffer, gint len, k12_t *k12) { guint32 type; guint buffer_offset; guint64 ts; guint32 length; guint32 extra_len; guint32 src_id; k12_src_desc_t* src_desc; phdr->presence_flags = WTAP_HAS_TS; ts = pntoh64(buffer + K12_PACKET_TIMESTAMP); phdr->ts.secs = (guint32) ((ts / 2000000) + 631152000); phdr->ts.nsecs = (guint32) ( (ts % 2000000) * 500 ); length = pntoh32(buffer + K12_RECORD_FRAME_LEN) & 0x00001FFF; phdr->len = phdr->caplen = length; type = pntoh32(buffer + K12_RECORD_TYPE); buffer_offset = (type == K12_REC_D0020) ? K12_PACKET_FRAME_D0020 : K12_PACKET_FRAME; buffer_assure_space(target, length); memcpy(buffer_start_ptr(target), buffer + buffer_offset, length); /* extra information need by some protocols */ extra_len = len - buffer_offset - length; buffer_assure_space(&(k12->extra_info), extra_len); memcpy(buffer_start_ptr(&(k12->extra_info)), buffer + buffer_offset + length, extra_len); phdr->pseudo_header.k12.extra_info = (guint8*)buffer_start_ptr(&(k12->extra_info)); phdr->pseudo_header.k12.extra_length = extra_len; src_id = pntoh32(buffer + K12_RECORD_SRC_ID); K12_DBG(5,("process_packet_data: src_id=%.8x",src_id)); phdr->pseudo_header.k12.input = src_id; if ( ! (src_desc = (k12_src_desc_t*)g_hash_table_lookup(k12->src_by_id,GUINT_TO_POINTER(src_id))) ) { /* * Some records from K15 files have a port ID of an undeclared * interface which happens to be the only one with the first byte changed. * It is still unknown how to recognize when this happens. * If the lookup of the interface record fails we'll mask it * and retry. */ src_desc = (k12_src_desc_t*)g_hash_table_lookup(k12->src_by_id,GUINT_TO_POINTER(src_id&K12_RECORD_SRC_ID_MASK)); } if (src_desc) { K12_DBG(5,("process_packet_data: input_name='%s' stack_file='%s' type=%x",src_desc->input_name,src_desc->stack_file,src_desc->input_type)); phdr->pseudo_header.k12.input_name = src_desc->input_name; phdr->pseudo_header.k12.stack_file = src_desc->stack_file; phdr->pseudo_header.k12.input_type = src_desc->input_type; switch(src_desc->input_type) { case K12_PORT_ATMPVC: if ((long)(buffer_offset + length + K12_PACKET_OFFSET_CID) < len) { phdr->pseudo_header.k12.input_info.atm.vp = pntoh16(buffer + buffer_offset + length + K12_PACKET_OFFSET_VP); phdr->pseudo_header.k12.input_info.atm.vc = pntoh16(buffer + buffer_offset + length + K12_PACKET_OFFSET_VC); phdr->pseudo_header.k12.input_info.atm.cid = *((unsigned char*)(buffer + buffer_offset + length + K12_PACKET_OFFSET_CID)); break; } /* Fall through */ default: memcpy(&(phdr->pseudo_header.k12.input_info),&(src_desc->input_info),sizeof(src_desc->input_info)); break; } } else { K12_DBG(5,("process_packet_data: NO SRC_RECORD FOUND")); memset(&(phdr->pseudo_header.k12),0,sizeof(phdr->pseudo_header.k12)); phdr->pseudo_header.k12.input_name = "unknown port"; phdr->pseudo_header.k12.stack_file = "unknown stack file"; } phdr->pseudo_header.k12.input = src_id; phdr->pseudo_header.k12.stuff = k12; }
static gboolean visual_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { struct visual_read_info *visual = (struct visual_read_info *)wth->priv; struct visual_pkt_hdr vpkt_hdr; int bytes_read; guint32 packet_size; struct visual_atm_hdr vatm_hdr; double t; time_t secs; guint32 usecs; guint32 packet_status; guint8 *pd; /* Read the packet header. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&vpkt_hdr, (unsigned int)sizeof vpkt_hdr, fh); if (bytes_read < 0 || (size_t)bytes_read != sizeof vpkt_hdr) { *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } /* Get the included length of data. This includes extra headers + payload */ packet_size = pletoh16(&vpkt_hdr.incl_len); phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; /* Set the packet time and length. */ t = visual->start_time; t += ((double)pletoh32(&vpkt_hdr.ts_delta))*1000; secs = (time_t)(t/1000000); usecs = (guint32)(t - secs*1000000); phdr->ts.secs = secs; phdr->ts.nsecs = usecs * 1000; phdr->len = pletoh16(&vpkt_hdr.orig_len); packet_status = pletoh32(&vpkt_hdr.status); /* Do encapsulation-specific processing. Most Visual capture types include the FCS in the original length value, but don't include the FCS as part of the payload or captured length. This is different from the model used in most other capture file formats, including pcap and pcap-ng in cases where the FCS isn't captured (which are the typical cases), and causes the RTP audio payload save to fail since then captured len != orig len. We adjust the original length to remove the FCS bytes we counted based on the file encapsualtion type. The only downside to this fix is throughput calculations will be slightly lower as it won't include the FCS bytes. However, as noted, that problem also exists with other capture formats. We also set status flags. The only status currently supported for all encapsulations is direction. This either goes in the p2p or the X.25 pseudo header. It would probably be better to move this up into the phdr. */ switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* Ethernet has a 4-byte FCS. */ if (phdr->len < 4) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("visual: Ethernet packet has %u-byte original packet, less than the FCS length", phdr->len); return FALSE; } phdr->len -= 4; /* XXX - the above implies that there's never an FCS; should this set the FCS length to 0? */ phdr->pseudo_header.eth.fcs_len = -1; break; case WTAP_ENCAP_CHDLC_WITH_PHDR: /* This has a 2-byte FCS. */ if (phdr->len < 2) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("visual: Cisco HDLC packet has %u-byte original packet, less than the FCS length", phdr->len); return FALSE; } phdr->len -= 2; phdr->pseudo_header.p2p.sent = (packet_status & PS_SENT) ? TRUE : FALSE; break; case WTAP_ENCAP_PPP_WITH_PHDR: /* No FCS. XXX - true? Note that PPP can negotiate no FCS, a 2-byte FCS, or a 4-byte FCS. */ phdr->pseudo_header.p2p.sent = (packet_status & PS_SENT) ? TRUE : FALSE; break; case WTAP_ENCAP_FRELAY_WITH_PHDR: /* This has a 2-byte FCS. */ if (phdr->len < 2) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("visual: Frame Relay packet has %u-byte original packet, less than the FCS length", phdr->len); return FALSE; } phdr->len -= 2; phdr->pseudo_header.x25.flags = (packet_status & PS_SENT) ? 0x00 : FROM_DCE; break; case WTAP_ENCAP_LAPB: /* This has a 2-byte FCS. */ if (phdr->len < 2) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("visual: Frame Relay packet has %u-byte original packet, less than the FCS length", phdr->len); return FALSE; } phdr->len -= 2; phdr->pseudo_header.x25.flags = (packet_status & PS_SENT) ? 0x00 : FROM_DCE; break; case WTAP_ENCAP_ATM_PDUS: /* ATM original length doesn't include any FCS. Do nothing to the packet length. ATM packets have an additional packet header; read and process it. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&vatm_hdr, (unsigned int)sizeof vatm_hdr, fh); if (bytes_read < 0 || (size_t)bytes_read != sizeof vatm_hdr) { *err = file_error(fh, err_info); if (*err == 0) { *err = WTAP_ERR_SHORT_READ; } return FALSE; } /* Remove ATM header from length of included bytes in capture, as this header was appended by the processor doing the packet reassembly, and was not transmitted across the wire */ packet_size -= (guint32)sizeof vatm_hdr; /* Set defaults */ phdr->pseudo_header.atm.type = TRAF_UNKNOWN; phdr->pseudo_header.atm.subtype = TRAF_ST_UNKNOWN; phdr->pseudo_header.atm.aal5t_len = 0; /* Next two items not supported. Defaulting to zero */ phdr->pseudo_header.atm.aal5t_u2u = 0; phdr->pseudo_header.atm.aal5t_chksum = 0; /* Flags appear only to convey that packet is a raw cell. Set to 0 */ phdr->pseudo_header.atm.flags = 0; /* Not supported. Defaulting to zero */ phdr->pseudo_header.atm.aal2_cid = 0; switch(vatm_hdr.category & VN_CAT_TYPE_MASK ) { case VN_AAL1: phdr->pseudo_header.atm.aal = AAL_1; break; case VN_AAL2: phdr->pseudo_header.atm.aal = AAL_2; break; case VN_AAL34: phdr->pseudo_header.atm.aal = AAL_3_4; break; case VN_AAL5: phdr->pseudo_header.atm.aal = AAL_5; phdr->pseudo_header.atm.type = TRAF_LLCMX; phdr->pseudo_header.atm.aal5t_len = pntoh32(&vatm_hdr.data_length); break; case VN_OAM: /* Marking next 3 as OAM versus unknown */ case VN_O191: case VN_IDLE: case VN_RM: phdr->pseudo_header.atm.aal = AAL_OAMCELL; break; case VN_UNKNOWN: default: phdr->pseudo_header.atm.aal = AAL_UNKNOWN; break; } phdr->pseudo_header.atm.vpi = pntoh16(&vatm_hdr.vpi) & 0x0FFF; phdr->pseudo_header.atm.vci = pntoh16(&vatm_hdr.vci); phdr->pseudo_header.atm.cells = pntoh16(&vatm_hdr.cell_count); /* Using bit value of 1 (DCE -> DTE) to indicate From Network */ phdr->pseudo_header.atm.channel = vatm_hdr.info & FROM_NETWORK; break; /* Not sure about token ring. Just leaving alone for now. */ case WTAP_ENCAP_TOKEN_RING: default: break; } phdr->caplen = packet_size; /* Check for too-large packet. */ if (packet_size > WTAP_MAX_PACKET_SIZE) { /* Probably a corrupt capture file; don't blow up trying to allocate space for an immensely-large packet. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("visual: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return FALSE; } /* Read the packet data */ if (!wtap_read_packet_bytes(fh, buf, packet_size, err, err_info)) return FALSE; if (wth->file_encap == WTAP_ENCAP_CHDLC_WITH_PHDR) { /* Fill in the encapsulation. Visual files have a media type in the file header and an encapsulation type in each packet header. Files with a media type of HDLC can be either Cisco EtherType or PPP. The encapsulation hint values we've seen are: 2 - seen in an Ethernet capture 13 - seen in a PPP capture; possibly also seen in Cisco HDLC captures 14 - seen in a PPP capture; probably seen only for PPP. According to bug 2005, the collection probe can be configured for PPP, in which case the encapsulation hint is 14, or can be configured for auto-detect, in which case the encapsulation hint is 13, and the encapsulation must be guessed from the packet contents. Auto-detect is the default. */ pd = ws_buffer_start_ptr(buf); /* If PPP is specified in the encap hint, then use that */ if (vpkt_hdr.encap_hint == 14) { /* But first we need to examine the first three octets to try to determine the proper encapsulation, see RFC 2364. */ if (packet_size >= 3 && (0xfe == pd[0]) && (0xfe == pd[1]) && (0x03 == pd[2])) { /* It is actually LLC encapsulated PPP */ phdr->pkt_encap = WTAP_ENCAP_ATM_RFC1483; } else { /* It is actually PPP */ phdr->pkt_encap = WTAP_ENCAP_PPP_WITH_PHDR; } } else { /* Otherwise, we need to examine the first two octets to try to determine the encapsulation. */ if (packet_size >= 2 && (0xff == pd[0]) && (0x03 == pd[1])) { /* It is actually PPP */ phdr->pkt_encap = WTAP_ENCAP_PPP_WITH_PHDR; } } } return TRUE; }
void capture_tr(const guchar *pd, int offset, int len, packet_counts *ld) { int source_routed = 0; int frame_type; int x; guint8 trn_rif_bytes; guint8 actual_rif_bytes; guint16 first2_sr; /* The trn_hdr struct, as separate variables */ guint8 trn_fc; /* field control field */ const guint8 *trn_shost; /* source host */ if (!BYTES_ARE_IN_FRAME(offset, len, TR_MIN_HEADER_LEN)) { ld->other++; return; } if ((x = check_for_old_linux(pd))) { /* Actually packet starts x bytes into what we have got but with all source routing compressed */ /* pd = &pd[x]; */ offset+=x; } /* get the data */ trn_fc = pd[offset + 1]; trn_shost = &pd[offset + 8]; frame_type = (trn_fc & 192) >> 6; /* if the high bit on the first byte of src hwaddr is 1, then this packet is source-routed */ source_routed = trn_shost[0] & 128; trn_rif_bytes = pd[offset + 14] & 31; if (fix_linux_botches) { /* the Linux 2.0 TR code strips source-route bits in * order to test for SR. This can be removed from most * packets with oltr, but not all. So, I try to figure out * which packets should have been SR here. I'll check to * see if there's a SNAP or IPX field right after * my RIF fields. * * The Linux 2.4.18 code, at least appears to do the * same thing, from a capture I got from somebody running * 2.4.18 (RH 7.1, so perhaps this is a Red Hat * "improvement"). */ if (!source_routed && trn_rif_bytes > 0) { if (pd[offset + 0x0e] != pd[offset + 0x0f]) { first2_sr = pntoh16(&pd[offset + 0xe0 + trn_rif_bytes]); if ( (first2_sr == 0xaaaa && pd[offset + 0x10 + trn_rif_bytes] == 0x03) || first2_sr == 0xe0e0 || first2_sr == 0xe0aa ) { source_routed = 1; } } } } if (source_routed) { actual_rif_bytes = trn_rif_bytes; } else { trn_rif_bytes = 0; actual_rif_bytes = 0; } if (fix_linux_botches) { /* this is a silly hack for Linux 2.0.x. Read the comment * below about LLC headers. If we're sniffing our own NIC, * we get a full RIF, sometimes with garbage */ if ((source_routed && trn_rif_bytes == 2 && frame_type == 1) || (!source_routed && frame_type == 1)) { /* look for SNAP or IPX only */ if ( (pd[offset + 0x20] == 0xaa && pd[offset + 0x21] == 0xaa && pd[offset + 0x22] == 03) || (pd[offset + 0x20] == 0xe0 && pd[offset + 0x21] == 0xe0) ) { actual_rif_bytes = 18; } else if ( pd[offset + 0x23] == 0 && pd[offset + 0x24] == 0 && pd[offset + 0x25] == 0 && pd[offset + 0x26] == 0x00 && pd[offset + 0x27] == 0x11) { actual_rif_bytes = 18; /* Linux 2.0.x also requires drivers pass up * a fake SNAP and LLC header before the * real LLC hdr for all Token Ring frames * that arrive with DSAP and SSAP != 0xAA * (i.e. for non SNAP frames e.g. for Netware * frames) the fake SNAP header has the * ETH_P_TR_802_2 ether type (0x0011) and the protocol id * bytes as zero frame looks like :- * TR Header | Fake LLC | Fake SNAP | Wire LLC | Rest of data */ offset += 8; /* Skip fake LLC and SNAP */ } } } offset += actual_rif_bytes + TR_MIN_HEADER_LEN; /* The package is either MAC or LLC */ switch (frame_type) { /* MAC */ case 0: ld->other++; break; case 1: capture_llc(pd, offset, len, ld); break; default: /* non-MAC, non-LLC, i.e., "Reserved" */ ld->other++; break; } }
static gboolean nettl_read_rec(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header; nettl_t *nettl = (nettl_t *)wth->priv; gboolean fddihack = FALSE; int bytes_read; struct nettlrec_hdr rec_hdr; guint16 hdr_len; struct nettlrec_ns_ls_drv_eth_hdr drv_eth_hdr; guint32 length, caplen; int subsys; guint padlen; int datalen; guint8 dummyc[16]; int bytes_to_read; guint8 *pd; guint8 dummy[3]; errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&rec_hdr.hdr_len, sizeof rec_hdr.hdr_len, fh); if (bytes_read != sizeof rec_hdr.hdr_len) { *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } hdr_len = g_ntohs(rec_hdr.hdr_len); if (hdr_len < NETTL_REC_HDR_LEN) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("nettl: record header length %u too short", hdr_len); return FALSE; } bytes_read = file_read(&rec_hdr.subsys, NETTL_REC_HDR_LEN - 2, fh); if (bytes_read != NETTL_REC_HDR_LEN - 2) { *err = file_error(fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } subsys = g_ntohs(rec_hdr.subsys); hdr_len -= NETTL_REC_HDR_LEN; if (file_seek(fh, hdr_len, SEEK_CUR, err) == -1) return FALSE; if ( (pntoh32(&rec_hdr.kind) & NETTL_HDR_PDU_MASK) == 0 ) { /* not actually a data packet (PDU) trace record */ phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_IP; length = pntoh32(&rec_hdr.length); caplen = pntoh32(&rec_hdr.caplen); padlen = 0; } else switch (subsys) { case NETTL_SUBSYS_LAN100 : case NETTL_SUBSYS_EISA100BT : case NETTL_SUBSYS_BASE100 : case NETTL_SUBSYS_GSC100BT : case NETTL_SUBSYS_PCI100BT : case NETTL_SUBSYS_SPP100BT : case NETTL_SUBSYS_100VG : case NETTL_SUBSYS_GELAN : case NETTL_SUBSYS_BTLAN : case NETTL_SUBSYS_INTL100 : case NETTL_SUBSYS_IGELAN : case NETTL_SUBSYS_IETHER : case NETTL_SUBSYS_IXGBE : case NETTL_SUBSYS_HSSN : case NETTL_SUBSYS_IGSSN : case NETTL_SUBSYS_ICXGBE : case NETTL_SUBSYS_IEXGBE : case NETTL_SUBSYS_IOCXGBE : case NETTL_SUBSYS_IQXGBE : case NETTL_SUBSYS_HPPB_FDDI : case NETTL_SUBSYS_EISA_FDDI : case NETTL_SUBSYS_PCI_FDDI : case NETTL_SUBSYS_HSC_FDDI : case NETTL_SUBSYS_TOKEN : case NETTL_SUBSYS_PCI_TR : case NETTL_SUBSYS_NS_LS_IP : case NETTL_SUBSYS_NS_LS_LOOPBACK : case NETTL_SUBSYS_NS_LS_TCP : case NETTL_SUBSYS_NS_LS_UDP : case NETTL_SUBSYS_HP_APAPORT : case NETTL_SUBSYS_HP_APALACP : case NETTL_SUBSYS_NS_LS_IPV6 : case NETTL_SUBSYS_NS_LS_ICMPV6 : case NETTL_SUBSYS_NS_LS_ICMP : case NETTL_SUBSYS_NS_LS_TELNET : case NETTL_SUBSYS_NS_LS_SCTP : if( (subsys == NETTL_SUBSYS_NS_LS_IP) || (subsys == NETTL_SUBSYS_NS_LS_LOOPBACK) || (subsys == NETTL_SUBSYS_NS_LS_UDP) || (subsys == NETTL_SUBSYS_NS_LS_TCP) || (subsys == NETTL_SUBSYS_NS_LS_SCTP) || (subsys == NETTL_SUBSYS_NS_LS_IPV6)) { phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_IP; } else if (subsys == NETTL_SUBSYS_NS_LS_ICMP) { phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMP; } else if (subsys == NETTL_SUBSYS_NS_LS_ICMPV6) { phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_ICMPV6; } else if (subsys == NETTL_SUBSYS_NS_LS_TELNET) { phdr->pkt_encap = WTAP_ENCAP_NETTL_RAW_TELNET; } else if( (subsys == NETTL_SUBSYS_HPPB_FDDI) || (subsys == NETTL_SUBSYS_EISA_FDDI) || (subsys == NETTL_SUBSYS_PCI_FDDI) || (subsys == NETTL_SUBSYS_HSC_FDDI) ) { phdr->pkt_encap = WTAP_ENCAP_NETTL_FDDI; } else if( (subsys == NETTL_SUBSYS_PCI_TR) || (subsys == NETTL_SUBSYS_TOKEN) ) { phdr->pkt_encap = WTAP_ENCAP_NETTL_TOKEN_RING; } else { phdr->pkt_encap = WTAP_ENCAP_NETTL_ETHERNET; } length = pntoh32(&rec_hdr.length); caplen = pntoh32(&rec_hdr.caplen); /* HPPB FDDI has different inbound vs outbound trace records */ if (subsys == NETTL_SUBSYS_HPPB_FDDI) { if (pntoh32(&rec_hdr.kind) == NETTL_HDR_PDUIN) { /* inbound is very strange... there are an extra 3 bytes after the DSAP and SSAP for SNAP frames ??? */ fddihack=TRUE; padlen = 0; } else { /* outbound appears to have variable padding */ bytes_read = file_read(dummyc, 9, fh); if (bytes_read != 9) { *err = file_error(fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } /* padding is usually either a total 11 or 16 bytes??? */ padlen = (int)dummyc[8]; if (file_seek(fh, padlen, SEEK_CUR, err) == -1) return FALSE; padlen += 9; } } else if ( (subsys == NETTL_SUBSYS_PCI_FDDI) || (subsys == NETTL_SUBSYS_EISA_FDDI) || (subsys == NETTL_SUBSYS_HSC_FDDI) ) { /* other flavor FDDI cards have an extra 3 bytes of padding */ if (file_seek(fh, 3, SEEK_CUR, err) == -1) return FALSE; padlen = 3; } else if (subsys == NETTL_SUBSYS_NS_LS_LOOPBACK) { /* LOOPBACK has an extra 26 bytes of padding */ if (file_seek(fh, 26, SEEK_CUR, err) == -1) return FALSE; padlen = 26; } else if (subsys == NETTL_SUBSYS_NS_LS_SCTP) { /* * SCTP 8 byte header that we will ignore... * 32 bit integer defines format * 1 = Log * 2 = ASCII * 3 = Binary (PDUs should be Binary format) * 32 bit integer defines type * 1 = Inbound * 2 = Outbound */ if (file_seek(fh, 8, SEEK_CUR, err) == -1) return FALSE; padlen = 8; } else { padlen = 0; } break; case NETTL_SUBSYS_NS_LS_DRIVER : /* XXX we dont know how to identify this as ethernet frames, so we assumes everything is. We will crash and burn for anything else */ /* for encapsulated 100baseT we do this */ phdr->pkt_encap = WTAP_ENCAP_NETTL_ETHERNET; bytes_read = file_read(&drv_eth_hdr, NS_LS_DRV_ETH_HDR_LEN, fh); if (bytes_read != NS_LS_DRV_ETH_HDR_LEN) { *err = file_error(fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } length = pntoh16(&drv_eth_hdr.length); caplen = pntoh16(&drv_eth_hdr.caplen); /* * XXX - is there a length field that would give the length * of this header, so that we don't have to check for * nettl files from HP-UX 11? * * And what are the extra two bytes? */ if (nettl->is_hpux_11) { if (file_seek(fh, 2, SEEK_CUR, err) == -1) return FALSE; } padlen = 0; break; case NETTL_SUBSYS_SX25L2: case NETTL_SUBSYS_SX25L3: /* * XXX - is the 24-byte padding actually a header with * packet lengths, time stamps, etc., just as is the case * for NETTL_SUBSYS_NS_LS_DRIVER? It might be * * guint8 caplen[2]; * guint8 length[2]; * guint8 xxc[4]; * guint8 sec[4]; * guint8 usec[4]; * guint8 xxd[4]; * * or something such as that - if it has 4 bytes before that * (making it 24 bytes), it'd be like struct * nettlrec_ns_ls_drv_eth_hdr but with 2 more bytes at the end. * * And is "from_dce" at xxa[0] in the nettlrec_hdr structure? */ phdr->pkt_encap = WTAP_ENCAP_NETTL_X25; length = pntoh32(&rec_hdr.length); caplen = pntoh32(&rec_hdr.caplen); padlen = 24; /* sizeof (struct nettlrec_sx25l2_hdr) - NETTL_REC_HDR_LEN + 4 */ if (file_seek(fh, padlen, SEEK_CUR, err) == -1) return FALSE; break; default: /* We're going to assume it's ethernet if we don't recognize the subsystem -- We'll probably spew junks and core if it isn't... */ wth->file_encap = WTAP_ENCAP_PER_PACKET; phdr->pkt_encap = WTAP_ENCAP_NETTL_ETHERNET; length = pntoh32(&rec_hdr.length); caplen = pntoh32(&rec_hdr.caplen); padlen = 0; break; } if (length < padlen) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("nettl: packet length %u in record header too short, less than %u", length, padlen); return FALSE; } phdr->rec_type = REC_TYPE_PACKET; phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; phdr->len = length - padlen; if (caplen < padlen) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("nettl: captured length %u in record header too short, less than %u", caplen, padlen); return FALSE; } datalen = caplen - padlen; phdr->caplen = datalen; phdr->ts.secs = pntoh32(&rec_hdr.sec); phdr->ts.nsecs = pntoh32(&rec_hdr.usec) * 1000; pseudo_header->nettl.subsys = subsys; pseudo_header->nettl.devid = pntoh32(&rec_hdr.devid); pseudo_header->nettl.kind = pntoh32(&rec_hdr.kind); pseudo_header->nettl.pid = pntoh32(&rec_hdr.pid); pseudo_header->nettl.uid = pntoh16(&rec_hdr.uid); if (phdr->caplen > WTAP_MAX_PACKET_SIZE) { /* * Probably a corrupt capture file; don't blow up trying * to allocate space for an immensely-large packet. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("nettl: File has %u-byte packet, bigger than maximum of %u", phdr->caplen, WTAP_MAX_PACKET_SIZE); return FALSE; } /* * Read the packet data. */ buffer_assure_space(buf, datalen); pd = buffer_start_ptr(buf); errno = WTAP_ERR_CANT_READ; if (fddihack) { /* read in FC, dest, src, DSAP and SSAP */ bytes_to_read = 15; if (bytes_to_read > datalen) bytes_to_read = datalen; bytes_read = file_read(pd, bytes_to_read, fh); if (bytes_read != bytes_to_read) { if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } datalen -= bytes_read; if (datalen == 0) { /* There's nothing past the FC, dest, src, DSAP and SSAP */ return TRUE; } if (pd[13] == 0xAA) { /* it's SNAP, have to eat 3 bytes??? */ bytes_to_read = 3; if (bytes_to_read > datalen) bytes_to_read = datalen; bytes_read = file_read(dummy, bytes_to_read, fh); if (bytes_read != bytes_to_read) { if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } datalen -= bytes_read; if (datalen == 0) { /* There's nothing past the FC, dest, src, DSAP, SSAP, and 3 bytes to eat */ return TRUE; } } bytes_read = file_read(pd + 15, datalen, fh); } else bytes_read = file_read(pd, datalen, fh); if (bytes_read != datalen) { *err = file_error(fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } return TRUE; }
wtap_open_return_val csids_open(wtap *wth, int *err, gchar **err_info) { /* There is no file header. There is only a header for each packet * so we read a packet header and compare the caplen with iplen. They * should always be equal except with the weird byteswap version. * * THIS IS BROKEN-- anytime the caplen is 0x0101 or 0x0202 up to 0x0505 * this will byteswap it. I need to fix this. XXX --mlh */ int tmp,iplen; gboolean byteswap = FALSE; struct csids_header hdr; csids_t *csids; /* check the file to make sure it is a csids file. */ if( !wtap_read_bytes( wth->fh, &hdr, sizeof( struct csids_header), err, err_info ) ) { if( *err != WTAP_ERR_SHORT_READ ) { return WTAP_OPEN_ERROR; } return WTAP_OPEN_NOT_MINE; } if( hdr.zeropad != 0 || hdr.caplen == 0 ) { return WTAP_OPEN_NOT_MINE; } hdr.seconds = pntoh32( &hdr.seconds ); hdr.caplen = pntoh16( &hdr.caplen ); if( !wtap_read_bytes( wth->fh, &tmp, 2, err, err_info ) ) { if( *err != WTAP_ERR_SHORT_READ ) { return WTAP_OPEN_ERROR; } return WTAP_OPEN_NOT_MINE; } if( !wtap_read_bytes(wth->fh, &iplen, 2, err, err_info ) ) { if( *err != WTAP_ERR_SHORT_READ ) { return WTAP_OPEN_ERROR; } return WTAP_OPEN_NOT_MINE; } iplen = pntoh16(&iplen); if ( iplen == 0 ) return WTAP_OPEN_NOT_MINE; /* if iplen and hdr.caplen are equal, default to no byteswap. */ if( iplen > hdr.caplen ) { /* maybe this is just a byteswapped version. the iplen ipflags */ /* and ipid are swapped. We cannot use the normal swaps because */ /* we don't know the host */ iplen = GUINT16_SWAP_LE_BE(iplen); if( iplen <= hdr.caplen ) { /* we know this format */ byteswap = TRUE; } else { /* don't know this one */ return WTAP_OPEN_NOT_MINE; } } else { byteswap = FALSE; } /* no file header. So reset the fh to 0 so we can read the first packet */ if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) return WTAP_OPEN_ERROR; csids = (csids_t *)g_malloc(sizeof(csids_t)); wth->priv = (void *)csids; csids->byteswapped = byteswap; wth->file_encap = WTAP_ENCAP_RAW_IP; wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_CSIDS; wth->snapshot_length = 0; /* not known */ wth->subtype_read = csids_read; wth->subtype_seek_read = csids_seek_read; wth->file_tsprec = WTAP_TSPREC_SEC; return WTAP_OPEN_MINE; }
static void fill_fp_info(fp_info* p_fp_info, guchar* extra_info, guint32 length) { guint adj = 0; /* 0x11=control frame 0x30=data frame */ guint info_type = pntoh16(extra_info); /* 1=FDD, 2=TDD 3.84, 3=TDD 1.28 */ guchar radio_mode = extra_info[14]; guchar channel_type = 0; guint i; if (!p_fp_info || length < 22) return; /* Store division type */ p_fp_info->division = (enum division_type)radio_mode; /* Format used by K15, later fields are shifted by 8 bytes. */ if (pntoh16(extra_info+2) == 5) adj = 8; p_fp_info->iface_type = IuB_Interface; p_fp_info->release = 0; /* dummy */ p_fp_info->release_year = 0; /* dummy */ p_fp_info->release_month = 0; /* dummy */ /* 1=UL, 2=DL */ if (extra_info[15] == 1) p_fp_info->is_uplink = 1; else p_fp_info->is_uplink = 0; if (info_type == 0x11) /* control frame */ channel_type = extra_info[21 + adj]; else if (info_type == 0x30) /* data frame */ channel_type = extra_info[22 + adj]; switch (channel_type) { case 1: p_fp_info->channel = CHANNEL_BCH; break; case 2: p_fp_info->channel = CHANNEL_PCH; p_fp_info->paging_indications = 0; /* dummy */ break; case 3: p_fp_info->channel = CHANNEL_CPCH; break; case 4: if (radio_mode == 1) p_fp_info->channel = CHANNEL_RACH_FDD; else if (radio_mode == 2) p_fp_info->channel = CHANNEL_RACH_TDD; else p_fp_info->channel = CHANNEL_RACH_TDD_128; break; case 5: if (radio_mode == 1) p_fp_info->channel = CHANNEL_FACH_FDD; else p_fp_info->channel = CHANNEL_FACH_TDD; break; case 6: if (radio_mode == 2) p_fp_info->channel = CHANNEL_USCH_TDD_384; else p_fp_info->channel = CHANNEL_USCH_TDD_128; break; case 7: if (radio_mode == 1) p_fp_info->channel = CHANNEL_DSCH_FDD; else p_fp_info->channel = CHANNEL_DSCH_TDD; break; case 8: p_fp_info->channel = CHANNEL_DCH; break; } p_fp_info->dch_crc_present = 2; /* information not available */ if (info_type == 0x30) { /* data frame */ p_fp_info->num_chans = extra_info[23 + adj]; /* For each channel */ for (i = 0; i < (guint)p_fp_info->num_chans && (36+i*104+adj) <= length; ++i) { /* Read TB size */ p_fp_info->chan_tf_size[i] = pntoh32(extra_info+28+i*104+adj); if (p_fp_info->chan_tf_size[i]) /* Work out number of TBs on this channel */ p_fp_info->chan_num_tbs[i] = pntoh32(extra_info+32+i*104+adj) / p_fp_info->chan_tf_size[i]; } } }
int k12_open(wtap *wth, int *err, gchar **err_info) { k12_src_desc_t* rec; guint8 header_buffer[0x200]; guint8* read_buffer; guint32 type; long offset; long len; guint port_type; guint32 rec_len; guint32 hwpart_len; guint32 name_len; guint32 stack_len; guint i; k12_t* file_data; #ifdef DEBUG_K12 gchar* env_level = getenv("K12_DEBUG_LEVEL"); env_file = getenv("K12_DEBUG_FILENAME"); if ( env_file ) { dbg_out = ws_fopen(env_file,"w"); if (dbg_out == NULL) { dbg_out = stderr; K12_DBG(1,("unable to open K12 DEBUG FILENAME for writing! Logging to standard error")); } } else dbg_out = stderr; if ( env_level ) debug_level = (unsigned int)strtoul(env_level,NULL,10); K12_DBG(1,("k12_open: ENTER debug_level=%u",debug_level)); #endif if ( file_read(header_buffer,0x200,wth->fh) != 0x200 ) { K12_DBG(1,("k12_open: FILE HEADER TOO SHORT OR READ ERROR")); *err = file_error(wth->fh, err_info); if (*err != 0 && *err != WTAP_ERR_SHORT_READ) { return -1; } return 0; } else { if ( memcmp(header_buffer,k12_file_magic,8) != 0 ) { K12_DBG(1,("k12_open: BAD MAGIC")); return 0; } } offset = 0x200; file_data = new_k12_file_data(); file_data->file_len = pntoh32( header_buffer + 0x8); file_data->num_of_records = pntoh32( header_buffer + 0xC ); K12_DBG(5,("k12_open: FILE_HEADER OK: offset=%x file_len=%i records=%i", offset, file_data->file_len, file_data->num_of_records )); do { len = get_record(file_data, wth->fh, offset, FALSE, err, err_info); if ( len < 0 ) { K12_DBG(1,("k12_open: BAD HEADER RECORD",len)); destroy_k12_file_data(file_data); return -1; } if (len == 0) { K12_DBG(1,("k12_open: BAD HEADER RECORD",len)); *err = WTAP_ERR_SHORT_READ; destroy_k12_file_data(file_data); return -1; } if (len == 0) { K12_DBG(1,("k12_open: BAD HEADER RECORD",len)); *err = WTAP_ERR_SHORT_READ; destroy_k12_file_data(file_data); return -1; } read_buffer = file_data->seq_read_buff; rec_len = pntoh32( read_buffer + K12_RECORD_LEN ); if (rec_len < K12_RECORD_TYPE + 4) { /* Record isn't long enough to have a type field */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: record length %u < %u", rec_len, K12_RECORD_TYPE + 4); return -1; } type = pntoh32( read_buffer + K12_RECORD_TYPE ); if ( (type & K12_MASK_PACKET) == K12_REC_PACKET || (type & K12_MASK_PACKET) == K12_REC_D0020) { /* * we are at the first packet record, rewind and leave. */ if (file_seek(wth->fh, offset, SEEK_SET, err) == -1) { destroy_k12_file_data(file_data); return -1; } K12_DBG(5,("k12_open: FIRST PACKET offset=%x",offset)); break; } else if (type == K12_REC_SRCDSC || type == K12_REC_SRCDSC2 ) { rec = g_new0(k12_src_desc_t,1); if (rec_len < K12_SRCDESC_HWPART) { /* * Record isn't long enough to have the fixed-length portion * of the source descriptor field. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u", rec_len, K12_SRCDESC_HWPART); destroy_k12_file_data(file_data); g_free(rec); return -1; } port_type = read_buffer[K12_SRCDESC_PORT_TYPE]; hwpart_len = pntoh16( read_buffer + K12_SRCDESC_HWPARTLEN ); name_len = pntoh16( read_buffer + K12_SRCDESC_NAMELEN ); stack_len = pntoh16( read_buffer + K12_SRCDESC_STACKLEN ); rec->input = pntoh32( read_buffer + K12_RECORD_SRC_ID ); K12_DBG(5,("k12_open: INTERFACE RECORD offset=%x interface=%x",offset,rec->input)); if (name_len == 0) { K12_DBG(5,("k12_open: failed (name_len == 0 in source description")); destroy_k12_file_data(file_data); g_free(rec); return 0; } if (stack_len == 0) { K12_DBG(5,("k12_open: failed (stack_len == 0 in source description")); destroy_k12_file_data(file_data); g_free(rec); return 0; } if (rec_len < K12_SRCDESC_HWPART + hwpart_len + name_len + stack_len) { /* * Record isn't long enough to have the full source descriptor * field, including the variable-length parts. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor record length %u < %u (%u + %u + %u + %u)", rec_len, K12_SRCDESC_HWPART + hwpart_len + name_len + stack_len, K12_SRCDESC_HWPART, hwpart_len, name_len, stack_len); destroy_k12_file_data(file_data); g_free(rec); return -1; } if (hwpart_len) { if (hwpart_len < 4) { /* Hardware part isn't long enough to have a type field */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor hardware part length %u < 4", hwpart_len); destroy_k12_file_data(file_data); g_free(rec); return -1; } switch(( rec->input_type = pntoh32( read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_HWPARTTYPE ) )) { case K12_PORT_DS0S: /* This appears to be variable-length */ rec->input_info.ds0mask = 0x00000000; if (hwpart_len > K12_SRCDESC_DS0_MASK) { for (i = 0; i < hwpart_len - K12_SRCDESC_DS0_MASK; i++) { rec->input_info.ds0mask |= ( *(read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_DS0_MASK + i) == 0xff ) ? 0x1<<(31-i) : 0x0; } } break; case K12_PORT_ATMPVC: if (hwpart_len < K12_SRCDESC_ATM_VCI + 2) { /* Hardware part isn't long enough to have ATM information */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("k12_open: source descriptor hardware part length %u < %u", hwpart_len, K12_SRCDESC_ATM_VCI + 2); destroy_k12_file_data(file_data); g_free(rec); return -1; } rec->input_info.atm.vp = pntoh16( read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_ATM_VPI ); rec->input_info.atm.vc = pntoh16( read_buffer + K12_SRCDESC_HWPART + K12_SRCDESC_ATM_VCI ); break; default: break; } } else { /* Record viewer generated files don't have this information */ if (port_type >= 0x14 && port_type <= 0x17) { /* For ATM2_E1DS1, ATM2_E3DS3, ATM2_STM1EL and ATM2_STM1OP */ rec->input_type = K12_PORT_ATMPVC; rec->input_info.atm.vp = 0; rec->input_info.atm.vc = 0; } } if (read_buffer[K12_SRCDESC_HWPART + hwpart_len + name_len - 1] != '\0') { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("k12_open: source descriptor record contains non-null-terminated link-layer name"); destroy_k12_file_data(file_data); g_free(rec); return -1; } if (read_buffer[K12_SRCDESC_HWPART + hwpart_len + name_len + stack_len - 1] != '\0') { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup("k12_open: source descriptor record contains non-null-terminated stack path"); destroy_k12_file_data(file_data); g_free(rec); return -1; } rec->input_name = (gchar *)g_memdup(read_buffer + K12_SRCDESC_HWPART + hwpart_len, name_len); rec->stack_file = (gchar *)g_memdup(read_buffer + K12_SRCDESC_HWPART + hwpart_len + name_len, stack_len); ascii_strdown_inplace (rec->stack_file); g_hash_table_insert(file_data->src_by_id,GUINT_TO_POINTER(rec->input),rec); g_hash_table_insert(file_data->src_by_name,rec->stack_file,rec); offset += len; continue; } else if (type == K12_REC_STK_FILE) { K12_DBG(1,("k12_open: K12_REC_STK_FILE")); K12_DBG(1,("Field 1: 0x%08x",pntoh32( read_buffer + 0x08 ))); K12_DBG(1,("Field 2: 0x%08x",pntoh32( read_buffer + 0x0c ))); K12_ASCII_DUMP(1, read_buffer, rec_len, 0x10); offset += len; continue; } else { K12_DBG(1,("k12_open: RECORD TYPE 0x%08x",type)); offset += len; continue; } } while(1); wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_K12; wth->file_encap = WTAP_ENCAP_K12; wth->snapshot_length = 0; wth->subtype_read = k12_read; wth->subtype_seek_read = k12_seek_read; wth->subtype_close = k12_close; wth->priv = (void *)file_data; wth->tsprecision = WTAP_FILE_TSPREC_NSEC; return 1; }