Skip to content

Commit

Permalink
DLT_NULL, from "libpcap", means different things on different platforms
Browse files Browse the repository at this point in the history
and in different capture files; throw in some heuristics to try to
figure out whether the 4-byte header is:

	1) PPP-over-HDLC (some version of ISDN4BSD?);

	2) big-endian AF_ value (BSD on big-endian platforms);

	3) little-endian AF_ value (BSD on little-endian platforms);

	4) two octets of 0 followed by an Ethernet type (Linux, at least
	   on little-endian platforms, as mutated by "libpcap").

Make a separate Wiretap encapsulation type, WTAP_ENCAP_NULL,
corresponding to DLT_NULL.

Have the PPP code dissect the frame if it's PPP-over-HDLC, and have
"ethertype()" dissect the Ethernet type and the rest of the packet if
it's a Linux-style header; dissect it ourselves only if it's an AF_
value.

Have Wiretap impose a maximum packet size of 65535 bytes, so that it
fails more gracefully when handed a corrupt "libpcap" capture file
(other capture file formats with more than a 16-bit capture length
field, if any, will have that check added later), and put that size in
"wtap.h" and have Ethereal use it as its notion of a maximum packet
size.

Have Ethereal put up a "this file appears to be damaged or corrupt"
message box if Wiretap returns a WTAP_ERR_BAD_RECORD error when opening
or reading a capture file.

Include loopback interfaces in the list of interfaces offered by the
"Capture" dialog box, but put them at the end of the list so that it
doesn't default to a loopback interface unless there are no other
interfaces.  Also, don't require that an interface in the list have an
IP address associated with it, and only put one entry in the list for a
given interface (SIOCGIFCONF returns one entry per interface *address*,
not per *interface* - and even if you were to use only IP addresses, an
interface could conceivably have more than one IP address).

Exclusively use Wiretap encapsulation types internally, even when
capturing; don't use DLT_ types.

svn path=/trunk/; revision=540
  • Loading branch information
guyharris committed Aug 22, 1999
1 parent 5c57f09 commit ee39938
Show file tree
Hide file tree
Showing 11 changed files with 453 additions and 184 deletions.
139 changes: 111 additions & 28 deletions capture.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* capture.c
* Routines for packet capture windows
*
* $Id: capture.c,v 1.57 1999/08/19 05:42:22 guy Exp $
* $Id: capture.c,v 1.58 1999/08/22 00:47:45 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
Expand Down Expand Up @@ -109,19 +109,29 @@ extern int quit_after_cap;
/* Capture filter key */
#define E_CAP_FILT_TE_KEY "cap_filt_te"

static void search_for_if_cb(gpointer data, gpointer user_data);
static void free_if_cb(gpointer data, gpointer user_data);
static void capture_prep_ok_cb(GtkWidget *, gpointer);
static void capture_prep_close_cb(GtkWidget *, gpointer);
static float pct(gint, gint);
static void capture_stop_cb(GtkWidget *, gpointer);
static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
const u_char *);

struct search_user_data {
char *name;
int found;
};

static GList *
get_interface_list() {
GList *il = NULL;
gint nonloopback_pos = 0;
struct ifreq *ifr, *last;
struct ifconf ifc;
struct ifreq ifrflags;
int sock = socket(AF_INET, SOCK_DGRAM, 0);
struct search_user_data user_data;

if (sock < 0)
{
Expand All @@ -139,7 +149,7 @@ get_interface_list() {
ifc.ifc_len < sizeof(struct ifreq))
{
simple_dialog(ESD_TYPE_WARN, NULL,
"Can't list interfaces: ioctl error.");
"Can't list interfaces: SIOCGIFCONF error: %s", strerror(errno));
return NULL;
}

Expand All @@ -148,19 +158,62 @@ get_interface_list() {
while (ifr < last)
{
/*
* What we want:
* - Interfaces that are up, and not loopback
* - IP interfaces (do we really need this?)
* - Anything that doesn't begin with "lo" (loopback again) or "dummy"
* - Anything that doesn't include a ":" (Solaris virtuals)
* Skip addresses that begin with "dummy", or that include a ":"
* (the latter are Solaris virtuals).
*/
if (strncmp(ifr->ifr_name, "dummy", 5) == 0 ||
strchr(ifr->ifr_name, ':') != NULL)
goto next;

/*
* If we already have this interface name on the list, don't add
* it (SIOCGIFCONF returns, at least on BSD-flavored systems, one
* entry per interface *address*; if an interface has multiple
* addresses, we get multiple entries for it).
*/
user_data.name = ifr->ifr_name;
user_data.found = FALSE;
g_list_foreach(il, search_for_if_cb, &user_data);
if (user_data.found)
goto next;

/*
* Get the interface flags.
*/
memset(&ifrflags, 0, sizeof ifrflags);
strncpy(ifrflags.ifr_name, ifr->ifr_name, sizeof ifrflags.ifr_name);
if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
goto next;
simple_dialog(ESD_TYPE_WARN, NULL,
"Can't list interfaces: SIOCGIFFLAGS error on %s: %s",
ifr->ifr_name, strerror(errno));
goto fail;
}

/*
* Skip interfaces that aren't up.
*/
if (! (ifr->ifr_flags & (IFF_UP | IFF_LOOPBACK)) &&
(ifr->ifr_addr.sa_family == AF_INET) &&
strncmp(ifr->ifr_name, "lo", 2) &&
strncmp(ifr->ifr_name, "dummy", 5) &&
! strchr(ifr->ifr_name, ':')) {
il = g_list_append(il, g_strdup(ifr->ifr_name));
if (!(ifrflags.ifr_flags & IFF_UP))
goto next;

/*
* If it's a loopback interface, add it at the end of the list,
* otherwise add it after the last non-loopback interface,
* so all loopback interfaces go at the end - we don't want a
* loopback interface to be the default capture device unless there
* are no non-loopback devices.
*/
if ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
strncmp(ifr->ifr_name, "lo", 2) == 0)
il = g_list_insert(il, g_strdup(ifr->ifr_name), -1);
else {
il = g_list_insert(il, g_strdup(ifr->ifr_name), nonloopback_pos);
/* Insert the next non-loopback interface after this one. */
nonloopback_pos++;
}

next:
#ifdef HAVE_SA_LEN
ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
#else
Expand All @@ -170,6 +223,26 @@ get_interface_list() {

free(ifc.ifc_buf);
return il;

fail:
g_list_foreach(il, free_if_cb, NULL);
g_list_free(il);
return NULL;
}

static void
search_for_if_cb(gpointer data, gpointer user_data)
{
struct search_user_data *search_user_data = user_data;

if (strcmp((char *)data, search_user_data->name) == 0)
search_user_data->found = TRUE;
}

static void
free_if_cb(gpointer data, gpointer user_data)
{
g_free(data);
}

void
Expand Down Expand Up @@ -268,7 +341,7 @@ capture_prep_cb(GtkWidget *w, gpointer d) {
gtk_widget_show(snap_lb);

adj = (GtkAdjustment *) gtk_adjustment_new((float) cf.snap,
MIN_PACKET_SIZE, MAX_PACKET_SIZE, 1.0, 10.0, 0.0);
MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0);
snap_sb = gtk_spin_button_new (adj, 0, 0);
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE);
gtk_widget_set_usize (snap_sb, 80, 0);
Expand Down Expand Up @@ -330,7 +403,7 @@ capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w) {
cf.count = atoi(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(count_cb)->entry)));
cf.snap = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
if (cf.snap < 1)
cf.snap = MAX_PACKET_SIZE;
cf.snap = WTAP_MAX_PACKET_SIZE;
else if (cf.snap < MIN_PACKET_SIZE)
cf.snap = MIN_PACKET_SIZE;

Expand Down Expand Up @@ -427,7 +500,6 @@ typedef struct _loop_data {
gint go;
gint max;
gint linktype;
gint wtap_linktype;
gint sync_packets;
packet_counts counts;
wtap_dumper *pdh;
Expand All @@ -449,7 +521,7 @@ capture(void) {
ld.go = TRUE;
ld.counts.total = 0;
ld.max = cf.count;
ld.linktype = DLT_NULL;
ld.linktype = WTAP_ENCAP_UNKNOWN;
ld.sync_packets = 0;
ld.counts.tcp = 0;
ld.counts.udp = 0;
Expand All @@ -465,15 +537,14 @@ capture(void) {
pch = pcap_open_live(cf.iface, cf.snap, 1, 250, err_str);

if (pch) {
ld.linktype = pcap_datalink(pch);
ld.wtap_linktype = wtap_pcap_encap_to_wtap_encap(ld.linktype);
if (ld.wtap_linktype == WTAP_ENCAP_UNKNOWN) {
ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(pch));
if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
errmsg = "The network you're capturing from is of a type"
" that Ethereal doesn't support.";
goto fail;
}
ld.pdh = wtap_dump_fdopen(cf.save_file_fd, WTAP_FILE_PCAP,
ld.wtap_linktype, pcap_snapshot(pch), &err);
ld.linktype, pcap_snapshot(pch), &err);

if (ld.pdh == NULL) { /* We have an error */
switch (err) {
Expand Down Expand Up @@ -740,29 +811,41 @@ capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
whdr.ts = phdr->ts;
whdr.caplen = phdr->caplen;
whdr.len = phdr->len;
whdr.pkt_encap = ld->wtap_linktype;
whdr.pkt_encap = ld->linktype;

/* XXX - do something if this fails */
wtap_dump(ld->pdh, &whdr, pd, &err);
}

switch (ld->linktype) {
case DLT_EN10MB :
case WTAP_ENCAP_ETHERNET:
capture_eth(pd, phdr->caplen, &ld->counts);
break;
case DLT_FDDI :
case WTAP_ENCAP_FDDI:
capture_fddi(pd, phdr->caplen, &ld->counts);
break;
case DLT_IEEE802 :
case WTAP_ENCAP_TR:
capture_tr(pd, phdr->caplen, &ld->counts);
break;
case DLT_NULL :
case WTAP_ENCAP_NULL:
capture_null(pd, phdr->caplen, &ld->counts);
break;
case DLT_PPP :
case WTAP_ENCAP_PPP:
capture_ppp(pd, phdr->caplen, &ld->counts);
break;
case DLT_RAW :
#if 0
#ifdef DLT_ENC
case DLT_ENC : /* XXX - OpenBSD "IPSEC enc type (af header, spi,
flags)" */
#endif
#ifdef DLT_LOOP
case DLT_LOOP : /* XXX - prepended 4-byte AF_xxxx value in OpenBSD,
network byte order */
#endif
#endif
/* XXX - FreeBSD may append 4-byte ATM pseudo-header
to DLT_ATM_RFC1483, with LLC header following */
case WTAP_ENCAP_RAW_IP:
capture_raw(pd, phdr->caplen, &ld->counts);
break;
}
Expand Down
6 changes: 3 additions & 3 deletions ethereal.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* ethereal.c
*
* $Id: ethereal.c,v 1.101 1999/08/20 21:57:29 guy Exp $
* $Id: ethereal.c,v 1.102 1999/08/22 00:47:44 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
Expand Down Expand Up @@ -1101,7 +1101,7 @@ main(int argc, char *argv[])
cf.save_file = NULL;
cf.save_file_fd = -1;
cf.user_saved = 0;
cf.snap = MAX_PACKET_SIZE;
cf.snap = WTAP_MAX_PACKET_SIZE;
cf.count = 0;
cf.cinfo.num_cols = prefs->num_cols;
cf.cinfo.col_fmt = (gint *) g_malloc(sizeof(gint) * cf.cinfo.num_cols);
Expand Down Expand Up @@ -1258,7 +1258,7 @@ main(int argc, char *argv[])
}

if (cf.snap < 1)
cf.snap = MAX_PACKET_SIZE;
cf.snap = WTAP_MAX_PACKET_SIZE;
else if (cf.snap < MIN_PACKET_SIZE)
cf.snap = MIN_PACKET_SIZE;

Expand Down
3 changes: 1 addition & 2 deletions ethereal.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* ethereal.h
* Global defines, etc.
*
* $Id: ethereal.h,v 1.21 1999/08/12 07:36:40 guy Exp $
* $Id: ethereal.h,v 1.22 1999/08/22 00:47:44 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
Expand Down Expand Up @@ -41,7 +41,6 @@
#endif

#define MIN_PACKET_SIZE 68 /* minimum amount of packet data we can read */
#define MAX_PACKET_SIZE 65535 /* maximum amount of packet data we can read */

/* Byte swapping routines */
#define SWAP16(x) \
Expand Down
4 changes: 3 additions & 1 deletion etypes.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* etypes.h
* Defines ethernet packet types, similar to tcpdump's ethertype.h
*
* $Id: etypes.h,v 1.6 1999/06/22 22:02:11 gram Exp $
* $Id: etypes.h,v 1.7 1999/08/22 00:47:42 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
Expand All @@ -26,6 +26,8 @@
#ifndef __ETYPES_H__
#define __ETYPES_H__

#define IEEE_802_3_MAX_LEN 1500

#ifndef ETHERTYPE_UNK
#define ETHERTYP_UNK 0x0000
#endif
Expand Down
11 changes: 9 additions & 2 deletions file.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
* $Id: file.c,v 1.77 1999/08/20 20:37:47 gram Exp $
* $Id: file.c,v 1.78 1999/08/22 00:47:43 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
Expand Down Expand Up @@ -257,6 +257,10 @@ read_cap_file(capture_file *cf) {
" in the middle of a packet.";
break;

case WTAP_ERR_BAD_RECORD:
errmsg = "The capture file appears to be damaged or corrupt.";
break;

default:
if (err < 0) {
sprintf(errmsg_errno, "An error occurred while reading the"
Expand Down Expand Up @@ -1018,10 +1022,13 @@ file_open_error_message(int err, int for_writing)

case WTAP_ERR_FILE_UNKNOWN_FORMAT:
case WTAP_ERR_UNSUPPORTED:
case WTAP_ERR_BAD_RECORD:
errmsg = "The file \"%s\" is not a capture file in a format Ethereal understands.";
break;

case WTAP_ERR_BAD_RECORD:
errmsg = "The file \"%s\" appears to be damaged or corrupt.";
break;

case WTAP_ERR_CANT_OPEN:
if (for_writing)
errmsg = "The file \"%s\" could not be created for some unknown reason.";
Expand Down
10 changes: 2 additions & 8 deletions file.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* file.h
* Definitions for file structures and routines
*
* $Id: file.h,v 1.38 1999/08/18 16:28:22 gram Exp $
* $Id: file.h,v 1.39 1999/08/22 00:47:43 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
Expand Down Expand Up @@ -76,13 +76,7 @@ typedef struct _capture_file {
gchar *cfilter; /* Capture filter string */
bpf_prog fcode; /* Compiled capture filter program */
#endif
/* XXX - I'm cheating for now. I'll hardcode 65536 here until I re-arrange
* more header files so that ethereal.h is split up into two files, a
* generic header and a gtk+-specific header (or the gtk+ definitions are
* moved to different header files) --gilbert
*/
/*guint8 pd[MAX_PACKET_SIZE];*/ /* Packet data */
guint8 pd[65536]; /* Packet data */
guint8 pd[WTAP_MAX_PACKET_SIZE]; /* Packet data */
frame_data *plist; /* Packet list */
frame_data *plist_end; /* Last packet in list */
column_info cinfo; /* Column formatting information */
Expand Down
4 changes: 1 addition & 3 deletions packet-eth.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* packet-eth.c
* Routines for ethernet packet disassembly
*
* $Id: packet-eth.c,v 1.16 1999/08/20 06:55:06 guy Exp $
* $Id: packet-eth.c,v 1.17 1999/08/22 00:47:43 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
Expand Down Expand Up @@ -45,8 +45,6 @@ static int hf_eth_src = -1;
static int hf_eth_len = -1;
static int hf_eth_type = -1;

#define IEEE_802_3_MAX_LEN 1500

#define ETH_HEADER_SIZE 14

/* These are the Netware-ish names for the different Ethernet frame types.
Expand Down
Loading

0 comments on commit ee39938

Please sign in to comment.