diff options
author | Guy Harris <guy@alum.mit.edu> | 2004-10-05 08:59:57 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2004-10-05 08:59:57 +0000 |
commit | 5a46037813733f4ff12f13848d85ea0b978835fa (patch) | |
tree | 8de9ca9a9413023cec1f852b2f48e802420994fc | |
parent | 919c62cc3972156c6b053d147693b804890a77cd (diff) |
From Mark C. Brown: support for the NETTL_SUBSYS_HPPB_FDDI records.
svn path=/trunk/; revision=12202
-rw-r--r-- | wiretap/nettl.c | 147 | ||||
-rw-r--r-- | wiretap/nettl.h | 5 |
2 files changed, 115 insertions, 37 deletions
diff --git a/wiretap/nettl.c b/wiretap/nettl.c index b48acddcb7..cff3ef3b0f 100644 --- a/wiretap/nettl.c +++ b/wiretap/nettl.c @@ -55,12 +55,14 @@ struct nettlrec_sx25l2_hdr { /* HP nettl record header for the NS_LS_IP subsystem */ /* This also works for BASE100 and GSC100BT */ struct nettlrec_ns_ls_ip_hdr { - guint8 xxa[28]; + guint8 xxa[8]; + guint8 rectype; + guint8 xxb[19]; guint8 caplen[4]; guint8 length[4]; guint8 sec[4]; guint8 usec[4]; - guint8 xxb[16]; + guint8 xxc[16]; }; @@ -130,9 +132,9 @@ static gboolean nettl_seek_read(wtap *wth, long seek_off, int length, int *err, gchar **err_info); static int nettl_read_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, union wtap_pseudo_header *pseudo_header, - int *err, gchar **err_info); + int *err, gchar **err_info, gboolean *fddihack); static gboolean nettl_read_rec_data(FILE_T fh, guchar *pd, int length, - int *err); + int *err, gboolean fddihack); static void nettl_close(wtap *wth); int nettl_open(wtap *wth, int *err, gchar **err_info _U_) @@ -190,11 +192,12 @@ static gboolean nettl_read(wtap *wth, int *err, gchar **err_info, long *data_offset) { int ret; + gboolean fddihack=FALSE; /* Read record header. */ *data_offset = wth->data_offset; ret = nettl_read_rec_header(wth, wth->fh, &wth->phdr, &wth->pseudo_header, - err, err_info); + err, err_info, &fddihack); if (ret <= 0) { /* Read error or EOF */ return FALSE; @@ -221,7 +224,7 @@ static gboolean nettl_read(wtap *wth, int *err, gchar **err_info, */ 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)) + wth->phdr.caplen, err, fddihack)) return FALSE; /* Read error */ wth->data_offset += wth->phdr.caplen; return TRUE; @@ -234,13 +237,14 @@ nettl_seek_read(wtap *wth, long seek_off, { int ret; struct wtap_pkthdr phdr; + gboolean fddihack=FALSE; if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) return FALSE; /* Read record header. */ ret = nettl_read_rec_header(wth, wth->random_fh, &phdr, pseudo_header, - err, err_info); + err, err_info, &fddihack); if (ret <= 0) { /* Read error or EOF */ if (ret == 0) { @@ -253,13 +257,13 @@ nettl_seek_read(wtap *wth, long seek_off, /* * Read the packet data. */ - return nettl_read_rec_data(wth->random_fh, pd, length, err); + return nettl_read_rec_data(wth->random_fh, pd, length, err, fddihack); } static int nettl_read_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, union wtap_pseudo_header *pseudo_header, int *err, - gchar **err_info) + gchar **err_info, gboolean *fddihack) { int bytes_read; struct nettlrec_sx25l2_hdr lapb_hdr; @@ -267,11 +271,13 @@ nettl_read_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, struct nettlrec_ns_ls_drv_eth_hdr drv_eth_hdr; guint16 length; int offset = 0; - guint8 encap[4]; + int encap; + int padlen; guint8 dummy[4]; + guchar dummyc[12]; errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(encap, 1, 4, fh); + bytes_read = file_read(dummy, 1, 4, fh); if (bytes_read != 4) { *err = file_error(fh); if (*err != 0) @@ -283,8 +289,9 @@ nettl_read_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, return 0; } offset += 4; + encap=dummy[3]; - switch (encap[3]) { + switch (encap) { case NETTL_SUBSYS_LAN100 : case NETTL_SUBSYS_BASE100 : case NETTL_SUBSYS_GSC100BT : @@ -295,6 +302,7 @@ nettl_read_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, case NETTL_SUBSYS_INTL100 : case NETTL_SUBSYS_IGELAN : case NETTL_SUBSYS_IETHER : + case NETTL_SUBSYS_HPPB_FDDI : case NETTL_SUBSYS_PCI_FDDI : case NETTL_SUBSYS_TOKEN : case NETTL_SUBSYS_PCI_TR : @@ -307,20 +315,21 @@ nettl_read_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, case NETTL_SUBSYS_NS_LS_IPV6 : case NETTL_SUBSYS_NS_LS_ICMPV6 : case NETTL_SUBSYS_NS_LS_ICMP : - if( (encap[3] == NETTL_SUBSYS_NS_LS_IP) - || (encap[3] == NETTL_SUBSYS_NS_LS_LOOPBACK) - || (encap[3] == NETTL_SUBSYS_NS_LS_UDP) - || (encap[3] == NETTL_SUBSYS_NS_LS_TCP) - || (encap[3] == NETTL_SUBSYS_NS_LS_IPV6)) { + if( (encap == NETTL_SUBSYS_NS_LS_IP) + || (encap == NETTL_SUBSYS_NS_LS_LOOPBACK) + || (encap == NETTL_SUBSYS_NS_LS_UDP) + || (encap == NETTL_SUBSYS_NS_LS_TCP) + || (encap == NETTL_SUBSYS_NS_LS_IPV6)) { phdr->pkt_encap = WTAP_ENCAP_RAW_IP; - } else if (encap[3] == NETTL_SUBSYS_NS_LS_ICMP) { + } else if (encap == NETTL_SUBSYS_NS_LS_ICMP) { phdr->pkt_encap = WTAP_ENCAP_RAW_ICMP; - } else if (encap[3] == NETTL_SUBSYS_NS_LS_ICMPV6) { + } else if (encap == NETTL_SUBSYS_NS_LS_ICMPV6) { phdr->pkt_encap = WTAP_ENCAP_RAW_ICMPV6; - } else if (encap[3] == NETTL_SUBSYS_PCI_FDDI) { + } else if( (encap == NETTL_SUBSYS_HPPB_FDDI) + || (encap == NETTL_SUBSYS_PCI_FDDI) ) { phdr->pkt_encap = WTAP_ENCAP_FDDI; - } else if( (encap[3] == NETTL_SUBSYS_PCI_TR) - || (encap[3] == NETTL_SUBSYS_TOKEN) ) { + } else if( (encap == NETTL_SUBSYS_PCI_TR) + || (encap == NETTL_SUBSYS_TOKEN) ) { phdr->pkt_encap = WTAP_ENCAP_TOKEN_RING; } else { phdr->pkt_encap = WTAP_ENCAP_ETHERNET; @@ -358,8 +367,57 @@ nettl_read_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, offset += 4; } - /* PCI FDDI has an extra 3 bytes of padding */ - if (encap[3] == NETTL_SUBSYS_PCI_FDDI) { + /* HPPB FDDI has different inbound vs outbound trace records */ + if (encap == NETTL_SUBSYS_HPPB_FDDI) { + if (ip_hdr.rectype == NETTL_HDR_PDUIN) { + /* inbound is very strange... + there are an extra 3 bytes after the DSAP and SSAP + for SNAP frames ??? + */ + *fddihack=TRUE; + length = pntohl(&ip_hdr.length); + if (length <= 0) + return 0; + phdr->len = length; + length = pntohl(&ip_hdr.caplen); + phdr->caplen = length; + } else { + /* outbound has an extra padding */ + bytes_read = file_read(dummyc, 1, 9, fh); + if (bytes_read != 9) { + *err = file_error(fh); + if (*err != 0) + return -1; + if (bytes_read != 0) { + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; + } + /* padding is usually either a total 11 or 16 bytes??? */ + padlen = (int)dummyc[8]; + bytes_read = file_read(dummy, 1, padlen, fh); + if (bytes_read != padlen) { + *err = file_error(fh); + if (*err != 0) + return -1; + if (bytes_read != 0) { + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; + } + padlen += 9; + offset += padlen; + length = pntohl(&ip_hdr.length); + if (length <= 0) + return 0; + phdr->len = length - padlen; + length = pntohl(&ip_hdr.caplen); + phdr->caplen = length - padlen; + } + } else if (encap == NETTL_SUBSYS_PCI_FDDI) { + /* PCI FDDI has an extra 3 bytes of padding */ bytes_read = file_read(dummy, 1, 3, fh); if (bytes_read != 3) { *err = file_error(fh); @@ -378,7 +436,7 @@ nettl_read_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, phdr->len = length - 3; length = pntohl(&ip_hdr.caplen); phdr->caplen = length - 3; - } else if (encap[3] == NETTL_SUBSYS_NS_LS_LOOPBACK) { + } else if (encap == NETTL_SUBSYS_NS_LS_LOOPBACK) { /* LOOPBACK has an extra 26 bytes of padding */ bytes_read = file_read(dummy, 1, 26, fh); if (bytes_read != 26) { @@ -509,29 +567,44 @@ nettl_read_rec_header(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, pseudo_header->x25.flags = (lapb_hdr.from_dce & 0x20 ? FROM_DCE : 0x00); break; - case NETTL_SUBSYS_HPPB_FDDI : - /* HP-PB FDDI has a different trace records for inbound vs outbound - Still need to work out a way 'round that... - */ - *err = WTAP_ERR_UNSUPPORTED_ENCAP; - *err_info = g_strdup_printf("nettl: HP-PB FDDI [Subsystem %u] currently unsupported", - encap[3]); - return -1; default: *err = WTAP_ERR_UNSUPPORTED_ENCAP; *err_info = g_strdup_printf("nettl: subsystem %u unknown or unsupported", - encap[3]); + encap); return -1; } return offset; } static gboolean -nettl_read_rec_data(FILE_T fh, guchar *pd, int length, int *err) +nettl_read_rec_data(FILE_T fh, guchar *pd, int length, int *err, gboolean fddihack) { int bytes_read; - - bytes_read = file_read(pd, 1, length, fh); + guchar *p=NULL; + guint8 dummy[3]; + + if (fddihack == TRUE) { + /* read in FC, dest, src and DSAP */ + if (file_read(pd, 1, 14, fh) == 14) { + if (pd[13] == 0xAA) { + /* it's SNAP, have to eat 3 bytes??? */ + if (file_read(dummy, 1, 3, fh) == 3) { + p=pd+14; + bytes_read = file_read(p, 1, length-17, fh); + bytes_read += 17; + } else { + bytes_read = -1; + } + } else { + /* not SNAP */ + p=pd+14; + bytes_read = file_read(p, 1, length-14, fh); + bytes_read += 14; + } + } else + bytes_read = -1; + } else + bytes_read = file_read(pd, 1, length, fh); if (bytes_read != length) { *err = file_error(fh); diff --git a/wiretap/nettl.h b/wiretap/nettl.h index b0c54a07b6..0a2bf5860f 100644 --- a/wiretap/nettl.h +++ b/wiretap/nettl.h @@ -94,6 +94,11 @@ #define NETTL_SUBSYS_TOKEN 31 #define NETTL_SUBSYS_PCI_TR 187 +/* from /usr/include/sys/subsys_id.h */ + +#define NETTL_HDR_PDUIN 0x20 +#define NETTL_HDR_PDUOUT 0x10 + int nettl_open(wtap *wth, int *err, gchar **err_info); #endif |