static gboolean snoop_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_header *pseudo_header, guint8 *pd, int length, int *err, gchar **err_info) { if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) return FALSE; switch (wth->file_encap) { case WTAP_ENCAP_ATM_PDUS: if (!snoop_read_atm_pseudoheader(wth->random_fh, pseudo_header, err, err_info)) { /* Read error */ return FALSE; } break; case WTAP_ENCAP_ETHERNET: /* * If this is a snoop file, we assume there's no FCS in * this frame; if this is a Shomit file, we assume there * is. (XXX - or should we treat it a "maybe"?) */ if (wth->file_type == WTAP_FILE_SHOMITI) pseudo_header->eth.fcs_len = 4; else pseudo_header->eth.fcs_len = 0; break; case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: if (!snoop_read_shomiti_wireless_pseudoheader(wth->random_fh, pseudo_header, err, err_info, NULL)) { /* Read error */ return FALSE; } break; } /* * Read the packet data. */ if (!snoop_read_rec_data(wth->random_fh, pd, length, err, err_info)) return FALSE; /* 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 && pseudo_header->atm.type == TRAF_LANE) atm_guess_lane_type(pd, length, pseudo_header); return TRUE; }
static gboolean btsnoop_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_header *pseudo_header, guint8 *pd, int length, int *err, gchar **err_info) { int bytes_read; struct btsnooprec_hdr hdr; guint32 flags; if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) return FALSE; /* Read record header. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&hdr, sizeof hdr, wth->random_fh); if (bytes_read != sizeof hdr) { *err = file_error(wth->random_fh, err_info); if (*err == 0 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } flags = g_ntohl(hdr.flags); /* * Read the packet data. */ if (!snoop_read_rec_data(wth->random_fh, pd, length, err, err_info)) return FALSE; /* failed */ if(wth->file_encap == WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR) { pseudo_header->p2p.sent = (flags & KHciLoggerControllerToHost) ? FALSE : TRUE; } else if(wth->file_encap == WTAP_ENCAP_BLUETOOTH_HCI) { pseudo_header->bthci.sent = (flags & KHciLoggerControllerToHost) ? FALSE : TRUE; if(flags & KHciLoggerCommandOrEvent) { if(pseudo_header->bthci.sent) { pseudo_header->bthci.channel = BTHCI_CHANNEL_COMMAND; } else { pseudo_header->bthci.channel = BTHCI_CHANNEL_EVENT; } } else { pseudo_header->bthci.channel = BTHCI_CHANNEL_ACL; } } return TRUE; }
static gboolean btsnoop_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { guint32 packet_size; guint32 flags; guint32 orig_size; int bytes_read; struct btsnooprec_hdr hdr; gint64 ts; /* As the send/receive flag is stored in the middle of the capture header but needs to go in the pseudo header for wiretap, the header needs to be reread in the seek_read function*/ *data_offset = wth->data_offset; /* Read record header. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&hdr, sizeof hdr, wth->fh); if (bytes_read != sizeof hdr) { *err = file_error(wth->fh, err_info); if (*err == 0 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } wth->data_offset += sizeof hdr; packet_size = g_ntohl(hdr.incl_len); orig_size = g_ntohl(hdr.orig_len); flags = g_ntohl(hdr.flags); if (packet_size > WTAP_MAX_PACKET_SIZE) { /* * Probably a corrupt capture file; don't blow up trying * to allocate space for an immensely-large packet. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("btsnoop: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return FALSE; } buffer_assure_space(wth->frame_buffer, packet_size); if (!snoop_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), packet_size, err, err_info)) { return FALSE; /* Read error */ } wth->data_offset += packet_size; ts = GINT64_FROM_BE(hdr.ts_usec); ts -= KUnixTimeBase; wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; wth->phdr.ts.secs = (guint)(ts / 1000000); wth->phdr.ts.nsecs = (guint)((ts % 1000000) * 1000); wth->phdr.caplen = packet_size; wth->phdr.len = orig_size; if(wth->file_encap == WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR) { wth->pseudo_header.p2p.sent = (flags & KHciLoggerControllerToHost) ? FALSE : TRUE; } else if(wth->file_encap == WTAP_ENCAP_BLUETOOTH_HCI) { wth->pseudo_header.bthci.sent = (flags & KHciLoggerControllerToHost) ? FALSE : TRUE; if(flags & KHciLoggerCommandOrEvent) { if(wth->pseudo_header.bthci.sent) { wth->pseudo_header.bthci.channel = BTHCI_CHANNEL_COMMAND; } else { wth->pseudo_header.bthci.channel = BTHCI_CHANNEL_EVENT; } } else { wth->pseudo_header.bthci.channel = BTHCI_CHANNEL_ACL; } } return TRUE; }
/* Read the next packet */ static gboolean snoop_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { guint32 rec_size; guint32 packet_size; guint32 orig_size; int bytes_read; struct snooprec_hdr hdr; char padbuf[4]; guint padbytes; int bytes_to_read; int header_size; /* Read record header. */ errno = WTAP_ERR_CANT_READ; bytes_read = file_read(&hdr, sizeof hdr, wth->fh); if (bytes_read != sizeof hdr) { *err = file_error(wth->fh, err_info); if (*err == 0 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } rec_size = g_ntohl(hdr.rec_len); orig_size = g_ntohl(hdr.orig_len); packet_size = g_ntohl(hdr.incl_len); if (orig_size > WTAP_MAX_PACKET_SIZE) { /* * Probably a corrupt capture file; don't blow up trying * to allocate space for an immensely-large packet. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("snoop: File has %u-byte original length, bigger than maximum of %u", orig_size, WTAP_MAX_PACKET_SIZE); return FALSE; } if (packet_size > WTAP_MAX_PACKET_SIZE) { /* * Probably a corrupt capture file; don't blow up trying * to allocate space for an immensely-large packet. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("snoop: File has %u-byte packet, bigger than maximum of %u", packet_size, WTAP_MAX_PACKET_SIZE); return FALSE; } if (packet_size > rec_size) { /* * Probably a corrupt capture file. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("snoop: File has %u-byte packet, bigger than record size %u", packet_size, rec_size); return FALSE; } *data_offset = file_tell(wth->fh); /* * If this is an ATM packet, the first four bytes are the * direction of the packet (transmit/receive), the VPI, and * the VCI; read them and generate the pseudo-header from * them. */ switch (wth->file_encap) { case WTAP_ENCAP_ATM_PDUS: if (packet_size < sizeof (struct snoop_atm_hdr)) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("snoop: atmsnoop file has a %u-byte packet, too small to have even an ATM pseudo-header", packet_size); return FALSE; } if (!snoop_read_atm_pseudoheader(wth->fh, &wth->pseudo_header, err, err_info)) return FALSE; /* Read error */ /* * Don't count the pseudo-header as part of the packet. */ rec_size -= (guint32)sizeof (struct snoop_atm_hdr); orig_size -= (guint32)sizeof (struct snoop_atm_hdr); packet_size -= (guint32)sizeof (struct snoop_atm_hdr); break; case WTAP_ENCAP_ETHERNET: /* * If this is a snoop file, we assume there's no FCS in * this frame; if this is a Shomit file, we assume there * is. (XXX - or should we treat it a "maybe"?) */ if (wth->file_type == WTAP_FILE_SHOMITI) wth->pseudo_header.eth.fcs_len = 4; else wth->pseudo_header.eth.fcs_len = 0; break; case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: if (packet_size < sizeof (shomiti_wireless_header)) { /* * Uh-oh, the packet isn't big enough to even * have a pseudo-header. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("snoop: Shomiti wireless file has a %u-byte packet, too small to have even a wireless pseudo-header", packet_size); return FALSE; } if (!snoop_read_shomiti_wireless_pseudoheader(wth->fh, &wth->pseudo_header, err, err_info, &header_size)) return FALSE; /* Read error */ /* * Don't count the pseudo-header as part of the packet. */ rec_size -= header_size; orig_size -= header_size; packet_size -= header_size; break; } buffer_assure_space(wth->frame_buffer, packet_size); if (!snoop_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), packet_size, err, err_info)) return FALSE; /* Read error */ wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; wth->phdr.ts.secs = g_ntohl(hdr.ts_sec); wth->phdr.ts.nsecs = g_ntohl(hdr.ts_usec) * 1000; wth->phdr.caplen = packet_size; wth->phdr.len = orig_size; /* * If this is ATM LANE traffic, try to guess what type of LANE * traffic it is based on the packet contents. */ if (wth->file_encap == WTAP_ENCAP_ATM_PDUS && wth->pseudo_header.atm.type == TRAF_LANE) { atm_guess_lane_type(buffer_start_ptr(wth->frame_buffer), wth->phdr.caplen, &wth->pseudo_header); } /* * Skip over the padding (don't "fseek()", as the standard * I/O library on some platforms discards buffered data if * you do that, which means it does a lot more reads). * There's probably not much padding (it's probably padded only * to a 4-byte boundary), so we probably need only do one read. */ if (rec_size < (sizeof hdr + packet_size)) { /* * What, *negative* padding? Bogus. */ *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("snoop: File has %u-byte record with packet size of %u", rec_size, packet_size); return FALSE; } padbytes = rec_size - ((guint)sizeof hdr + packet_size); while (padbytes != 0) { bytes_to_read = padbytes; if ((unsigned)bytes_to_read > sizeof padbuf) bytes_to_read = sizeof padbuf; errno = WTAP_ERR_CANT_READ; bytes_read = file_read(padbuf, bytes_to_read, wth->fh); if (bytes_read != bytes_to_read) { *err = file_error(wth->fh, err_info); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } padbytes -= bytes_read; } return TRUE; }