diff options
author | Stephen Fisher <steve@stephen-fisher.com> | 2007-08-23 22:11:39 +0000 |
---|---|---|
committer | Stephen Fisher <steve@stephen-fisher.com> | 2007-08-23 22:11:39 +0000 |
commit | f76387ba1ce2e1206d05e0c1774baccdcc065bb8 (patch) | |
tree | bb9df0d7b34e4705458a64648fe80f100f63dbfe | |
parent | 1cd16d84938dfbaff3519dbaa29034a745ceb3fe (diff) |
From Scott Robinson:
Enhancement patch:
http://bugs.wireshark.org/bugzilla/show_bug.cgi?id=1758
This change gives Wireshark the ability to read ATM captures saved by UpTime
Select traffic capture.
svn path=/trunk/; revision=22612
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | wiretap/visual.c | 230 |
2 files changed, 219 insertions, 12 deletions
@@ -2804,6 +2804,7 @@ Tuomas Maattanen <maattanen [AT] iki.fi> Joe Eykholt <joe [AT] nuovasystems.com> Ian Brumby <ian.brumby [AT] baesystems.com> Todd J Martin <todd.martin [AT] acm.org> +Scott Robinson <scott.robinson [AT] flukenetworks.com> Alain Magloire <alainm[AT]rcsm.ece.mcgill.ca> was kind enough to give his permission to use his version of snprintf.c. diff --git a/wiretap/visual.c b/wiretap/visual.c index a68112ab24..a4d4f67395 100644 --- a/wiretap/visual.c +++ b/wiretap/visual.c @@ -33,14 +33,26 @@ #include "visual.h" /* - * A Visual Networks traffic capture file contains three sections. The + * A Visual Networks traffic capture file contains three sections. The * first is a 192 octet file header. This is followed by the captured - * packet headers and data. The last section is the packet index block. + * packet header, and for ATM captures, there is an additional atm packet header. + * The data follows the packet header. The last section is the packet index block. * The index block contains one 4 octet pointer for each captured packet. * The first packet index is (4 * num_pkts) octets from the end of the file * and the last index is in the last four octets of the file. * - * All integer and time values are stored in little-endian format. + * All integer and time values are stored in little-endian format, except for + * the ATM Packet Header, which is stored in network byte order. + * + * [ File Header ] + * + * + * [ Packet Header 1 ] [(opt) ATM Packet Header] [ Data ] + * ... + * [ Packet Header n ] [(opt) ATM Packet Header] [ Data ] + * + * + * [ Index Block 1 ] ... [ Index Block n ] */ /* Capture file header, INCLUDING the magic number, is 192 bytes. */ @@ -52,7 +64,8 @@ static const char visual_magic[] = { }; -/* Visual file header (minus magic number). */ +/* Visual File Header (minus magic number). */ +/* This structure is used to extract information */ struct visual_file_hdr { guint32 num_pkts; /* Number of packets in the file */ @@ -78,7 +91,8 @@ struct visual_file_hdr #define PS_SENT 0x40 #define PS_ABORTED 0x80 -/* Visual packet header */ +/* Visual Packet Header */ +/* This structure is used to extract information */ struct visual_pkt_hdr { guint32 ts_delta; /* Time stamp - msecs since start of capture */ @@ -90,6 +104,42 @@ struct visual_pkt_hdr char RESERVED_[6]; /* RESERVED - must be zero */ }; +/* Optional Visual ATM Packet Header */ +/* This structure is used to extract information */ +struct visual_atm_hdr +{ + guint16 vpi; /* 4 bits of zeros; 12 bits of ATM VPI */ + guint16 vci; /* ATM VCI */ + guint8 info; /* 4 bits version; 3 bits unused-zero; 1 bit direction */ + guint8 category; /* indicates type of traffic. 4 bits of status + 4 bits of type */ + guint16 cell_count; /* number of cells that make up this pdu */ + guint32 data_length; /* PDU data length for AAL-5 PDUs, all others - cellcount * 48 */ + guint32 ts_secs; /* seonds value of sysUpTime when the last cell of this PDU was captured */ + guint32 ts_nsec; /* nanoseonds value of sysUpTime when the last cell of this PDU was captured */ + +}; + +/* visual_atm_hdr info bit definitions */ +#define FROM_NETWORK 0x01 +#define ATM_VER_MASK 0xf0 /* Not currently displayed */ + +/* visual_atm_hdr category definitions */ +/* High nibble - not currently displayed */ +#define VN_INCOMPLETE 0x40 +#define VN_BAD_CRC 0x80 +#define VN_CAT_STAT_MASK 0xf0 +/* Low nibble */ +#define VN_UNKNOWN 0x00 +#define VN_AAL1 0x01 +#define VN_AAL2 0x02 +#define VN_AAL34 0x03 +#define VN_O191 0x04 +#define VN_AAL5 0x05 +#define VN_OAM 0x0a +#define VN_RM 0x0b +#define VN_IDLE 0x0c +#define VN_CAT_TYPE_MASK 0x0f + /* Additional information for reading Visual files */ struct visual_read_info @@ -119,7 +169,7 @@ static gboolean visual_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_header *pseudo_header, guchar *pd, int packet_size, int *err, gchar **err_info); static void visual_set_pseudo_header(int encap, struct visual_pkt_hdr *vpkt_hdr, - union wtap_pseudo_header *pseudo_header); + struct visual_atm_hdr *vatm_hdr, union wtap_pseudo_header *pseudo_header); static gboolean visual_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err); static gboolean visual_dump_close(wtap_dumper *wdh, int *err); @@ -196,6 +246,10 @@ int visual_open(wtap *wth, int *err, gchar **err_info) encap = WTAP_ENCAP_FRELAY_WITH_PHDR; break; + case 37: + encap = WTAP_ENCAP_ATM_PDUS; + break; + default: *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("visual: network type %u unknown or unsupported", @@ -216,7 +270,7 @@ int visual_open(wtap *wth, int *err, gchar **err_info) wth->subtype_read = visual_read; wth->subtype_seek_read = visual_seek_read; wth->subtype_close = visual_close; - wth->tsprecision = WTAP_FILE_TSPREC_USEC; + wth->tsprecision = WTAP_FILE_TSPREC_USEC; /* Add Visual-specific information to the wiretap struct for later use. */ visual = g_malloc(sizeof(struct visual_read_info)); @@ -240,7 +294,9 @@ static gboolean visual_read(wtap *wth, int *err, gchar **err_info, guint32 packet_size = 0; int bytes_read; struct visual_pkt_hdr vpkt_hdr; + struct visual_atm_hdr vatm_hdr; int phdr_size = sizeof(vpkt_hdr); + int ahdr_size = sizeof(vatm_hdr); time_t secs; guint32 usecs; guint8 *buf; @@ -270,8 +326,33 @@ static gboolean visual_read(wtap *wth, int *err, gchar **err_info, } wth->data_offset += phdr_size; - /* Read the packet data. */ + /* Get the included length of data. This includes extra headers + payload */ packet_size = pletohs(&vpkt_hdr.incl_len); + + /* Check for additional ATM packet header */ + if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) + { + /* Read the atm packet header. */ + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(&vatm_hdr, 1, ahdr_size, wth->fh); + if (bytes_read != ahdr_size) + { + *err = file_error(wth->fh); + if (*err == 0 && bytes_read != 0) + { + *err = WTAP_ERR_SHORT_READ; + } + return FALSE; + } + wth->data_offset += ahdr_size; + + /* Remove ATM header from length of included bytes in capture, as + this header was appended by the processor doing the packet reassembly, + and was not transmitted across the wire */ + packet_size -= ahdr_size; + } + + /* Read the packet data. */ if (packet_size > WTAP_MAX_PACKET_SIZE) { /* Probably a corrupt capture file; don't blow up trying @@ -303,11 +384,48 @@ static gboolean visual_read(wtap *wth, int *err, gchar **err_info, usecs = (guint32)(t - secs*1000000); wth->phdr.ts.secs = secs; wth->phdr.ts.nsecs = usecs * 1000; + + /* Most visual capture types include FCS checks in the original length value, but + * but don't include the FCS as part of the payload or captured length. + * This causes the RTP audio payload save to fail since then captured len != orig len. + * Adjusting the original length to remove the FCS bytes we counted based + * on the file encapsualtion type. + * + * Only downside to this fix is throughput calculations will be slightly lower + * as they won't include the FCS bytes. + */ + wth->phdr.caplen = packet_size; wth->phdr.len = pletohs(&vpkt_hdr.orig_len); + switch (wth->file_encap) + { + case WTAP_ENCAP_ETHERNET: + wth->phdr.len -= 4; + break; + + case WTAP_ENCAP_FRELAY_WITH_PHDR: + case WTAP_ENCAP_CHDLC_WITH_PHDR: + case WTAP_ENCAP_LAPB: + wth->phdr.len -= 2; + break; + + /* ATM original length doesn't include any FCS. Do nothing. */ + case WTAP_ENCAP_ATM_PDUS: + /* Not sure about token ring. Just leaving alone for now. */ + case WTAP_ENCAP_TOKEN_RING: + default: + break; + } + + /* Sanity check */ + if (wth->phdr.len < wth->phdr.caplen) + { + wth->phdr.len = wth->phdr.caplen; + } + /* Set the pseudo_header. */ - visual_set_pseudo_header(wth->file_encap, &vpkt_hdr, &wth->pseudo_header); + visual_set_pseudo_header(wth->file_encap, &vpkt_hdr, &vatm_hdr, &wth->pseudo_header); /* Fill in the encapsulation. Visual files have a media type in the file header and an encapsulation type in each packet header. Files @@ -344,11 +462,23 @@ static gboolean visual_seek_read (wtap *wth, gint64 seek_off, int *err, gchar **err_info _U_) { struct visual_pkt_hdr vpkt_hdr; + struct visual_atm_hdr vatm_hdr; int phdr_size = sizeof(vpkt_hdr); + int ahdr_size = sizeof(vatm_hdr); int bytes_read; + int header_size; + /* Get the size of the visual packet header to skip */ + header_size = sizeof(struct visual_pkt_hdr); + + /* If ATM capture, need to skip over visual ATM packet header too */ + if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) + { + header_size += sizeof(struct visual_atm_hdr); + } + /* Seek to the packet header */ - if (file_seek(wth->random_fh, seek_off - sizeof(struct visual_pkt_hdr), + if (file_seek(wth->random_fh, seek_off - header_size, SEEK_SET, err) == -1) return FALSE; @@ -361,6 +491,23 @@ static gboolean visual_seek_read (wtap *wth, gint64 seek_off, *err = WTAP_ERR_SHORT_READ; return FALSE; } + + /* Check for additional ATM packet header */ + if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) + { + /* Read the atm packet header */ + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(&vatm_hdr, 1, ahdr_size, wth->random_fh); + if (bytes_read != ahdr_size) + { + *err = file_error(wth->fh); + if (*err == 0 && bytes_read != 0) + { + *err = WTAP_ERR_SHORT_READ; + } + return FALSE; + } + } /* Read the packet data. */ errno = WTAP_ERR_CANT_READ; @@ -372,13 +519,13 @@ static gboolean visual_seek_read (wtap *wth, gint64 seek_off, } /* Set the pseudo_header. */ - visual_set_pseudo_header(wth->file_encap, &vpkt_hdr, pseudo_header); + visual_set_pseudo_header(wth->file_encap, &vpkt_hdr, &vatm_hdr, pseudo_header); return TRUE; } static void visual_set_pseudo_header(int encap, struct visual_pkt_hdr *vpkt_hdr, - union wtap_pseudo_header *pseudo_header) + struct visual_atm_hdr *vatm_hdr, union wtap_pseudo_header *pseudo_header) { guint32 packet_status; @@ -404,6 +551,65 @@ static void visual_set_pseudo_header(int encap, struct visual_pkt_hdr *vpkt_hdr, pseudo_header->x25.flags = (packet_status & PS_SENT) ? 0x00 : FROM_DCE; break; + + case WTAP_ENCAP_ATM_PDUS: + /* Set defaults */ + pseudo_header->atm.type = TRAF_UNKNOWN; + pseudo_header->atm.subtype = TRAF_ST_UNKNOWN; + pseudo_header->atm.aal5t_len = 0; + + /* Next two items not supported. Defaulting to zero */ + pseudo_header->atm.aal5t_u2u = 0; + pseudo_header->atm.aal5t_chksum = 0; + + /* Flags appear only to convey that packet is a raw cell. Set to 0 */ + pseudo_header->atm.flags = 0; + + /* Not supported. Defaulting to zero */ + pseudo_header->atm.aal2_cid = 0; + + switch(vatm_hdr->category & VN_CAT_TYPE_MASK ) + { + case VN_AAL1: + pseudo_header->atm.aal = AAL_1; + break; + + case VN_AAL2: + pseudo_header->atm.aal = AAL_2; + break; + + case VN_AAL34: + pseudo_header->atm.aal = AAL_3_4; + break; + + case VN_AAL5: + pseudo_header->atm.aal = AAL_5; + pseudo_header->atm.type = TRAF_LLCMX; + pseudo_header->atm.aal5t_len = pntohl(&vatm_hdr->data_length); + break; + + case VN_OAM: + /* Marking next 3 as OAM versus unknown */ + case VN_O191: + case VN_IDLE: + case VN_RM: + pseudo_header->atm.aal = AAL_OAMCELL; + break; + + case VN_UNKNOWN: + default: + pseudo_header->atm.aal = AAL_UNKNOWN; + break; + + } + pseudo_header->atm.vpi = pntohs(&vatm_hdr->vpi) & 0x0FFF; + pseudo_header->atm.vci = pntohs(&vatm_hdr->vci); + pseudo_header->atm.cells = pntohs(&vatm_hdr->cell_count); + + /* Using bit value of 1 (DCE -> DTE) to indicate From Network */ + pseudo_header->atm.channel = vatm_hdr->info & FROM_NETWORK; + + break; } } |