/* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on failure */ gboolean network_instruments_dump_open(wtap_dumper *wdh, gboolean cant_seek, int *err) { capture_file_header file_header; tlv_header comment_header; char comment[64]; struct tm *current_time; time_t system_time; niobserver_dump_t *niobserver; if (cant_seek) { *err = WTAP_ERR_CANT_WRITE_TO_PIPE; return FALSE; } wdh->subtype_write = observer_dump; niobserver = (niobserver_dump_t *)g_malloc(sizeof(niobserver_dump_t)); wdh->priv = (void *)niobserver; niobserver->packet_count = 0; niobserver->network_type = from_wtap_encap[wdh->encap]; /* create the file comment */ time(&system_time); current_time = localtime(&system_time); memset(&comment, 0x00, sizeof(comment)); g_snprintf(comment, 64, "This capture was saved from Wireshark on %s", asctime(current_time)); /* create the file header */ if (fseek(wdh->fh, 0, SEEK_SET) == -1) { *err = errno; return FALSE; } memset(&file_header, 0x00, sizeof(capture_file_header)); g_strlcpy(file_header.observer_version, network_instruments_magic, 32); file_header.offset_to_first_packet = (guint16) (sizeof(capture_file_header) + sizeof(tlv_header) + strlen(comment)); file_header.offset_to_first_packet = GUINT16_TO_LE(file_header.offset_to_first_packet); file_header.number_of_information_elements = 1; if(!fwrite(&file_header, sizeof(capture_file_header), 1, wdh->fh)) { *err = errno; return FALSE; } /* create the comment entry */ comment_header.type = GUINT16_TO_LE(INFORMATION_TYPE_COMMENT); comment_header.length = (guint16) (sizeof(tlv_header) + strlen(comment)); comment_header.length = GUINT16_TO_LE(comment_header.length); if(!fwrite(&comment_header, sizeof(tlv_header), 1, wdh->fh)) { *err = errno; return FALSE; } if(!fwrite(&comment, sizeof(char), strlen(comment), wdh->fh)) { *err = errno; return FALSE; } init_time_offset(); return TRUE; }
int network_instruments_open(wtap *wth, int *err, gchar **err_info) { int bytes_read; int offset; capture_file_header file_header; guint i; tlv_header tlvh; int seek_increment; packet_entry_header packet_header; errno = WTAP_ERR_CANT_READ; offset = 0; /* Read in the buffer file header */ bytes_read = file_read(&file_header, sizeof file_header, 1, wth->fh); if (bytes_read != sizeof file_header) { *err = file_error(wth->fh); if (*err != 0) return -1; return 0; } offset += bytes_read; /* check the magic number */ if (memcmp(file_header.observer_version, network_instruments_magic, true_magic_length)!=0) { return 0; } /* check the version */ if (strncmp(network_instruments_magic, file_header.observer_version, 30)!=0) { *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("Observer: unsupported file version %s", file_header.observer_version); return -1; } /* process extra information */ for (i = 0; i < file_header.number_of_information_elements; i++) { /* read the TLV header */ bytes_read = file_read(&tlvh, sizeof tlvh, 1, wth->fh); if (bytes_read != sizeof tlvh) { *err = file_error(wth->fh); if (*err == 0) *err = WTAP_ERR_SHORT_READ; return -1; } offset += bytes_read; tlvh.length = GUINT16_FROM_LE(tlvh.length); if (tlvh.length < sizeof tlvh) { *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup_printf("Observer: bad record (TLV length %u < %lu)", tlvh.length, (unsigned long)sizeof tlvh); return -1; } /* skip the TLV data */ seek_increment = tlvh.length - (int)sizeof tlvh; if (seek_increment > 0) { if (file_seek(wth->fh, seek_increment, SEEK_CUR, err) == -1) return -1; } offset += seek_increment; } /* get to the first packet */ file_header.offset_to_first_packet = GUINT16_FROM_LE(file_header.offset_to_first_packet); if (file_header.offset_to_first_packet < offset) { *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup_printf("Observer: bad record (offset to first packet %d < %d)", file_header.offset_to_first_packet, offset); return FALSE; } seek_increment = file_header.offset_to_first_packet - offset; if (seek_increment > 0) { if (file_seek(wth->fh, seek_increment, SEEK_CUR, err) == -1) return -1; } /* pull off the packet header */ bytes_read = file_read(&packet_header, sizeof packet_header, 1, wth->fh); if (bytes_read != sizeof packet_header) { *err = file_error(wth->fh); if (*err != 0) return -1; return 0; } /* check the packet's magic number; the magic number is all 8's, so the byte order doesn't matter */ if (packet_header.packet_magic != observer_packet_magic) { *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("Observer: unsupported packet version %ul", packet_header.packet_magic); return -1; } /* Check the data link type. */ if (packet_header.network_type >= NUM_OBSERVER_ENCAPS) { *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("Observer: network type %u unknown or unsupported", packet_header.network_type); return -1; } wth->file_encap = observer_encap[packet_header.network_type]; wth->file_type = WTAP_FILE_NETWORK_INSTRUMENTS_V9; /* set up the rest of the capture parameters */ wth->subtype_read = observer_read; wth->subtype_seek_read = observer_seek_read; wth->subtype_close = NULL; wth->subtype_sequential_close = NULL; wth->snapshot_length = 0; /* not available in header */ wth->tsprecision = WTAP_FILE_TSPREC_NSEC; /* reset the pointer to the first packet */ if (file_seek(wth->fh, file_header.offset_to_first_packet, SEEK_SET, err) == -1) return -1; wth->data_offset = file_header.offset_to_first_packet; init_time_offset(); return 1; }