diff options
author | Guy Harris <guy@alum.mit.edu> | 2002-06-07 21:11:24 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2002-06-07 21:11:24 +0000 |
commit | c2b438ddfa12d8cec7b4da8026012d2808baad5a (patch) | |
tree | be2e1bf7af783c71c773706bc786dec9d18b26a6 | |
parent | ec511777923e32cdb0b1877ece838a376f511076 (diff) | |
download | wireshark-c2b438ddfa12d8cec7b4da8026012d2808baad5a.tar.gz wireshark-c2b438ddfa12d8cec7b4da8026012d2808baad5a.tar.bz2 wireshark-c2b438ddfa12d8cec7b4da8026012d2808baad5a.zip |
Add a Wiretap routine to process packets captured via libpcap, possibly
extracting a pseudo-header, for the use of SunATM captures.
Add support for SunATM capture.
svn path=/trunk/; revision=5652
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | capture.c | 29 | ||||
-rw-r--r-- | packet-atm.c | 57 | ||||
-rw-r--r-- | packet-atm.h | 30 | ||||
-rw-r--r-- | tethereal.c | 27 | ||||
-rw-r--r-- | wiretap/Makefile.am | 3 | ||||
-rw-r--r-- | wiretap/libpcap.c | 110 | ||||
-rw-r--r-- | wiretap/wtap-capture.h | 33 | ||||
-rw-r--r-- | wiretap/wtap.h | 5 |
9 files changed, 247 insertions, 50 deletions
diff --git a/Makefile.am b/Makefile.am index a8264744ae..95eb8e2184 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Ethereal # -# $Id: Makefile.am,v 1.439 2002/06/02 12:32:08 sahlberg Exp $ +# $Id: Makefile.am,v 1.440 2002/06/07 21:11:22 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs <gerald@ethereal.com> @@ -374,6 +374,7 @@ noinst_HEADERS = \ packet-afs-defs.h \ packet-arp.h \ packet-atalk.h \ + packet-atm.h \ packet-bgp.h \ packet-bootparams.h \ packet-chdlc.h \ @@ -1,7 +1,7 @@ /* capture.c * Routines for packet capture windows * - * $Id: capture.c,v 1.180 2002/06/07 11:12:43 guy Exp $ + * $Id: capture.c,v 1.181 2002/06/07 21:11:22 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -151,8 +151,10 @@ #include "wiretap/libpcap.h" #include "wiretap/wtap.h" +#include "wiretap/wtap-capture.h" #include "packet-atalk.h" +#include "packet-atm.h" #include "packet-clip.h" #include "packet-eth.h" #include "packet-fddi.h" @@ -1956,6 +1958,7 @@ capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr, const u_char *pd) { struct wtap_pkthdr whdr; + union wtap_pseudo_header pseudo_header; loop_data *ld = (loop_data *) user; int err; @@ -1964,21 +1967,22 @@ capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr, ld->go = FALSE; } - /* "phdr->ts" may not necessarily be a "struct timeval" - it may - be a "struct bpf_timeval", with member sizes wired to 32 - bits - and we may go that way ourselves in the future, so - copy the members individually. */ - whdr.ts.tv_sec = phdr->ts.tv_sec; - whdr.ts.tv_usec = phdr->ts.tv_usec; - whdr.caplen = phdr->caplen; - whdr.len = phdr->len; - whdr.pkt_encap = ld->linktype; + /* Convert from libpcap to Wiretap format. + If that fails, set "ld->go" to FALSE, to stop the capture, and set + "ld->err" to the error. */ + pd = wtap_process_pcap_packet(ld->linktype, phdr, pd, &pseudo_header, + &whdr, &err); + if (pd == NULL) { + ld->go = FALSE; + ld->err = err; + return; + } if (ld->pdh) { /* We're supposed to write the packet to a file; do so. If this fails, set "ld->go" to FALSE, to stop the capture, and set "ld->err" to the error. */ - if (!wtap_dump(ld->pdh, &whdr, NULL, pd, &err)) { + if (!wtap_dump(ld->pdh, &whdr, &pseudo_header, pd, &err)) { ld->go = FALSE; ld->err = err; } @@ -2023,6 +2027,9 @@ capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr, case WTAP_ENCAP_LOCALTALK: capture_llap(&ld->counts); break; + case WTAP_ENCAP_ATM_SNIFFER: + capture_atm(&pseudo_header, pd, whdr.caplen, &ld->counts); + break; /* XXX - some ATM drivers on FreeBSD might prepend a 4-byte ATM pseudo-header to DLT_ATM_RFC1483, with LLC header following; we might have to implement that at some point. */ diff --git a/packet-atm.c b/packet-atm.c index a09eca6614..889264aa2f 100644 --- a/packet-atm.c +++ b/packet-atm.c @@ -1,7 +1,7 @@ /* packet-atm.c * Routines for ATM packet disassembly * - * $Id: packet-atm.c,v 1.46 2002/05/25 07:40:11 guy Exp $ + * $Id: packet-atm.c,v 1.47 2002/06/07 21:11:22 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -36,7 +36,11 @@ #include "oui.h" #include <epan/resolv.h> +#include "packet-atm.h" #include "packet-snmp.h" +#include "packet-eth.h" +#include "packet-tr.h" +#include "packet-llc.h" static int proto_atm = -1; static int hf_atm_vpi = -1; @@ -613,6 +617,31 @@ dissect_le_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } static void +capture_lane(const union wtap_pseudo_header *pseudo_header, const u_char *pd, + int len, packet_counts *ld) +{ + /* Is it LE Control, 802.3, 802.5, or "none of the above"? */ + switch (pseudo_header->atm.subtype) { + + case TRAF_ST_LANE_802_3: + case TRAF_ST_LANE_802_3_MC: + /* Dissect as Ethernet */ + capture_eth(pd, 2, len, ld); + break; + + case TRAF_ST_LANE_802_5: + case TRAF_ST_LANE_802_5_MC: + /* Dissect as Token-Ring */ + capture_tr(pd, 2, len, ld); + break; + + default: + ld->other++; + break; + } +} + +static void dissect_lane(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *next_tvb; @@ -730,6 +759,32 @@ static const value_string ipsilon_type_vals[] = { { 0, NULL } }; +void +capture_atm(const union wtap_pseudo_header *pseudo_header, const u_char *pd, + int len, packet_counts *ld) +{ + if (pseudo_header->atm.aal == AAL_5) { + switch (pseudo_header->atm.type) { + + case TRAF_LLCMX: + /* Dissect as WTAP_ENCAP_ATM_RFC1483 */ + /* The ATM iptrace capture that we have shows LLC at this point, + * so that's what I'm calling */ + capture_llc(pd, 0, len, ld); + break; + + case TRAF_LANE: + capture_lane(pseudo_header, pd, len, ld); + break; + + default: + ld->other++; + break; + } + } else + ld->other++; +} + static void dissect_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { diff --git a/packet-atm.h b/packet-atm.h new file mode 100644 index 0000000000..3c6be61920 --- /dev/null +++ b/packet-atm.h @@ -0,0 +1,30 @@ +/* packet-atm.h + * + * $Id: packet-atm.h,v 1.7 2002/06/07 21:11:22 guy Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __PACKET_ATM_H__ +#define __PACKET_ATM_H__ + +void capture_atm(const union wtap_pseudo_header *, const u_char *, int, + packet_counts *); + +#endif diff --git a/tethereal.c b/tethereal.c index 26dadfc627..11dab8a92c 100644 --- a/tethereal.c +++ b/tethereal.c @@ -1,6 +1,6 @@ /* tethereal.c * - * $Id: tethereal.c,v 1.139 2002/06/04 07:03:47 guy Exp $ + * $Id: tethereal.c,v 1.140 2002/06/07 21:11:22 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -103,6 +103,10 @@ #include "ringbuffer.h" #include <epan/epan_dissect.h> +#ifdef HAVE_LIBPCAP +#include <wiretap/wtap-capture.h> +#endif + #ifdef WIN32 #include "capture-wpcap.h" #endif @@ -1090,26 +1094,31 @@ capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr, const u_char *pd) { struct wtap_pkthdr whdr; + union wtap_pseudo_header pseudo_header; loop_data *ld = (loop_data *) user; cb_args_t args; - - whdr.ts.tv_sec = phdr->ts.tv_sec; - whdr.ts.tv_usec = phdr->ts.tv_usec; - whdr.caplen = phdr->caplen; - whdr.len = phdr->len; - whdr.pkt_encap = ld->linktype; + int err; + + /* Convert from libpcap to Wiretap format. + If that fails, ignore the packet. + XXX - print a message. */ + pd = wtap_process_pcap_packet(ld->linktype, phdr, pd, &pseudo_header, + &whdr, &err); + if (pd == NULL) { + return; + } args.cf = &cfile; args.pdh = ld->pdh; if (ld->pdh) { - wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, NULL, pd); + wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, &pseudo_header, pd); /* Report packet capture count if not quiet */ if (!quiet) { fprintf(stderr, "\r%u ", cfile.count); fflush(stdout); } } else { - wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, NULL, pd); + wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, &pseudo_header, pd); } } diff --git a/wiretap/Makefile.am b/wiretap/Makefile.am index 2d68dd2360..23b9cbcfd5 100644 --- a/wiretap/Makefile.am +++ b/wiretap/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Wiretap # -# $Id: Makefile.am,v 1.37 2002/04/30 18:58:15 guy Exp $ +# $Id: Makefile.am,v 1.38 2002/06/07 21:11:24 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs <gerald@zing.org> @@ -82,6 +82,7 @@ libwiretap_a_SOURCES = \ vms.h \ wtap.c \ wtap.h \ + wtap-capture.h \ wtap-int.h EXTRA_DIST = \ diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c index 57fb13453c..afd419121c 100644 --- a/wiretap/libpcap.c +++ b/wiretap/libpcap.c @@ -1,6 +1,6 @@ /* libpcap.c * - * $Id: libpcap.c,v 1.75 2002/06/07 07:27:35 guy Exp $ + * $Id: libpcap.c,v 1.76 2002/06/07 21:11:24 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> @@ -30,6 +30,11 @@ #include "buffer.h" #include "libpcap.h" +#ifdef HAVE_PCAP_H +#include <pcap.h> +#include "wtap-capture.h" +#endif + /* * The link-layer header on ATM packets. */ @@ -61,6 +66,8 @@ static gboolean libpcap_seek_read(wtap *wth, long seek_off, static int libpcap_read_header(wtap *wth, int *err, struct pcaprec_ss990915_hdr *hdr, gboolean silent); static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr); +static void libpcap_get_atm_pseudoheader(const struct sunatm_hdr *atm_phdr, + union wtap_pseudo_header *pseudo_header); static gboolean libpcap_read_atm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, int *err); static gboolean libpcap_read_rec_data(FILE_T fh, u_char *pd, int length, @@ -92,10 +99,6 @@ static gboolean libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, * platform). */ -#ifdef HAVE_PCAP_H -#include <pcap.h> -#endif - static const struct { int dlt_value; int wtap_encap_value; @@ -1014,33 +1017,22 @@ adjust_header(wtap *wth, struct pcaprec_hdr *hdr) } } -static gboolean -libpcap_read_atm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, - int *err) +static void +libpcap_get_atm_pseudoheader(const struct sunatm_hdr *atm_phdr, + union wtap_pseudo_header *pseudo_header) { - struct sunatm_hdr atm_phdr; - int bytes_read; guint8 vpi; guint16 vci; - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(&atm_phdr, 1, sizeof (struct sunatm_hdr), fh); - if (bytes_read != sizeof (struct sunatm_hdr)) { - *err = file_error(fh); - if (*err == 0) - *err = WTAP_ERR_SHORT_READ; - return FALSE; - } - - vpi = atm_phdr.vpi; - vci = pntohs(&atm_phdr.vci); + vpi = atm_phdr->vpi; + vci = pntohs(&atm_phdr->vci); /* * The lower 4 bits of the first byte of the header indicate * the type of traffic, as per the "atmioctl.h" header in * SunATM. */ - switch (atm_phdr.flags & 0x0F) { + switch (atm_phdr->flags & 0x0F) { case 0x01: /* LANE */ pseudo_header->atm.aal = AAL_5; @@ -1095,13 +1087,32 @@ libpcap_read_atm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header pseudo_header->atm.vpi = vpi; pseudo_header->atm.vci = vci; - pseudo_header->atm.channel = (atm_phdr.flags & 0x80) ? 1 : 0; + pseudo_header->atm.channel = (atm_phdr->flags & 0x80) ? 1 : 0; /* We don't have this information */ pseudo_header->atm.cells = 0; pseudo_header->atm.aal5t_u2u = 0; pseudo_header->atm.aal5t_len = 0; pseudo_header->atm.aal5t_chksum = 0; +} + +static gboolean +libpcap_read_atm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header, + int *err) +{ + struct sunatm_hdr atm_phdr; + int bytes_read; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(&atm_phdr, 1, sizeof (struct sunatm_hdr), fh); + if (bytes_read != sizeof (struct sunatm_hdr)) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return FALSE; + } + + libpcap_get_atm_pseudoheader(&atm_phdr, pseudo_header); return TRUE; } @@ -1160,6 +1171,59 @@ static int wtap_wtap_encap_to_pcap_encap(int encap) return -1; } +#ifdef HAVE_PCAP_H +/* + * Given a Wiretap encapsulation type, and raw packet data and the packet + * header from libpcap, process any pseudo-header in the packet, + * fill in the Wiretap packet header, and return a pointer to the + * beginning of the non-pseudo-header data in the packet. + */ +const u_char * +wtap_process_pcap_packet(gint linktype, const struct pcap_pkthdr *phdr, + const u_char *pd, union wtap_pseudo_header *pseudo_header, + struct wtap_pkthdr *whdr, int *err) +{ + /* "phdr->ts" may not necessarily be a "struct timeval" - it may + be a "struct bpf_timeval", with member sizes wired to 32 + bits - and we may go that way ourselves in the future, so + copy the members individually. */ + whdr->ts.tv_sec = phdr->ts.tv_sec; + whdr->ts.tv_usec = phdr->ts.tv_usec; + whdr->caplen = phdr->caplen; + whdr->len = phdr->len; + whdr->pkt_encap = linktype; + + /* + * If this is an ATM packet, the first four bytes are the + * direction of the packet (transmit/receive), the VPI, and + * the VCI; read them and generate the pseudo-header from + * them. + */ + if (linktype == WTAP_ENCAP_ATM_SNIFFER) { + if (whdr->caplen < sizeof (struct sunatm_hdr)) { + /* + * Uh-oh, the packet isn't big enough to even + * have a pseudo-header. + */ + g_message("libpcap: SunATM capture has a %u-byte packet, too small to have even an ATM pseudo-header\n", + whdr->caplen); + *err = WTAP_ERR_BAD_RECORD; + return NULL; + } + libpcap_get_atm_pseudoheader((struct sunatm_hdr *)pd, + pseudo_header); + + /* + * Don't count the pseudo-header as part of the packet. + */ + whdr->len -= sizeof (struct sunatm_hdr); + whdr->caplen -= sizeof (struct sunatm_hdr); + pd += sizeof (struct sunatm_hdr); + } + return pd; +} +#endif + /* Returns 0 if we could write the specified encapsulation type, an error indication otherwise. */ int libpcap_dump_can_write_encap(int encap) diff --git a/wiretap/wtap-capture.h b/wiretap/wtap-capture.h new file mode 100644 index 0000000000..59c56af79e --- /dev/null +++ b/wiretap/wtap-capture.h @@ -0,0 +1,33 @@ +/* wtap_capture.h + * + * $Id: wtap-capture.h,v 1.1 2002/06/07 21:11:24 guy Exp $ + * + * Wiretap Library + * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __WTAP_CAPTURE_H__ +#define __WTAP_CAPTURE_H__ + +/* XXX - needed until "wiretap" can do live packet captures */ +int wtap_pcap_encap_to_wtap_encap(int encap); +const u_char *wtap_process_pcap_packet(gint linktype, + const struct pcap_pkthdr *phdr, const u_char *pd, + union wtap_pseudo_header *pseudo_header, struct wtap_pkthdr *whdr, + int *err); + +#endif /* __WTAP_CAPTURE_H__ */ diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 857fd88557..edd90ef01f 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1,6 +1,6 @@ /* wtap.h * - * $Id: wtap.h,v 1.113 2002/06/07 07:47:58 guy Exp $ + * $Id: wtap.h,v 1.114 2002/06/07 21:11:24 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> @@ -380,9 +380,6 @@ gboolean wtap_dump_close(wtap_dumper *, int *); long wtap_get_bytes_dumped(wtap_dumper *); void wtap_set_bytes_dumped(wtap_dumper *wdh, long bytes_dumped); -/* XXX - needed until "wiretap" can do live packet captures */ -int wtap_pcap_encap_to_wtap_encap(int encap); - /* * Wiretap error codes. */ |