diff options
author | Guy Harris <guy@alum.mit.edu> | 2000-05-18 09:09:50 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2000-05-18 09:09:50 +0000 |
commit | f3d90d30a49382db3955b9ece00d71fe12d54c49 (patch) | |
tree | b3976154972b7e5a4d8ee25e4c4f2f5bef77d2f0 /wiretap/iptrace.c | |
parent | e7ea221d9c8370817a7b9c9dab3cea47586e1561 (diff) | |
download | wireshark-f3d90d30a49382db3955b9ece00d71fe12d54c49.tar.gz wireshark-f3d90d30a49382db3955b9ece00d71fe12d54c49.tar.bz2 wireshark-f3d90d30a49382db3955b9ece00d71fe12d54c49.zip |
Remove the "union pseudo_header" from the "frame_data" structure;
there's no need to keep it around in memory - when the frame data is
read in when handing a frame, read in the information, if any, necessary
to reconstruct the frame header, and reconstruct it. This saves some
memory.
This requires that the seek-and-read function be implemented inside
Wiretap, and that the Wiretap handle remain open even after we've
finished reading the file sequentially.
This also points out that we can't really do X.25-over-Ethernet
correctly, as we don't know where the direction (DTE->DCE or DCE->DTE)
flag is stored; it's not clear how the Ethernet type 0x0805 for X.25
Layer 3 is supposed to be handled in any case. We eliminate
X.25-over-Ethernet support (until we find out what we're supposed to
do).
svn path=/trunk/; revision=1975
Diffstat (limited to 'wiretap/iptrace.c')
-rw-r--r-- | wiretap/iptrace.c | 199 |
1 files changed, 130 insertions, 69 deletions
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, |