diff options
Diffstat (limited to 'wiretap')
-rw-r--r-- | wiretap/ascend-grammar.y | 5 | ||||
-rw-r--r-- | wiretap/ascend-int.h | 5 | ||||
-rw-r--r-- | wiretap/ascend-scanner.l | 4 | ||||
-rw-r--r-- | wiretap/ascend.c | 14 | ||||
-rw-r--r-- | wiretap/ascend.h | 3 | ||||
-rw-r--r-- | wiretap/file.c | 36 | ||||
-rw-r--r-- | wiretap/i4btrace.c | 153 | ||||
-rw-r--r-- | wiretap/iptrace.c | 199 | ||||
-rw-r--r-- | wiretap/lanalyzer.c | 3 | ||||
-rw-r--r-- | wiretap/libpcap.c | 7 | ||||
-rw-r--r-- | wiretap/netmon.c | 7 | ||||
-rw-r--r-- | wiretap/nettl.c | 175 | ||||
-rw-r--r-- | wiretap/netxray.c | 7 | ||||
-rw-r--r-- | wiretap/ngsniffer.c | 321 | ||||
-rw-r--r-- | wiretap/radcom.c | 109 | ||||
-rw-r--r-- | wiretap/snoop.c | 149 | ||||
-rw-r--r-- | wiretap/toshiba.c | 59 | ||||
-rw-r--r-- | wiretap/toshiba.h | 3 | ||||
-rw-r--r-- | wiretap/wtap.c | 45 | ||||
-rw-r--r-- | wiretap/wtap.h | 26 |
20 files changed, 887 insertions, 443 deletions
diff --git a/wiretap/ascend-grammar.y b/wiretap/ascend-grammar.y index 4b0bd51363..41d7dad015 100644 --- a/wiretap/ascend-grammar.y +++ b/wiretap/ascend-grammar.y @@ -1,7 +1,7 @@ %{ /* ascend-grammar.y * - * $Id: ascend-grammar.y,v 1.10 2000/01/22 06:22:35 guy Exp $ + * $Id: ascend-grammar.y,v 1.11 2000/05/18 09:09:17 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -63,7 +63,6 @@ WD_DIALOUT_DISP: chunk 2515EE type IP. #define NFH_PATH "/dev/null" -extern void ascend_init_lexer(FILE *fh, FILE *nfh); extern int at_eof; int yyparse(void); @@ -232,7 +231,7 @@ init_parse_ascend() /* Parse the capture file. Return the offset of the next packet, or zero if there is none. */ int -parse_ascend(FILE *fh, void *pd, struct ascend_phdr *phdr, +parse_ascend(FILE_T *fh, void *pd, struct ascend_phdr *phdr, ascend_pkthdr *hdr, int len) { /* yydebug = 1; */ diff --git a/wiretap/ascend-int.h b/wiretap/ascend-int.h index 5ad414cd98..d376fe259e 100644 --- a/wiretap/ascend-int.h +++ b/wiretap/ascend-int.h @@ -2,7 +2,7 @@ * Definitions for routines common to multiple modules in the Lucent/Ascend * capture file reading code code, but not used outside that code. * - * $Id: ascend-int.h,v 1.4 1999/11/24 19:29:45 guy Exp $ + * $Id: ascend-int.h,v 1.5 2000/05/18 09:09:19 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -43,7 +43,8 @@ extern struct ascend_phdr *pseudo_header; int ascendlex(void); void init_parse_ascend(void); -int parse_ascend(FILE *fh, void *pd, struct ascend_phdr *phdr, +void ascend_init_lexer(FILE_T *fh, FILE *nfh); +int parse_ascend(FILE_T *fh, void *pd, struct ascend_phdr *phdr, ascend_pkthdr *hdr, int len); #endif /* ! __ASCEND_INT_H__ */ diff --git a/wiretap/ascend-scanner.l b/wiretap/ascend-scanner.l index 90baee246f..2121066120 100644 --- a/wiretap/ascend-scanner.l +++ b/wiretap/ascend-scanner.l @@ -1,7 +1,7 @@ %{ /* ascend-scanner.l * - * $Id: ascend-scanner.l,v 1.13 2000/02/15 21:06:58 gram Exp $ + * $Id: ascend-scanner.l,v 1.14 2000/05/18 09:09:21 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -253,7 +253,7 @@ task:|time:|octets { return KEYWORD; } int ascendwrap() { return 1; } -void ascend_init_lexer(FILE *fh, FILE *nfh) +void ascend_init_lexer(FILE_T *fh, FILE *nfh) { yyrestart(0); yyout = nfh; diff --git a/wiretap/ascend.c b/wiretap/ascend.c index a07178a0e8..f7484e7f71 100644 --- a/wiretap/ascend.c +++ b/wiretap/ascend.c @@ -1,6 +1,6 @@ /* ascend.c * - * $Id: ascend.c,v 1.14 2000/05/10 22:20:26 guy Exp $ + * $Id: ascend.c,v 1.15 2000/05/18 09:09:21 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -98,6 +98,8 @@ static const char ascend_w2magic[] = { 'W', 'D', '_', 'D', 'I', 'A', 'L', 'O', ' #define ASCEND_W2_SIZE (sizeof ascend_w2magic / sizeof ascend_w2magic[0]) static int ascend_read(wtap *wth, int *err); +static int ascend_seek_read (wtap *wth, int seek_off, + union pseudo_header *pseudo_header, guint8 *pd, int len); static void ascend_close(wtap *wth); /* Seeks to the beginning of the next packet, and returns the @@ -166,6 +168,7 @@ int ascend_open(wtap *wth, int *err) wth->file_type = WTAP_FILE_ASCEND; wth->snapshot_length = ASCEND_MAX_PKT_LEN; wth->subtype_read = ascend_read; + wth->subtype_seek_read = ascend_seek_read; wth->subtype_close = ascend_close; wth->capture.ascend = g_malloc(sizeof(ascend_t)); @@ -204,7 +207,7 @@ static int ascend_read(wtap *wth, int *err) if (offset < 1) { return 0; } - if (! parse_ascend(wth->fh, buf, &wth->phdr.pseudo_header.ascend, &header, 0)) { + if (! parse_ascend(wth->fh, buf, &wth->pseudo_header.ascend, &header, 0)) { *err = WTAP_ERR_BAD_RECORD; return -1; } @@ -225,10 +228,11 @@ static int ascend_read(wtap *wth, int *err) return offset; } -int ascend_seek_read (FILE *fh, int seek_off, guint8 *pd, int len) +static int ascend_seek_read (wtap *wth, int seek_off, + union pseudo_header *pseudo_header, guint8 *pd, int len) { - file_seek(fh, seek_off - 1, SEEK_SET); - return parse_ascend(fh, pd, NULL, NULL, len); + file_seek(wth->random_fh, seek_off - 1, SEEK_SET); + return parse_ascend(wth->random_fh, pd, &pseudo_header->ascend, NULL, len); } static void ascend_close(wtap *wth) diff --git a/wiretap/ascend.h b/wiretap/ascend.h index 6b13b928d6..5b908b9e93 100644 --- a/wiretap/ascend.h +++ b/wiretap/ascend.h @@ -1,6 +1,6 @@ /* ascend.h * - * $Id: ascend.h,v 1.5 2000/01/22 06:22:36 guy Exp $ + * $Id: ascend.h,v 1.6 2000/05/18 09:09:24 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -26,4 +26,3 @@ #define ASCEND_MAX_PKT_LEN (ASCEND_MAX_DATA_ROWS * ASCEND_MAX_DATA_COLS) int ascend_open(wtap *wth, int *err); -int ascend_seek_read (FILE *fh, int seek_off, guint8 *pd, int len); diff --git a/wiretap/file.c b/wiretap/file.c index 0d246e3555..bf4c4ee31d 100644 --- a/wiretap/file.c +++ b/wiretap/file.c @@ -1,6 +1,6 @@ /* file.c * - * $Id: file.c,v 1.50 2000/05/10 22:16:28 guy Exp $ + * $Id: file.c,v 1.51 2000/05/18 09:09:25 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -96,16 +96,24 @@ static int (*open_routines[])(wtap *, int *) = { i4btrace_open, }; -int wtap_def_seek_read (FILE *fh, int seek_off, guint8 *pd, int len) +int wtap_def_seek_read(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, guint8 *pd, int len) { - file_seek(fh, seek_off, SEEK_SET); - return file_read(pd, sizeof(guint8), len, fh); + file_seek(wth->random_fh, seek_off, SEEK_SET); + + return file_read(pd, sizeof(guint8), len, wth->random_fh); } #define N_FILE_TYPES (sizeof open_routines / sizeof open_routines[0]) -/* Opens a file and prepares a wtap struct */ -wtap* wtap_open_offline(const char *filename, int *err) +/* Opens a file and prepares a wtap struct. + If "do_random" is TRUE, it opens the file twice; the second open + allows the application to do random-access I/O without moving + the seek offset for sequential I/O, which is used by Ethereal + so that it can do sequential I/O to a capture file that's being + written to as new packets arrive independently of random I/O done + to display protocol trees for packets when they're selected. */ +wtap* wtap_open_offline(const char *filename, int *err, gboolean do_random) { struct stat statb; wtap *wth; @@ -148,6 +156,16 @@ wtap* wtap_open_offline(const char *filename, int *err) return NULL; } + if (do_random) { + if (!(wth->random_fh = file_open(filename, "rb"))) { + *err = errno; + file_close(wth->fh); + g_free(wth); + return NULL; + } + } else + wth->random_fh = NULL; + /* initialization */ wth->file_encap = WTAP_ENCAP_UNKNOWN; wth->data_offset = 0; @@ -174,6 +192,8 @@ wtap* wtap_open_offline(const char *filename, int *err) } /* Well, it's not one of the types of file we know about. */ + if (wth->random_fh != NULL) + file_close(wth->random_fh); file_close(wth->fh); g_free(wth); *err = WTAP_ERR_FILE_UNKNOWN_FORMAT; @@ -424,9 +444,9 @@ FILE* wtap_dump_file(wtap_dumper *wdh) } gboolean wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, - const u_char *pd, int *err) + const union pseudo_header *pseudo_header, const u_char *pd, int *err) { - return (wdh->subtype_write)(wdh, phdr, pd, err); + return (wdh->subtype_write)(wdh, phdr, pseudo_header, pd, err); } gboolean wtap_dump_close(wtap_dumper *wdh, int *err) diff --git a/wiretap/i4btrace.c b/wiretap/i4btrace.c index c03f7be871..04b52c4ff1 100644 --- a/wiretap/i4btrace.c +++ b/wiretap/i4btrace.c @@ -1,6 +1,6 @@ /* i4btrace.c * - * $Id: i4btrace.c,v 1.4 2000/04/15 21:12:37 guy Exp $ + * $Id: i4btrace.c,v 1.5 2000/05/18 09:09:27 guy Exp $ * * Wiretap Library * Copyright (c) 1999 by Bert Driehuis <driehuis@playbeing.org> @@ -33,6 +33,11 @@ #include "i4b_trace.h" static int i4btrace_read(wtap *wth, int *err); +static int i4btrace_seek_read(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int length); +static int i4b_read_rec_header(FILE_T *fh, i4b_trace_hdr_t *hdr, int *err); +static void i4b_byte_swap_header(wtap *wth, i4b_trace_hdr_t *hdr); +static int i4b_read_rec_data(FILE_T *fh, char *pd, int length, int *err); /* * Test some fields in the header to see if they make sense. @@ -91,6 +96,7 @@ int i4btrace_open(wtap *wth, int *err) wth->file_type = WTAP_FILE_I4BTRACE; wth->capture.i4btrace = g_malloc(sizeof(i4btrace_t)); wth->subtype_read = i4btrace_read; + wth->subtype_seek_read = i4btrace_seek_read; wth->snapshot_length = 2048; /* actual length set per packet */ wth->capture.i4btrace->bchannel_prot[0] = -1; @@ -107,39 +113,21 @@ int i4btrace_open(wtap *wth, int *err) /* Read the next packet */ static int i4btrace_read(wtap *wth, int *err) { - int bytes_read; + int record_offset; + int ret; i4b_trace_hdr_t hdr; guint16 length; - int data_offset; void *bufp; /* Read record header. */ - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh); - if (bytes_read != sizeof hdr) { - *err = file_error(wth->fh); - if (*err != 0) - return -1; - if (bytes_read != 0) { - *err = WTAP_ERR_SHORT_READ; - return -1; - } - return 0; + record_offset = wth->data_offset; + ret = i4b_read_rec_header(wth->fh, &hdr, err); + if (ret <= 0) { + /* Read error or EOF */ + return ret; } wth->data_offset += sizeof hdr; - if (wth->capture.i4btrace->byte_swapped) { - /* - * Byte-swap the header. - */ - hdr.length = BSWAP32(hdr.length); - hdr.unit = BSWAP32(hdr.unit); - hdr.type = BSWAP32(hdr.type); - hdr.dir = BSWAP32(hdr.dir); - hdr.trunc = BSWAP32(hdr.trunc); - hdr.count = BSWAP32(hdr.count); - hdr.time.tv_sec = BSWAP32(hdr.time.tv_sec); - hdr.time.tv_usec = BSWAP32(hdr.time.tv_usec); - } + i4b_byte_swap_header(wth, &hdr); length = hdr.length - sizeof(hdr); if (length == 0) return 0; @@ -150,23 +138,15 @@ static int i4btrace_read(wtap *wth, int *err) wth->phdr.ts.tv_sec = hdr.time.tv_sec; wth->phdr.ts.tv_usec = hdr.time.tv_usec; - wth->phdr.pseudo_header.x25.flags = (hdr.dir == FROM_TE) ? 0x00 : 0x80; + wth->pseudo_header.x25.flags = (hdr.dir == FROM_TE) ? 0x00 : 0x80; /* * Read the packet data. */ buffer_assure_space(wth->frame_buffer, length); - data_offset = wth->data_offset; - errno = WTAP_ERR_CANT_READ; bufp = buffer_start_ptr(wth->frame_buffer); - bytes_read = file_read(bufp, 1, length, wth->fh); - - if (bytes_read != length) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return -1; - } + if (i4b_read_rec_data(wth->fh, bufp, length, err) < 0) + return -1; /* Read error */ wth->data_offset += length; /* @@ -200,5 +180,100 @@ static int i4btrace_read(wtap *wth, int *err) wth->phdr.pkt_encap = WTAP_ENCAP_NULL; } - return data_offset; + /* + * XXX - there is no file header for i4btrace files, so the + * first record begins at the beginning of the file, hence + * its offset is 0. + * + * Unfortunately, a return value of 0 means "end of file". + * + * Therefore, we return the record offset + 1, and compensate + * for that in "i4btrace_seek_read()". + */ + return record_offset + 1; +} + +static int +i4btrace_seek_read(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int length) +{ + int ret; + int err; /* XXX - return this */ + i4b_trace_hdr_t hdr; + + /* + * We subtract 1 because we added 1 before returning the record + * offset in "i4btrace_read()"; see the comment above. + */ + file_seek(wth->random_fh, seek_off - 1, SEEK_SET); + + /* Read record header. */ + ret = i4b_read_rec_header(wth->random_fh, &hdr, &err); + if (ret <= 0) { + /* Read error or EOF */ + return ret; + } + i4b_byte_swap_header(wth, &hdr); + + pseudo_header->x25.flags = (hdr.dir == FROM_TE) ? 0x00 : 0x80; + + /* + * Read the packet data. + */ + return i4b_read_rec_data(wth->random_fh, pd, length, &err); +} + +static int +i4b_read_rec_header(FILE_T *fh, i4b_trace_hdr_t *hdr, int *err) +{ + int bytes_read; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(hdr, 1, sizeof *hdr, fh); + if (bytes_read != sizeof *hdr) { + *err = file_error(fh); + if (*err != 0) + return -1; + if (bytes_read != 0) { + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; + } + return 1; +} + +static void +i4b_byte_swap_header(wtap *wth, i4b_trace_hdr_t *hdr) +{ + if (wth->capture.i4btrace->byte_swapped) { + /* + * Byte-swap the header. + */ + hdr->length = BSWAP32(hdr->length); + hdr->unit = BSWAP32(hdr->unit); + hdr->type = BSWAP32(hdr->type); + hdr->dir = BSWAP32(hdr->dir); + hdr->trunc = BSWAP32(hdr->trunc); + hdr->count = BSWAP32(hdr->count); + hdr->time.tv_sec = BSWAP32(hdr->time.tv_sec); + hdr->time.tv_usec = BSWAP32(hdr->time.tv_usec); + } +} + +static int +i4b_read_rec_data(FILE_T *fh, char *pd, int length, int *err) +{ + int bytes_read; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(pd, 1, length, fh); + + if (bytes_read != length) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; } diff --git a/wiretap/iptrace.c b/wiretap/iptrace.c index a4f97ac6aa..79eeb1336b 100644 --- a/wiretap/iptrace.c +++ b/wiretap/iptrace.c @@ -1,6 +1,6 @@ /* iptrace.c * - * $Id: iptrace.c,v 1.26 2000/03/30 21:41:11 gram Exp $ + * $Id: iptrace.c,v 1.27 2000/05/18 09:09:30 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -33,9 +33,18 @@ #include "iptrace.h" static int iptrace_read_1_0(wtap *wth, int *err); +static int iptrace_seek_read_1_0(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int packet_size); static int iptrace_read_2_0(wtap *wth, int *err); +static int iptrace_seek_read_2_0(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int packet_size); +static int iptrace_read_rec_header(FILE_T *fh, guint8 *header, int header_len, + int *err); +static int iptrace_read_rec_data(FILE_T *fh, guint8 *data_ptr, int packet_size, + int *err); +static void get_atm_pseudo_header(union pseudo_header *pseudo_header, + guint8 *header); static int wtap_encap_ift(unsigned int ift); -static void get_atm_pseudo_header(wtap *wth, guint8 *header, guint8 *pd); int iptrace_open(wtap *wth, int *err) { @@ -58,10 +67,12 @@ int iptrace_open(wtap *wth, int *err) if (strcmp(name, "iptrace 1.0") == 0) { wth->file_type = WTAP_FILE_IPTRACE_1_0; wth->subtype_read = iptrace_read_1_0; + wth->subtype_seek_read = iptrace_seek_read_1_0; } else if (strcmp(name, "iptrace 2.0") == 0) { wth->file_type = WTAP_FILE_IPTRACE_2_0; wth->subtype_read = iptrace_read_2_0; + wth->subtype_seek_read = iptrace_seek_read_2_0; } else { return 0; @@ -88,49 +99,30 @@ typedef struct { /* Read the next packet */ static int iptrace_read_1_0(wtap *wth, int *err) { - int bytes_read; - int data_offset; + int record_offset; + int ret; guint32 packet_size; guint8 header[30]; guint8 *data_ptr; iptrace_1_0_phdr pkt_hdr; /* Read the descriptor data */ - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(header, 1, 30, wth->fh); - if (bytes_read != 30) { - *err = file_error(wth->fh); - if (*err != 0) - return -1; - if (bytes_read != 0) { - *err = WTAP_ERR_SHORT_READ; - return -1; - } - return 0; + record_offset = wth->data_offset; + ret = iptrace_read_rec_header(wth->fh, header, 30, err); + if (ret <= 0) { + /* Read error or EOF */ + return ret; } wth->data_offset += 30; /* Read the packet data */ packet_size = pntohl(&header[0]) - 0x16; buffer_assure_space( wth->frame_buffer, packet_size ); - data_offset = wth->data_offset; - errno = WTAP_ERR_CANT_READ; data_ptr = buffer_start_ptr( wth->frame_buffer ); - bytes_read = file_read( data_ptr, 1, packet_size, wth->fh ); - - if (bytes_read != packet_size) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return -1; - } + if (iptrace_read_rec_data(wth->fh, data_ptr, packet_size, err) < 0) + return -1; /* Read error */ wth->data_offset += packet_size; - - /* AIX saves time in nsec, not usec. It's easier to make iptrace - * files more Unix-compliant here than try to get the calling - * program to know when to use nsec or usec */ - wth->phdr.len = packet_size; wth->phdr.caplen = packet_size; wth->phdr.ts.tv_sec = pntohl(&header[4]); @@ -152,7 +144,7 @@ static int iptrace_read_1_0(wtap *wth, int *err) } if ( wth->phdr.pkt_encap == WTAP_ENCAP_ATM_SNIFFER ) { - get_atm_pseudo_header(wth, header, data_ptr); + get_atm_pseudo_header(&wth->pseudo_header, header); } /* If the per-file encapsulation isn't known, set it to this @@ -168,7 +160,31 @@ static int iptrace_read_1_0(wtap *wth, int *err) wth->file_encap = WTAP_ENCAP_PER_PACKET; } - return data_offset; + return record_offset; +} + +static int iptrace_seek_read_1_0(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int packet_size) +{ + int ret; + int err; /* XXX - return this */ + guint8 header[30]; + + file_seek(wth->random_fh, seek_off, SEEK_SET); + + /* Read the descriptor data */ + ret = iptrace_read_rec_header(wth->random_fh, header, 30, &err); + if (ret <= 0) { + /* Read error or EOF */ + return ret; + } + + if ( wtap_encap_ift(header[28]) == WTAP_ENCAP_ATM_SNIFFER ) { + get_atm_pseudo_header(pseudo_header, header); + } + + /* Read the packet data */ + return iptrace_read_rec_data(wth->random_fh, pd, packet_size, &err); } /*********************************************************** @@ -192,45 +208,30 @@ typedef struct { /* Read the next packet */ static int iptrace_read_2_0(wtap *wth, int *err) { - int bytes_read; - int data_offset; + int record_offset; + int ret; guint32 packet_size; guint8 header[40]; guint8 *data_ptr; iptrace_2_0_phdr pkt_hdr; /* Read the descriptor data */ - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(header, 1, 40, wth->fh); - if (bytes_read != 40) { - *err = file_error(wth->fh); - if (*err != 0) - return -1; - if (bytes_read != 0) { - *err = WTAP_ERR_SHORT_READ; - return -1; - } - return 0; + record_offset = wth->data_offset; + ret = iptrace_read_rec_header(wth->fh, header, 40, err); + if (ret <= 0) { + /* Read error or EOF */ + return ret; } wth->data_offset += 40; /* Read the packet data */ packet_size = pntohl(&header[0]) - 32; buffer_assure_space( wth->frame_buffer, packet_size ); - data_offset = wth->data_offset; - errno = WTAP_ERR_CANT_READ; data_ptr = buffer_start_ptr( wth->frame_buffer ); - bytes_read = file_read( data_ptr, 1, packet_size, wth->fh ); - - if (bytes_read != packet_size) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return -1; - } + if (iptrace_read_rec_data(wth->fh, data_ptr, packet_size, err) < 0) + return -1; /* Read error */ wth->data_offset += packet_size; - /* AIX saves time in nsec, not usec. It's easier to make iptrace * files more Unix-compliant here than try to get the calling * program to know when to use nsec or usec */ @@ -256,7 +257,7 @@ static int iptrace_read_2_0(wtap *wth, int *err) } if ( wth->phdr.pkt_encap == WTAP_ENCAP_ATM_SNIFFER ) { - get_atm_pseudo_header(wth, header, data_ptr); + get_atm_pseudo_header(&wth->pseudo_header, header); } /* If the per-file encapsulation isn't known, set it to this @@ -272,7 +273,68 @@ static int iptrace_read_2_0(wtap *wth, int *err) wth->file_encap = WTAP_ENCAP_PER_PACKET; } - return data_offset; + return record_offset; +} + +static int iptrace_seek_read_2_0(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int packet_size) +{ + int ret; + int err; /* XXX - return this */ + guint8 header[40]; + + file_seek(wth->random_fh, seek_off, SEEK_SET); + + /* Read the descriptor data */ + ret = iptrace_read_rec_header(wth->random_fh, header, 40, &err); + if (ret <= 0) { + /* Read error or EOF */ + return ret; + } + + if ( wtap_encap_ift(header[28]) == WTAP_ENCAP_ATM_SNIFFER ) { + get_atm_pseudo_header(pseudo_header, header); + } + + /* Read the packet data */ + return iptrace_read_rec_data(wth->random_fh, pd, packet_size, &err); +} + +static int +iptrace_read_rec_header(FILE_T *fh, guint8 *header, int header_len, int *err) +{ + int bytes_read; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(header, 1, header_len, fh); + if (bytes_read != header_len) { + *err = file_error(fh); + if (*err != 0) + return -1; + if (bytes_read != 0) { + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; + } + return 1; +} + +static int +iptrace_read_rec_data(FILE_T *fh, guint8 *data_ptr, int packet_size, int *err) +{ + int bytes_read; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read( data_ptr, 1, packet_size, fh ); + + if (bytes_read != packet_size) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; } /* @@ -292,7 +354,7 @@ static int iptrace_read_2_0(wtap *wth, int *err) * in some fashion what sort of traffic it is, or being told by the user. */ static void -get_atm_pseudo_header(wtap *wth, guint8 *header, guint8 *pd) +get_atm_pseudo_header(union pseudo_header *pseudo_header, guint8 *header) { char if_text[9]; char *decimal; @@ -309,26 +371,25 @@ get_atm_pseudo_header(wtap *wth, guint8 *header, guint8 *pd) decimal++; Vci = strtoul(decimal, NULL, 10); } - wth->phdr.pseudo_header.ngsniffer_atm.Vpi = Vpi; - wth->phdr.pseudo_header.ngsniffer_atm.Vci = Vci; + pseudo_header->ngsniffer_atm.Vpi = Vpi; + pseudo_header->ngsniffer_atm.Vci = Vci; /* * OK, which value means "DTE->DCE" and which value means * "DCE->DTE"? */ - wth->phdr.pseudo_header.ngsniffer_atm.channel = header[29]; + pseudo_header->ngsniffer_atm.channel = header[29]; /* We don't have this information */ - wth->phdr.pseudo_header.ngsniffer_atm.cells = 0; - wth->phdr.pseudo_header.ngsniffer_atm.aal5t_u2u = 0; - wth->phdr.pseudo_header.ngsniffer_atm.aal5t_len = 0; - wth->phdr.pseudo_header.ngsniffer_atm.aal5t_chksum = 0; + pseudo_header->ngsniffer_atm.cells = 0; + pseudo_header->ngsniffer_atm.aal5t_u2u = 0; + pseudo_header->ngsniffer_atm.aal5t_len = 0; + pseudo_header->ngsniffer_atm.aal5t_chksum = 0; /* Assume it's AAL5 traffic, but indicate that we don't know what it is beyond that. */ - wth->phdr.pseudo_header.ngsniffer_atm.AppTrafType = - ATT_AAL5|ATT_HL_UNKNOWN; - wth->phdr.pseudo_header.ngsniffer_atm.AppHLType = AHLT_UNKNOWN; + pseudo_header->ngsniffer_atm.AppTrafType = ATT_AAL5|ATT_HL_UNKNOWN; + pseudo_header->ngsniffer_atm.AppHLType = AHLT_UNKNOWN; } /* Given an RFC1573 (SNMP ifType) interface type, diff --git a/wiretap/lanalyzer.c b/wiretap/lanalyzer.c index 29ab094361..68b1378b75 100644 --- a/wiretap/lanalyzer.c +++ b/wiretap/lanalyzer.c @@ -1,6 +1,6 @@ /* lanalyzer.c * - * $Id: lanalyzer.c,v 1.21 2000/03/22 07:06:58 guy Exp $ + * $Id: lanalyzer.c,v 1.22 2000/05/18 09:09:31 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -87,6 +87,7 @@ int lanalyzer_open(wtap *wth, int *err) wth->file_type = WTAP_FILE_LANALYZER; wth->capture.lanalyzer = g_malloc(sizeof(lanalyzer_t)); wth->subtype_read = lanalyzer_read; + wth->subtype_seek_read = wtap_def_seek_read; wth->subtype_close = lanalyzer_close; wth->snapshot_length = 0; diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c index 822b2faaed..737cab784a 100644 --- a/wiretap/libpcap.c +++ b/wiretap/libpcap.c @@ -1,6 +1,6 @@ /* libpcap.c * - * $Id: libpcap.c,v 1.33 2000/03/22 07:06:58 guy Exp $ + * $Id: libpcap.c,v 1.34 2000/05/18 09:09:32 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -90,7 +90,7 @@ static int libpcap_read(wtap *wth, int *err); static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr); static void libpcap_close(wtap *wth); static gboolean libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, - const u_char *pd, int *err); + const union pseudo_header *pseudo_header, const u_char *pd, int *err); /* * XXX - this is a bit of a mess. OpenBSD, and perhaps NetBSD, and @@ -260,6 +260,7 @@ int libpcap_open(wtap *wth, int *err) wth->capture.pcap->version_major = hdr.version_major; wth->capture.pcap->version_minor = hdr.version_minor; wth->subtype_read = libpcap_read; + wth->subtype_seek_read = wtap_def_seek_read; wth->subtype_close = libpcap_close; wth->file_encap = pcap_encap[hdr.network]; wth->snapshot_length = hdr.snaplen; @@ -563,7 +564,7 @@ gboolean libpcap_dump_open(wtap_dumper *wdh, int *err) /* Write a record for a packet to a dump file. Returns TRUE on success, FALSE on failure. */ static gboolean libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, - const u_char *pd, int *err) + const union pseudo_header *pseudo_header, const u_char *pd, int *err) { struct pcaprec_modified_hdr rec_hdr; int hdr_size; diff --git a/wiretap/netmon.c b/wiretap/netmon.c index 0189a32cf6..8154babf2b 100644 --- a/wiretap/netmon.c +++ b/wiretap/netmon.c @@ -1,6 +1,6 @@ /* netmon.c * - * $Id: netmon.c,v 1.29 2000/05/10 22:16:29 guy Exp $ + * $Id: netmon.c,v 1.30 2000/05/18 09:09:36 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -97,7 +97,7 @@ struct netmonrec_2_x_hdr { static int netmon_read(wtap *wth, int *err); static void netmon_close(wtap *wth); static gboolean netmon_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, - const u_char *pd, int *err); + const union pseudo_header *pseudo_header, const u_char *pd, int *err); static gboolean netmon_dump_close(wtap_dumper *wdh, int *err); int netmon_open(wtap *wth, int *err) @@ -186,6 +186,7 @@ int netmon_open(wtap *wth, int *err) wth->file_type = file_type; wth->capture.netmon = g_malloc(sizeof(netmon_t)); wth->subtype_read = netmon_read; + wth->subtype_seek_read = wtap_def_seek_read; wth->subtype_close = netmon_close; wth->file_encap = netmon_encap[hdr.network]; wth->snapshot_length = 16384; /* XXX - not available in header */ @@ -471,7 +472,7 @@ gboolean netmon_dump_open(wtap_dumper *wdh, int *err) /* Write a record for a packet to a dump file. Returns TRUE on success, FALSE on failure. */ static gboolean netmon_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, - const u_char *pd, int *err) + const union pseudo_header *pseudo_header, const u_char *pd, int *err) { netmon_dump_t *netmon = wdh->dump.netmon; struct netmonrec_1_x_hdr rec_1_x_hdr; diff --git a/wiretap/nettl.c b/wiretap/nettl.c index 2748809e69..c89bfb433e 100644 --- a/wiretap/nettl.c +++ b/wiretap/nettl.c @@ -1,6 +1,6 @@ /* nettl.c * - * $Id: nettl.c,v 1.10 2000/04/15 21:12:37 guy Exp $ + * $Id: nettl.c,v 1.11 2000/05/18 09:09:38 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -65,6 +65,12 @@ struct nettlrec_ns_ls_ip_hdr { /* header is followed by data and once again the total length (2 bytes) ! */ static int nettl_read(wtap *wth, int *err); +static int nettl_seek_read(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int length); +static int nettl_read_rec_header(wtap *wth, FILE_T *fh, + struct wtap_pkthdr *phdr, union pseudo_header *pseudo_header, + int *err); +static int nettl_read_rec_data(FILE_T *fh, char *pd, int length, int *err); static void nettl_close(wtap *wth); int nettl_open(wtap *wth, int *err) @@ -109,6 +115,7 @@ int nettl_open(wtap *wth, int *err) else wth->capture.nettl->is_hpux_11 = FALSE; wth->subtype_read = nettl_read; + wth->subtype_seek_read = nettl_seek_read; wth->subtype_close = nettl_close; wth->snapshot_length = 16384; /* not available in header, only in frame */ @@ -118,19 +125,70 @@ int nettl_open(wtap *wth, int *err) /* Read the next packet */ static int nettl_read(wtap *wth, int *err) { - int bytes_read; + int record_offset; + int ret; + + /* Read record header. */ + record_offset = wth->data_offset; + ret = nettl_read_rec_header(wth, wth->fh, &wth->phdr, &wth->pseudo_header, + err); + if (ret <= 0) { + /* Read error or EOF */ + return ret; + } + wth->data_offset += ret; + + /* + * Read the packet data. + */ + buffer_assure_space(wth->frame_buffer, wth->phdr.caplen); + if (nettl_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), + wth->phdr.caplen, err) < 0) + return -1; /* Read error */ + wth->data_offset += wth->phdr.caplen; + return record_offset; +} + +static int +nettl_seek_read(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int length) +{ + int ret; + int err; /* XXX - return this */ + struct wtap_pkthdr phdr; + + file_seek(wth->random_fh, seek_off, SEEK_SET); + + /* Read record header. */ + ret = nettl_read_rec_header(wth, wth->random_fh, &phdr, pseudo_header, + &err); + if (ret <= 0) { + /* Read error or EOF */ + return ret; + } + + /* + * Read the packet data. + */ + return nettl_read_rec_data(wth->random_fh, pd, length, &err); +} + +static int +nettl_read_rec_header(wtap *wth, FILE_T *fh, struct wtap_pkthdr *phdr, + union pseudo_header *pseudo_header, int *err) +{ + int bytes_read; struct nettlrec_sx25l2_hdr lapb_hdr; struct nettlrec_ns_ls_ip_hdr ip_hdr; guint16 length; - int data_offset; + int offset = 0; guint8 encap[4]; guint8 dummy[4]; - /* Read record header. */ errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(encap, 1, 4, wth->fh); + bytes_read = file_read(encap, 1, 4, fh); if (bytes_read != 4) { - *err = file_error(wth->fh); + *err = file_error(fh); if (*err != 0) return -1; if (bytes_read != 0) { @@ -139,13 +197,14 @@ static int nettl_read(wtap *wth, int *err) } return 0; } - wth->data_offset += 4; + offset += 4; + switch (encap[3]) { case NETTL_SUBSYS_NS_LS_IP : - wth->phdr.pkt_encap = WTAP_ENCAP_RAW_IP; - bytes_read = file_read(&ip_hdr, 1, sizeof ip_hdr, wth->fh); + phdr->pkt_encap = WTAP_ENCAP_RAW_IP; + bytes_read = file_read(&ip_hdr, 1, sizeof ip_hdr, fh); if (bytes_read != sizeof ip_hdr) { - *err = file_error(wth->fh); + *err = file_error(fh); if (*err != 0) return -1; if (bytes_read != 0) { @@ -154,14 +213,14 @@ static int nettl_read(wtap *wth, int *err) } return 0; } - wth->data_offset += sizeof ip_hdr; + offset += sizeof ip_hdr; /* The packet header in HP-UX 11 nettl traces is 4 octets longer than * HP-UX 9 and 10 */ if (wth->capture.nettl->is_hpux_11) { - bytes_read = file_read(dummy, 1, 4, wth->fh); + bytes_read = file_read(dummy, 1, 4, fh); if (bytes_read != 4) { - *err = file_error(wth->fh); + *err = file_error(fh); if (*err != 0) return -1; if (bytes_read != 0) { @@ -170,39 +229,22 @@ static int nettl_read(wtap *wth, int *err) } return 0; } - wth->data_offset += 4; + offset += 4; } length = pntohl(&ip_hdr.length); if (length <= 0) return 0; - wth->phdr.len = length; - wth->phdr.caplen = length; - - wth->phdr.ts.tv_sec = pntohl(&ip_hdr.sec); - wth->phdr.ts.tv_usec = pntohl(&ip_hdr.usec); - - /* - * Read the packet data. - */ - buffer_assure_space(wth->frame_buffer, length); - data_offset = wth->data_offset; - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1, - length, wth->fh); - - if (bytes_read != length) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return -1; - } - wth->data_offset += length; + phdr->len = length; + phdr->caplen = length; + + phdr->ts.tv_sec = pntohl(&ip_hdr.sec); + phdr->ts.tv_usec = pntohl(&ip_hdr.usec); break; case NETTL_SUBSYS_SX25L2 : - wth->phdr.pkt_encap = WTAP_ENCAP_LAPB; - bytes_read = file_read(&lapb_hdr, 1, sizeof lapb_hdr, wth->fh); + phdr->pkt_encap = WTAP_ENCAP_LAPB; + bytes_read = file_read(&lapb_hdr, 1, sizeof lapb_hdr, fh); if (bytes_read != sizeof lapb_hdr) { - *err = file_error(wth->fh); + *err = file_error(fh); if (*err != 0) return -1; if (bytes_read != 0) { @@ -211,12 +253,12 @@ static int nettl_read(wtap *wth, int *err) } return 0; } - wth->data_offset += sizeof lapb_hdr; + offset += sizeof lapb_hdr; if (wth->capture.nettl->is_hpux_11) { - bytes_read = file_read(dummy, 1, 4, wth->fh); + bytes_read = file_read(dummy, 1, 4, fh); if (bytes_read != 4) { - *err = file_error(wth->fh); + *err = file_error(fh); if (*err != 0) return -1; if (bytes_read != 0) { @@ -225,34 +267,17 @@ static int nettl_read(wtap *wth, int *err) } return 0; } - wth->data_offset += 4; + offset += 4; } length = pntohs(&lapb_hdr.length); if (length <= 0) return 0; - wth->phdr.len = length; - wth->phdr.caplen = length; - - wth->phdr.ts.tv_sec = pntohl(&lapb_hdr.sec); - wth->phdr.ts.tv_usec = pntohl(&lapb_hdr.usec); - wth->phdr.pseudo_header.x25.flags = (lapb_hdr.from_dce & 0x20 ? 0x80 : 0x00); - - /* - * Read the packet data. - */ - buffer_assure_space(wth->frame_buffer, length); - data_offset = wth->data_offset; - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1, - length, wth->fh); - - if (bytes_read != length) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return -1; - } - wth->data_offset += length; + phdr->len = length; + phdr->caplen = length; + + phdr->ts.tv_sec = pntohl(&lapb_hdr.sec); + phdr->ts.tv_usec = pntohl(&lapb_hdr.usec); + pseudo_header->x25.flags = (lapb_hdr.from_dce & 0x20 ? 0x80 : 0x00); break; default: g_message("nettl: network type %u unknown or unsupported", @@ -260,7 +285,23 @@ static int nettl_read(wtap *wth, int *err) *err = WTAP_ERR_UNSUPPORTED_ENCAP; return -1; } - return data_offset; + return offset; +} + +static int +nettl_read_rec_data(FILE_T *fh, char *pd, int length, int *err) +{ + int bytes_read; + + bytes_read = file_read(pd, 1, length, fh); + + if (bytes_read != length) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; } static void nettl_close(wtap *wth) diff --git a/wiretap/netxray.c b/wiretap/netxray.c index 54aa410410..400d002ffc 100644 --- a/wiretap/netxray.c +++ b/wiretap/netxray.c @@ -1,6 +1,6 @@ /* netxray.c * - * $Id: netxray.c,v 1.26 2000/05/10 22:16:29 guy Exp $ + * $Id: netxray.c,v 1.27 2000/05/18 09:09:39 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -93,7 +93,7 @@ struct netxrayrec_2_x_hdr { static int netxray_read(wtap *wth, int *err); static void netxray_close(wtap *wth); static gboolean netxray_dump_1_1(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, - const u_char *pd, int *err); + const union pseudo_header *pseudo_header, const u_char *pd, int *err); static gboolean netxray_dump_close_1_1(wtap_dumper *wdh, int *err); int netxray_open(wtap *wth, int *err) @@ -187,6 +187,7 @@ int netxray_open(wtap *wth, int *err) wth->file_type = file_type; wth->capture.netxray = g_malloc(sizeof(netxray_t)); wth->subtype_read = netxray_read; + wth->subtype_seek_read = wtap_def_seek_read; wth->subtype_close = netxray_close; wth->file_encap = netxray_encap[hdr.network]; wth->snapshot_length = 16384; /* XXX - not available in header */ @@ -361,7 +362,7 @@ gboolean netxray_dump_open_1_1(wtap_dumper *wdh, int *err) /* Write a record for a packet to a dump file. Returns TRUE on success, FALSE on failure. */ static gboolean netxray_dump_1_1(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, - const u_char *pd, int *err) + const union pseudo_header *pseudo_header, const u_char *pd, int *err) { netxray_dump_t *netxray = wdh->dump.netxray; guint32 timestamp; diff --git a/wiretap/ngsniffer.c b/wiretap/ngsniffer.c index add033c0e2..908e645a65 100644 --- a/wiretap/ngsniffer.c +++ b/wiretap/ngsniffer.c @@ -1,6 +1,6 @@ /* ngsniffer.c * - * $Id: ngsniffer.c,v 1.39 2000/05/12 22:12:21 guy Exp $ + * $Id: ngsniffer.c,v 1.40 2000/05/18 09:09:41 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -247,9 +247,22 @@ struct frame4_rec { static double Usec[] = { 15.0, 0.838096, 15.0, 0.5, 2.0, 1.0, 0.1 }; static int ngsniffer_read(wtap *wth, int *err); +static int ngsniffer_seek_read(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int packet_size); +static int ngsniffer_read_rec_header(FILE_T *fh, guint16 *typep, + guint16 *lengthp, int *err); +static int ngsniffer_read_frame2(FILE_T *fh, struct frame2_rec *frame2, + int *err); +static void set_pseudo_header_frame2(union pseudo_header *pseudo_header, + struct frame2_rec *frame2); +static int ngsniffer_read_frame4(FILE_T *fh, struct frame4_rec *frame4, + int *err); +static void set_pseudo_header_frame4(union pseudo_header *pseudo_header, + struct frame4_rec *frame4); +static int ngsniffer_read_rec_data(FILE_T *fh, char *pd, int length, int *err); static void ngsniffer_close(wtap *wth); static gboolean ngsniffer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, - const u_char *pd, int *err); + const union pseudo_header *pseudo_header, const u_char *pd, int *err); static gboolean ngsniffer_dump_close(wtap_dumper *wdh, int *err); int ngsniffer_open(wtap *wth, int *err) @@ -371,6 +384,7 @@ int ngsniffer_open(wtap *wth, int *err) wth->file_type = WTAP_FILE_NGSNIFFER; wth->capture.ngsniffer = g_malloc(sizeof(ngsniffer_t)); wth->subtype_read = ngsniffer_read; + wth->subtype_seek_read = ngsniffer_seek_read; wth->subtype_close = ngsniffer_close; wth->snapshot_length = 16384; /* not available in header, only in frame */ wth->capture.ngsniffer->timeunit = Usec[version.timeunit]; @@ -415,46 +429,26 @@ int ngsniffer_open(wtap *wth, int *err) /* Read the next packet */ static int ngsniffer_read(wtap *wth, int *err) { - int bytes_read; - char record_type[2]; - char record_length[4]; /* only 1st 2 bytes are length */ + int record_offset; + int ret; guint16 type, length; struct frame2_rec frame2; struct frame4_rec frame4; double t; guint16 time_low, time_med, time_high, true_size, size; - int data_offset; u_char *pd; for (;;) { /* * Read the record header. */ - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(record_type, 1, 2, wth->fh); - if (bytes_read != 2) { - *err = file_error(wth->fh); - if (*err != 0) - return -1; - if (bytes_read != 0) { - *err = WTAP_ERR_SHORT_READ; - return -1; - } - return 0; + record_offset = wth->data_offset; + ret = ngsniffer_read_rec_header(wth->fh, &type, &length, err); + if (ret <= 0) { + /* Read error or EOF */ + return ret; } - wth->data_offset += 2; - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(record_length, 1, 4, wth->fh); - if (bytes_read != 4) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return -1; - } - wth->data_offset += 4; - - type = pletohs(record_type); - length = pletohs(record_length); + wth->data_offset += 6; switch (type) { @@ -470,13 +464,10 @@ static int ngsniffer_read(wtap *wth, int *err) } /* Read the f_frame2_struct */ - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(&frame2, 1, sizeof frame2, wth->fh); - if (bytes_read != sizeof frame2) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return -1; + ret = ngsniffer_read_frame2(wth->fh, &frame2, err); + if (ret < 0) { + /* Read error */ + return ret; } wth->data_offset += sizeof frame2; time_low = pletohs(&frame2.time_low); @@ -490,30 +481,7 @@ static int ngsniffer_read(wtap *wth, int *err) t = (double)time_low+(double)(time_med)*65536.0 + (double)time_high*4294967296.0; - /* - * In one PPP "Internetwork analyzer" capture, - * the only bit seen in "fs" is the 0x80 bit, - * which probably indicates the packet's - * direction; all other bits were zero. - * All bits in "frame2.flags" were zero. - * - * In one X.25 "Interenetwork analyzer" capture, - * the only bit seen in "fs" is the 0x80 bit, - * which probably indicates the packet's - * direction; all other bits were zero. - * "frame2.flags" was always 0x18. - * - * In one Ethernet capture, "fs" was always 0, - * and "flags" was either 0 or 0x18, with no - * obvious correlation with anything. - * - * In one Token Ring capture, "fs" was either 0 - * or 0xcc, and "flags" was either 0 or 0x18, - * with no obvious correlation with anything. - */ - wth->phdr.pseudo_header.x25.flags = - (frame2.fs & 0x80) ? 0x00 : 0x80; - + set_pseudo_header_frame2(&wth->pseudo_header, &frame2); goto found; case REC_FRAME4: @@ -528,14 +496,7 @@ static int ngsniffer_read(wtap *wth, int *err) } /* Read the f_frame4_struct */ - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(&frame4, 1, sizeof frame4, wth->fh); - if (bytes_read != sizeof frame4) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return -1; - } + ret = ngsniffer_read_frame4(wth->fh, &frame4, err); wth->data_offset += sizeof frame4; time_low = pletohs(&frame4.time_low); time_med = pletohs(&frame4.time_med); @@ -552,24 +513,7 @@ static int ngsniffer_read(wtap *wth, int *err) t = (double)time_low+(double)(time_med)*65536.0 + (double)time_high*4294967296.0; - wth->phdr.pseudo_header.ngsniffer_atm.AppTrafType = - frame4.atm_info.AppTrafType; - wth->phdr.pseudo_header.ngsniffer_atm.AppHLType = - frame4.atm_info.AppHLType; - wth->phdr.pseudo_header.ngsniffer_atm.Vpi = - pletohs(&frame4.atm_info.Vpi); - wth->phdr.pseudo_header.ngsniffer_atm.Vci = - pletohs(&frame4.atm_info.Vci); - wth->phdr.pseudo_header.ngsniffer_atm.channel = - pletohs(&frame4.atm_info.channel); - wth->phdr.pseudo_header.ngsniffer_atm.cells = - pletohs(&frame4.atm_info.cells); - wth->phdr.pseudo_header.ngsniffer_atm.aal5t_u2u = - pletohs(&frame4.atm_info.Trailer.aal5t_u2u); - wth->phdr.pseudo_header.ngsniffer_atm.aal5t_len = - pletohs(&frame4.atm_info.Trailer.aal5t_len); - wth->phdr.pseudo_header.ngsniffer_atm.aal5t_chksum = - pletohl(&frame4.atm_info.Trailer.aal5t_chksum); + set_pseudo_header_frame4(&wth->pseudo_header, &frame4); goto found; case REC_EOF: @@ -599,17 +543,9 @@ found: * Read the packet data. */ buffer_assure_space(wth->frame_buffer, length); - data_offset = wth->data_offset; - errno = WTAP_ERR_CANT_READ; pd = buffer_start_ptr(wth->frame_buffer); - bytes_read = file_read(pd, 1, length, wth->fh); - - if (bytes_read != length) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return -1; - } + if (ngsniffer_read_rec_data(wth->fh, pd, length, err) < 0) + return -1; /* Read error */ wth->data_offset += length; if (wth->file_encap == WTAP_ENCAP_UNKNOWN) { @@ -637,11 +573,192 @@ found: wth->phdr.ts.tv_usec = (unsigned long)((t-(double)(wth->phdr.ts.tv_sec)) *1.0e6); wth->phdr.pkt_encap = wth->file_encap; - return data_offset; + return record_offset; +} + +static int ngsniffer_seek_read(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int packet_size) +{ + int ret; + int err; /* XXX - return this */ + guint16 type, length; + struct frame2_rec frame2; + struct frame4_rec frame4; + + file_seek(wth->random_fh, seek_off, SEEK_SET); + + ret = ngsniffer_read_rec_header(wth->random_fh, &type, &length, &err); + if (ret <= 0) { + /* Read error or EOF */ + return ret; + } + + switch (type) { + + case REC_FRAME2: + /* Read the f_frame2_struct */ + ret = ngsniffer_read_frame2(wth->random_fh, &frame2, &err); + if (ret < 0) { + /* Read error */ + return ret; + } + + length -= sizeof frame2; /* we already read that much */ + + set_pseudo_header_frame2(pseudo_header, &frame2); + break; + + case REC_FRAME4: + /* Read the f_frame4_struct */ + ret = ngsniffer_read_frame4(wth->random_fh, &frame4, &err); + + length -= sizeof frame4; /* we already read that much */ + + set_pseudo_header_frame4(pseudo_header, &frame4); + break; + + default: + /* + * "Can't happen". + */ + g_assert_not_reached(); + return -1; + } + + /* + * Got the pseudo-header (if any), now get the data. + */ + return ngsniffer_read_rec_data(wth->random_fh, pd, packet_size, &err); +} + +static int ngsniffer_read_rec_header(FILE_T *fh, guint16 *typep, + guint16 *lengthp, int *err) +{ + int bytes_read; + char record_type[2]; + char record_length[4]; /* only 1st 2 bytes are length */ + + /* + * Read the record header. + */ + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(record_type, 1, 2, fh); + if (bytes_read != 2) { + *err = file_error(fh); + if (*err != 0) + return -1; + if (bytes_read != 0) { + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; + } + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(record_length, 1, 4, fh); + if (bytes_read != 4) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + + *typep = pletohs(record_type); + *lengthp = pletohs(record_length); + return 1; /* success */ +} + +static int ngsniffer_read_frame2(FILE_T *fh, struct frame2_rec *frame2, + int *err) +{ + int bytes_read; + + /* Read the f_frame2_struct */ + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(frame2, 1, sizeof *frame2, fh); + if (bytes_read != sizeof *frame2) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; +} + +static void set_pseudo_header_frame2(union pseudo_header *pseudo_header, + struct frame2_rec *frame2) +{ + /* + * In one PPP "Internetwork analyzer" capture, + * the only bit seen in "fs" is the 0x80 bit, + * which probably indicates the packet's + * direction; all other bits were zero. + * All bits in "frame2.flags" were zero. + * + * In one X.25 "Interenetwork analyzer" capture, + * the only bit seen in "fs" is the 0x80 bit, + * which probably indicates the packet's + * direction; all other bits were zero. + * "frame2.flags" was always 0x18. + * + * In one Ethernet capture, "fs" was always 0, + * and "flags" was either 0 or 0x18, with no + * obvious correlation with anything. + * + * In one Token Ring capture, "fs" was either 0 + * or 0xcc, and "flags" was either 0 or 0x18, + * with no obvious correlation with anything. + */ + pseudo_header->x25.flags = (frame2->fs & 0x80) ? 0x00 : 0x80; +} + +static int ngsniffer_read_frame4(FILE_T *fh, struct frame4_rec *frame4, + int *err) +{ + int bytes_read; + + /* Read the f_frame4_struct */ + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(frame4, 1, sizeof *frame4, fh); + if (bytes_read != sizeof *frame4) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; +} + +static void set_pseudo_header_frame4(union pseudo_header *pseudo_header, + struct frame4_rec *frame4) +{ + pseudo_header->ngsniffer_atm.AppTrafType = frame4->atm_info.AppTrafType; + pseudo_header->ngsniffer_atm.AppHLType = frame4->atm_info.AppHLType; + pseudo_header->ngsniffer_atm.Vpi = pletohs(&frame4->atm_info.Vpi); + pseudo_header->ngsniffer_atm.Vci = pletohs(&frame4->atm_info.Vci); + pseudo_header->ngsniffer_atm.channel = pletohs(&frame4->atm_info.channel); + pseudo_header->ngsniffer_atm.cells = pletohs(&frame4->atm_info.cells); + pseudo_header->ngsniffer_atm.aal5t_u2u = pletohs(&frame4->atm_info.Trailer.aal5t_u2u); + pseudo_header->ngsniffer_atm.aal5t_len = pletohs(&frame4->atm_info.Trailer.aal5t_len); + pseudo_header->ngsniffer_atm.aal5t_chksum = pletohl(&frame4->atm_info.Trailer.aal5t_chksum); +} + +static int ngsniffer_read_rec_data(FILE_T *fh, char *pd, int length, int *err) +{ + int bytes_read; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(pd, 1, length, fh); + + if (bytes_read != length) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; } -static void -ngsniffer_close(wtap *wth) +static void ngsniffer_close(wtap *wth) { g_free(wth->capture.ngsniffer); } @@ -717,7 +834,7 @@ gboolean ngsniffer_dump_open(wtap_dumper *wdh, int *err) /* Write a record for a packet to a dump file. Returns TRUE on success, FALSE on failure. */ static gboolean ngsniffer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, - const u_char *pd, int *err) + const union pseudo_header *pseudo_header, const u_char *pd, int *err) { ngsniffer_dump_t *priv = wdh->dump.ngsniffer; struct frame2_rec rec_hdr; @@ -792,7 +909,7 @@ static gboolean ngsniffer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, rec_hdr.time_high = htoles(t_high); rec_hdr.size = htoles(phdr->caplen); if (wdh->encap == WTAP_ENCAP_LAPB || wdh->encap == WTAP_ENCAP_PPP) - rec_hdr.fs = (phdr->pseudo_header.x25.flags & 0x80) ? 0x00 : 0x80; + rec_hdr.fs = (pseudo_header->x25.flags & 0x80) ? 0x00 : 0x80; else rec_hdr.fs = 0; rec_hdr.flags = 0; diff --git a/wiretap/radcom.c b/wiretap/radcom.c index ac378a2a83..ed168f417e 100644 --- a/wiretap/radcom.c +++ b/wiretap/radcom.c @@ -1,6 +1,6 @@ /* radcom.c * - * $Id: radcom.c,v 1.20 2000/04/15 21:12:37 guy Exp $ + * $Id: radcom.c,v 1.21 2000/05/18 09:09:43 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -68,6 +68,11 @@ struct radcomrec_hdr { }; static int radcom_read(wtap *wth, int *err); +static int radcom_seek_read(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int length); +static int radcom_read_rec_header(FILE_T *fh, struct radcomrec_hdr *hdr, + int *err); +static int radcom_read_rec_data(FILE_T *fh, char *pd, int length, int *err); int radcom_open(wtap *wth, int *err) { @@ -134,6 +139,7 @@ int radcom_open(wtap *wth, int *err) /* This is a radcom file */ wth->file_type = WTAP_FILE_RADCOM; wth->subtype_read = radcom_read; + wth->subtype_seek_read = radcom_seek_read; wth->snapshot_length = 16384; /* not available in header, only in frame */ tm.tm_year = pletohs(&start_date.year)-1900; @@ -218,26 +224,21 @@ read_error: /* Read the next packet */ static int radcom_read(wtap *wth, int *err) { - int bytes_read; + int record_offset; + int ret; struct radcomrec_hdr hdr; guint16 length; guint32 sec; + int bytes_read; struct tm tm; - int data_offset; char fcs[2]; /* Read record header. */ - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh); - if (bytes_read != sizeof hdr) { - *err = file_error(wth->fh); - if (*err != 0) - return -1; - if (bytes_read != 0) { - *err = WTAP_ERR_SHORT_READ; - return -1; - } - return 0; + record_offset = wth->data_offset; + ret = radcom_read_rec_header(wth->fh, &hdr, err); + if (ret <= 0) { + /* Read error or EOF */ + return ret; } wth->data_offset += sizeof hdr; length = pletohs(&hdr.length); @@ -259,23 +260,15 @@ static int radcom_read(wtap *wth, int *err) tm.tm_isdst = -1; wth->phdr.ts.tv_sec = mktime(&tm); wth->phdr.ts.tv_usec = pletohl(&hdr.date.usec); - wth->phdr.pseudo_header.x25.flags = (hdr.dce & 0x1) ? 0x00 : 0x80; + wth->pseudo_header.x25.flags = (hdr.dce & 0x1) ? 0x00 : 0x80; /* * Read the packet data. */ buffer_assure_space(wth->frame_buffer, length); - data_offset = wth->data_offset; - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1, - length, wth->fh); - - if (bytes_read != length) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return -1; - } + if (radcom_read_rec_data(wth->fh, + buffer_start_ptr(wth->frame_buffer), length, err) < 0) + return -1; /* Read error */ wth->data_offset += length; wth->phdr.pkt_encap = wth->file_encap; @@ -294,5 +287,67 @@ static int radcom_read(wtap *wth, int *err) wth->data_offset += sizeof fcs; } - return data_offset; + return record_offset; +} + +static int +radcom_seek_read(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int length) +{ + int ret; + int err; /* XXX - return this */ + struct radcomrec_hdr hdr; + + file_seek(wth->random_fh, seek_off, SEEK_SET); + + /* Read record header. */ + ret = radcom_read_rec_header(wth->random_fh, &hdr, &err); + if (ret <= 0) { + /* Read error or EOF */ + return ret; + } + + pseudo_header->x25.flags = (hdr.dce & 0x1) ? 0x00 : 0x80; + + /* + * Read the packet data. + */ + return radcom_read_rec_data(wth->random_fh, pd, length, &err); +} + +static int +radcom_read_rec_header(FILE_T *fh, struct radcomrec_hdr *hdr, int *err) +{ + int bytes_read; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(hdr, 1, sizeof *hdr, fh); + if (bytes_read != sizeof *hdr) { + *err = file_error(fh); + if (*err != 0) + return -1; + if (bytes_read != 0) { + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; + } + return 1; +} + +static int +radcom_read_rec_data(FILE_T *fh, char *pd, int length, int *err) +{ + int bytes_read; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(pd, 1, length, fh); + + if (bytes_read != length) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; } diff --git a/wiretap/snoop.c b/wiretap/snoop.c index 97e6c5e861..26b5b600cd 100644 --- a/wiretap/snoop.c +++ b/wiretap/snoop.c @@ -1,6 +1,6 @@ /* snoop.c * - * $Id: snoop.c,v 1.25 2000/02/19 08:00:04 guy Exp $ + * $Id: snoop.c,v 1.26 2000/05/18 09:09:44 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -56,8 +56,13 @@ struct snooprec_hdr { }; static int snoop_read(wtap *wth, int *err); +static int snoop_seek_read(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int length); +static int snoop_read_atm_pseudoheader(FILE_T *fh, + union pseudo_header *pseudo_header, int *err); +static int snoop_read_rec_data(FILE_T *fh, char *pd, int length, int *err); static gboolean snoop_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, - const u_char *pd, int *err); + const union pseudo_header *pseudo_header, const u_char *pd, int *err); /* * See @@ -194,6 +199,7 @@ int snoop_open(wtap *wth, int *err) /* This is a snoop file */ wth->file_type = WTAP_FILE_SNOOP; wth->subtype_read = snoop_read; + wth->subtype_seek_read = snoop_seek_read; wth->file_encap = snoop_encap[hdr.network]; wth->snapshot_length = 16384; /* XXX - not available in header */ return 1; @@ -205,10 +211,9 @@ static int snoop_read(wtap *wth, int *err) guint32 rec_size; guint32 packet_size; guint32 orig_size; + int data_offset; int bytes_read; struct snooprec_hdr hdr; - char atm_phdr[4]; - int data_offset; char padbuf[4]; int padbytes; int bytes_to_read; @@ -242,6 +247,8 @@ static int snoop_read(wtap *wth, int *err) return -1; } + data_offset = wth->data_offset; + /* * If this is an ATM packet, the first four bytes are the * direction of the packet (transmit/receive), the VPI, and @@ -259,39 +266,9 @@ static int snoop_read(wtap *wth, int *err) *err = WTAP_ERR_BAD_RECORD; return -1; } - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(atm_phdr, 1, 4, wth->fh); - if (bytes_read != 4) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return -1; - } - - wth->phdr.pseudo_header.ngsniffer_atm.channel = - (atm_phdr[0] & 0x80) ? 1 : 0; - wth->phdr.pseudo_header.ngsniffer_atm.Vpi = atm_phdr[1]; - wth->phdr.pseudo_header.ngsniffer_atm.Vci = pntohs(&atm_phdr[2]); - - /* We don't have this information */ - wth->phdr.pseudo_header.ngsniffer_atm.cells = 0; - wth->phdr.pseudo_header.ngsniffer_atm.aal5t_u2u = 0; - wth->phdr.pseudo_header.ngsniffer_atm.aal5t_len = 0; - wth->phdr.pseudo_header.ngsniffer_atm.aal5t_chksum = 0; - - /* - * Assume it's AAL5; we know nothing more about it. - * - * For what it's worth, in one "atmsnoop" capture, - * the lower 7 bits of the first byte of the header - * were 0x05 for ILMI traffic, 0x06 for Signalling - * AAL traffic, and 0x02 for at least some RFC 1483-style - * LLC multiplexed traffic. - */ - wth->phdr.pseudo_header.ngsniffer_atm.AppTrafType = - ATT_AAL5|ATT_HL_UNKNOWN; - wth->phdr.pseudo_header.ngsniffer_atm.AppHLType = - AHLT_UNKNOWN; + if (snoop_read_atm_pseudoheader(wth->fh, &wth->pseudo_header, + err) < 0) + return -1; /* Read error */ /* * Don't count the pseudo-header as part of the packet. @@ -303,17 +280,9 @@ static int snoop_read(wtap *wth, int *err) } buffer_assure_space(wth->frame_buffer, packet_size); - data_offset = wth->data_offset; - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1, - packet_size, wth->fh); - - if (bytes_read != packet_size) { - *err = file_error(wth->fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return -1; - } + if (snoop_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), + packet_size, err) < 0) + return -1; /* Read error */ wth->data_offset += packet_size; wth->phdr.ts.tv_sec = ntohl(hdr.ts_sec); @@ -349,6 +318,88 @@ static int snoop_read(wtap *wth, int *err) return data_offset; } +static int +snoop_seek_read(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, u_char *pd, int length) +{ + int ret; + int err; /* XXX - return this */ + + file_seek(wth->random_fh, seek_off, SEEK_SET); + + if (wth->file_encap == WTAP_ENCAP_ATM_SNIFFER) { + ret = snoop_read_atm_pseudoheader(wth->random_fh, pseudo_header, + &err); + if (ret < 0) { + /* Read error */ + return ret; + } + } + + /* + * Read the packet data. + */ + return snoop_read_rec_data(wth->random_fh, pd, length, &err); +} + +static int +snoop_read_atm_pseudoheader(FILE_T *fh, union pseudo_header *pseudo_header, + int *err) +{ + char atm_phdr[4]; + int bytes_read; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(atm_phdr, 1, 4, fh); + if (bytes_read != 4) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + + pseudo_header->ngsniffer_atm.channel = (atm_phdr[0] & 0x80) ? 1 : 0; + pseudo_header->ngsniffer_atm.Vpi = atm_phdr[1]; + pseudo_header->ngsniffer_atm.Vci = pntohs(&atm_phdr[2]); + + /* We don't have this information */ + pseudo_header->ngsniffer_atm.cells = 0; + pseudo_header->ngsniffer_atm.aal5t_u2u = 0; + pseudo_header->ngsniffer_atm.aal5t_len = 0; + pseudo_header->ngsniffer_atm.aal5t_chksum = 0; + + /* + * Assume it's AAL5; we know nothing more about it. + * + * For what it's worth, in one "atmsnoop" capture, + * the lower 7 bits of the first byte of the header + * were 0x05 for ILMI traffic, 0x06 for Signalling + * AAL traffic, and 0x02 for at least some RFC 1483-style + * LLC multiplexed traffic. + */ + pseudo_header->ngsniffer_atm.AppTrafType = ATT_AAL5|ATT_HL_UNKNOWN; + pseudo_header->ngsniffer_atm.AppHLType = AHLT_UNKNOWN; + + return 0; +} + +static int +snoop_read_rec_data(FILE_T *fh, char *pd, int length, int *err) +{ + int bytes_read; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(pd, 1, length, fh); + + if (bytes_read != length) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; +} + static const int wtap_encap[] = { -1, /* WTAP_ENCAP_UNKNOWN -> unsupported */ 0x04, /* WTAP_ENCAP_ETHERNET -> DL_ETHER */ @@ -420,7 +471,7 @@ gboolean snoop_dump_open(wtap_dumper *wdh, int *err) /* Write a record for a packet to a dump file. Returns TRUE on success, FALSE on failure. */ static gboolean snoop_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, - const u_char *pd, int *err) + const union pseudo_header *pseudo_header, const u_char *pd, int *err) { struct snooprec_hdr rec_hdr; int nwritten; diff --git a/wiretap/toshiba.c b/wiretap/toshiba.c index e075110d68..363ef0bdcc 100644 --- a/wiretap/toshiba.c +++ b/wiretap/toshiba.c @@ -1,6 +1,6 @@ /* toshiba.c * - * $Id: toshiba.c,v 1.8 2000/03/04 14:22:29 gram Exp $ + * $Id: toshiba.c,v 1.9 2000/05/18 09:09:46 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -105,10 +105,11 @@ static const char toshiba_rec_magic[] = { '[', 'N', 'o', '.' }; #define TOSHIBA_REC_MAGIC_SIZE (sizeof toshiba_rec_magic / sizeof toshiba_rec_magic[0]) static int toshiba_read(wtap *wth, int *err); +static int toshiba_seek_read(wtap *wth, int seek_off, union pseudo_header *pseudo_header, guint8 *pd, int len); static gboolean parse_single_hex_dump_line(char* rec, guint8 *buf, int byte_offset); -static int parse_toshiba_hex_dump(FILE *fh, int pkt_len, guint8* buf, int *err); -static int parse_toshiba_rec_hdr(wtap *wth, FILE *fh, int *err); -static int parse_toshiba(FILE *fh, guint8 *pd, int len); +static int parse_toshiba_hex_dump(FILE_T *fh, int pkt_len, guint8* buf, int *err); +static int parse_toshiba_rec_hdr(wtap *wth, FILE_T *fh, + union pseudo_header *pseudo_header, int *err); /* Seeks to the beginning of the next packet, and returns the byte offset. Returns -1 on failure. */ @@ -192,6 +193,7 @@ int toshiba_open(wtap *wth, int *err) wth->file_type = WTAP_FILE_TOSHIBA; wth->snapshot_length = 16384; /* just guessing */ wth->subtype_read = toshiba_read; + wth->subtype_seek_read = toshiba_seek_read; return 1; } @@ -210,7 +212,8 @@ static int toshiba_read(wtap *wth, int *err) } /* Parse the header */ - pkt_len = parse_toshiba_rec_hdr(wth, wth->fh, err); + pkt_len = parse_toshiba_rec_hdr(wth, wth->fh, + &wth->pseudo_header, err); /* Make sure we have enough room for the packet */ buffer_assure_space(wth->frame_buffer, wth->snapshot_length); @@ -224,34 +227,31 @@ static int toshiba_read(wtap *wth, int *err) } /* Used to read packets in random-access fashion */ -int -toshiba_seek_read (FILE *fh, int seek_off, guint8 *pd, int len) -{ - file_seek(fh, seek_off - 1, SEEK_SET); - return parse_toshiba(fh, pd, len); -} - -/* Used to read packets in random-access fashion */ static int -parse_toshiba(FILE *fh, guint8 *pd, int len) +toshiba_seek_read (wtap *wth, int seek_off, union pseudo_header *pseudo_header, + guint8 *pd, int len) { int pkt_len; int err; - pkt_len = parse_toshiba_rec_hdr(NULL, fh, &err); + file_seek(wth->random_fh, seek_off - 1, SEEK_SET); + + pkt_len = parse_toshiba_rec_hdr(NULL, wth->random_fh, pseudo_header, + &err); if (pkt_len != len) { return -1; } - parse_toshiba_hex_dump(fh, pkt_len, pd, &err); + parse_toshiba_hex_dump(wth->random_fh, pkt_len, pd, &err); return 0; } /* Parses a packet record header. */ static int -parse_toshiba_rec_hdr(wtap *wth, FILE *fh, int *err) +parse_toshiba_rec_hdr(wtap *wth, FILE_T *fh, + union pseudo_header *pseudo_header, int *err) { char line[TOSHIBA_LINE_LENGTH]; int num_items_scanned; @@ -315,28 +315,31 @@ parse_toshiba_rec_hdr(wtap *wth, FILE *fh, int *err) wth->phdr.ts.tv_usec = csec * 10000; wth->phdr.caplen = pkt_len; wth->phdr.len = pkt_len; - switch (channel[0]) { - case 'B': + } + switch (channel[0]) { + case 'B': + if (wth) wth->phdr.pkt_encap = WTAP_ENCAP_PPP; - break; + break; - case 'D': + case 'D': + if (wth) wth->phdr.pkt_encap = WTAP_ENCAP_LAPD; - wth->phdr.pseudo_header.lapd.from_network_to_user = - (direction[0] == 'R' ? TRUE : FALSE ); - break; + pseudo_header->lapd.from_network_to_user = + (direction[0] == 'R' ? TRUE : FALSE ); + break; - default: + default: + if (wth) wth->phdr.pkt_encap = WTAP_ENCAP_ETHERNET; - break; - } + break; } return pkt_len; } /* Converts ASCII hex dump to binary data */ static int -parse_toshiba_hex_dump(FILE *fh, int pkt_len, guint8* buf, int *err) +parse_toshiba_hex_dump(FILE_T *fh, int pkt_len, guint8* buf, int *err) { char line[TOSHIBA_LINE_LENGTH]; int i, hex_lines; diff --git a/wiretap/toshiba.h b/wiretap/toshiba.h index 6d4c225808..f4127ba969 100644 --- a/wiretap/toshiba.h +++ b/wiretap/toshiba.h @@ -1,6 +1,6 @@ /* toshiba.h * - * $Id: toshiba.h,v 1.1 1999/10/31 17:46:10 gram Exp $ + * $Id: toshiba.h,v 1.2 2000/05/18 09:09:48 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -22,4 +22,3 @@ */ int toshiba_open(wtap *wth, int *err); -int toshiba_seek_read (FILE *fh, int seek_off, guint8 *pd, int len); diff --git a/wiretap/wtap.c b/wiretap/wtap.c index d541af4669..00200cb010 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -1,6 +1,6 @@ /* wtap.c * - * $Id: wtap.c,v 1.40 2000/05/12 05:06:33 gram Exp $ + * $Id: wtap.c,v 1.41 2000/05/18 09:09:48 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -187,17 +187,33 @@ const char *wtap_strerror(int err) return strerror(err); } -void wtap_close(wtap *wth) +/* Close only the sequential side, freeing up memory it uses. + Note that we do *not* want to call the subtype's close function, + as it would free any per-subtype data, and that data may be + needed by the random-access side. */ +void wtap_sequential_close(wtap *wth) { - if (wth->subtype_close != NULL) - (*wth->subtype_close)(wth); - - file_close(wth->fh); + if (wth->fh != NULL) { + file_close(wth->fh); + wth->fh = NULL; + } if (wth->frame_buffer) { buffer_free(wth->frame_buffer); g_free(wth->frame_buffer); + wth->frame_buffer = NULL; } +} + +void wtap_close(wtap *wth) +{ + wtap_sequential_close(wth); + + if (wth->subtype_close != NULL) + (*wth->subtype_close)(wth); + + if (wth->random_fh != NULL) + file_close(wth->random_fh); g_free(wth); } @@ -217,7 +233,7 @@ int wtap_loop(wtap *wth, int count, wtap_handler callback, u_char* user, while ((data_offset = wth->subtype_read(wth, err)) > 0) { callback(user, &wth->phdr, data_offset, - buffer_start_ptr(wth->frame_buffer)); + &wth->pseudo_header, buffer_start_ptr(wth->frame_buffer)); if (count > 0 && ++loop >= count) break; } @@ -227,17 +243,8 @@ int wtap_loop(wtap *wth, int count, wtap_handler callback, u_char* user, return TRUE; /* success */ } -int wtap_seek_read(int file_type, FILE *fh, int seek_off, guint8 *pd, int len) +int wtap_seek_read(wtap *wth, int seek_off, + union pseudo_header *pseudo_header, guint8 *pd, int len) { - switch (file_type) { - - case WTAP_FILE_ASCEND: - return ascend_seek_read(fh, seek_off, pd, len); - - case WTAP_FILE_TOSHIBA: - return toshiba_seek_read(fh, seek_off, pd, len); - - default: - return wtap_def_seek_read(fh, seek_off, pd, len); - } + return wth->subtype_seek_read(wth, seek_off, pseudo_header, pd, len); } diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 655a099456..f4e4c70e2f 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1,6 +1,6 @@ /* wtap.h * - * $Id: wtap.h,v 1.69 2000/05/12 21:27:04 guy Exp $ + * $Id: wtap.h,v 1.70 2000/05/18 09:09:50 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org> @@ -304,23 +304,26 @@ struct wtap_pkthdr { guint32 caplen; guint32 len; int pkt_encap; - union pseudo_header pseudo_header; }; typedef void (*wtap_handler)(u_char*, const struct wtap_pkthdr*, - int, const u_char *); + int, union pseudo_header *pseudo_header, const u_char *); struct wtap; struct Buffer; typedef int (*subtype_read_func)(struct wtap*, int*); +typedef int (*subtype_seek_read_func)(struct wtap*, int, union pseudo_header*, + guint8*, int); typedef struct wtap { FILE_T fh; int fd; /* File descriptor for cap file */ + FILE_T random_fh; /* Secondary FILE_T for random access */ int file_type; int snapshot_length; struct Buffer *frame_buffer; struct wtap_pkthdr phdr; + union pseudo_header pseudo_header; long data_offset; @@ -336,6 +339,7 @@ typedef struct wtap { } capture; subtype_read_func subtype_read; + subtype_seek_read_func subtype_seek_read; void (*subtype_close)(struct wtap*); int file_encap; /* per-file, for those file formats that have @@ -346,7 +350,8 @@ typedef struct wtap { struct wtap_dumper; typedef gboolean (*subtype_write_func)(struct wtap_dumper*, - const struct wtap_pkthdr*, const u_char*, int*); + const struct wtap_pkthdr*, const union pseudo_header*, + const u_char*, int*); typedef gboolean (*subtype_close_func)(struct wtap_dumper*, int*); typedef struct { @@ -394,7 +399,7 @@ typedef struct wtap_dumper { * * a negative number, indicating the type of error, on other failures. */ -wtap* wtap_open_offline(const char *filename, int *err); +wtap* wtap_open_offline(const char *filename, int *err, gboolean do_random); int wtap_loop(wtap *wth, int, wtap_handler, u_char*, int*); int wtap_read(wtap *wth, int *err); @@ -413,9 +418,12 @@ const char *wtap_encap_short_string(int encap); int wtap_short_string_to_encap(const char *short_name); const char *wtap_strerror(int err); +void wtap_sequential_close(wtap *wth); void wtap_close(wtap *wth); -int wtap_seek_read (int file_type, FILE *fh, int seek_off, guint8 *pd, int len); -int wtap_def_seek_read (FILE *fh, int seek_off, guint8 *pd, int len); +int wtap_seek_read (wtap *wth, int seek_off, + union pseudo_header *pseudo_header, guint8 *pd, int len); +int wtap_def_seek_read (wtap *wth, int seek_off, + union pseudo_header *pseudo_header, guint8 *pd, int len); gboolean wtap_dump_can_open(int filetype); gboolean wtap_dump_can_write_encap(int filetype, int encap); @@ -423,8 +431,8 @@ wtap_dumper* wtap_dump_open(const char *filename, int filetype, int encap, int snaplen, int *err); wtap_dumper* wtap_dump_fdopen(int fd, int filetype, int encap, int snaplen, int *err); -gboolean wtap_dump(wtap_dumper *, const struct wtap_pkthdr *, const u_char *, - int *err); +gboolean wtap_dump(wtap_dumper *, const struct wtap_pkthdr *, + const union pseudo_header *pseudo_header, const u_char *, int *err); FILE* wtap_dump_file(wtap_dumper *); gboolean wtap_dump_close(wtap_dumper *, int *); |