aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap
diff options
context:
space:
mode:
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2004-02-19 08:02:06 +0000
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2004-02-19 08:02:06 +0000
commit7431cacdba311e6ca142e83f8cf26f0fe37c70a6 (patch)
tree1ce3007984c5e36a3fc9b456c6ab564afa899ca6 /wiretap
parenta7bbb5773b025262f6f7f345706e3dc1c2dc77ae (diff)
A DLT_ value of 13, in a Nokia-format capture, appears to be an ATM
capture of some sort. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@10109 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'wiretap')
-rw-r--r--wiretap/libpcap.c244
1 files changed, 193 insertions, 51 deletions
diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c
index 6ae786addf..88a9170f67 100644
--- a/wiretap/libpcap.c
+++ b/wiretap/libpcap.c
@@ -1,6 +1,6 @@
/* libpcap.c
*
- * $Id: libpcap.c,v 1.114 2004/02/12 19:49:08 guy Exp $
+ * $Id: libpcap.c,v 1.115 2004/02/19 08:02:06 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -45,7 +45,7 @@
#endif
/*
- * The link-layer header on ATM packets.
+ * The link-layer header on SunATM packets.
*/
struct sunatm_hdr {
guint8 flags; /* destination and traffic type */
@@ -54,6 +54,15 @@ struct sunatm_hdr {
};
/*
+ * The link-layer header on Nokia IPSO ATM packets.
+ */
+struct nokiaatm_hdr {
+ guint8 flags; /* destination */
+ guint8 vpi; /* VPI */
+ guint16 vci; /* VCI */
+};
+
+/*
* The fake link-layer header of IrDA packets as introduced by Jean Tourrilhes
* to libpcap.
*/
@@ -87,9 +96,11 @@ static gboolean libpcap_seek_read(wtap *wth, long seek_off,
static int libpcap_read_header(wtap *wth, int *err, gchar **err_info,
struct pcaprec_ss990915_hdr *hdr);
static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr);
-static void libpcap_get_atm_pseudoheader(const struct sunatm_hdr *atm_phdr,
+static void libpcap_get_sunatm_pseudoheader(const struct sunatm_hdr *atm_phdr,
union wtap_pseudo_header *pseudo_header);
-static gboolean libpcap_read_atm_pseudoheader(FILE_T fh,
+static gboolean libpcap_read_sunatm_pseudoheader(FILE_T fh,
+ union wtap_pseudo_header *pseudo_header, int *err);
+static gboolean libpcap_read_nokiaatm_pseudoheader(FILE_T fh,
union wtap_pseudo_header *pseudo_header, int *err);
static gboolean libpcap_get_irda_pseudoheader(const struct irda_sll_hdr *irda_phdr,
union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info);
@@ -659,8 +670,19 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
break;
}
}
+
+ /*
+ * We treat a DLT_ value of 13 specially - it appears that in
+ * Nokia libpcap format, it's some form of ATM with what I
+ * suspect is a pseudo-header (even though Nokia's IPSO is
+ * based on FreeBSD, which #defines DLT_SLIP_BSDOS as 13).
+ *
+ * We don't yet know whether this is a Nokia capture, so if
+ * "wtap_pcap_encap_to_wtap_encap()" returned WTAP_ENCAP_UNKNOWN
+ * but "hdr.network" is 13, we don't treat that as an error yet.
+ */
file_encap = wtap_pcap_encap_to_wtap_encap(hdr.network);
- if (file_encap == WTAP_ENCAP_UNKNOWN) {
+ if (file_encap == WTAP_ENCAP_UNKNOWN && hdr.network != 13) {
*err = WTAP_ERR_UNSUPPORTED_ENCAP;
*err_info = g_strdup_printf("pcap: network type %u unknown or unsupported",
hdr.network);
@@ -894,6 +916,22 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info)
}
}
+ if (hdr.network == 13) {
+ /*
+ * OK, if this was a Nokia capture, make it
+ * WTAP_ENCAP_ATM_PDUS, otherwise return
+ * an error.
+ */
+ if (wth->file_type == WTAP_FILE_PCAP_NOKIA)
+ wth->file_encap = WTAP_ENCAP_ATM_PDUS;
+ else {
+ *err = WTAP_ERR_UNSUPPORTED_ENCAP;
+ *err_info = g_strdup_printf("pcap: network type %u unknown or unsupported",
+ hdr.network);
+ return -1;
+ }
+ }
+
return 1;
}
@@ -1039,26 +1077,57 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
switch (wth->file_encap) {
case WTAP_ENCAP_ATM_PDUS:
- if (packet_size < sizeof (struct sunatm_hdr)) {
+ if (wth->file_type == WTAP_FILE_PCAP_NOKIA) {
/*
- * Uh-oh, the packet isn't big enough to even
- * have a pseudo-header.
+ * Nokia IPSO ATM.
*/
- *err = WTAP_ERR_BAD_RECORD;
- *err_info = g_strdup_printf("libpcap: SunATM file has a %u-byte packet, too small to have even an ATM pseudo-header\n",
- packet_size);
- return FALSE;
- }
- if (!libpcap_read_atm_pseudoheader(wth->fh, &wth->pseudo_header,
- err))
- return FALSE; /* Read error */
+ if (packet_size < sizeof (struct nokiaatm_hdr)) {
+ /*
+ * Uh-oh, the packet isn't big enough to even
+ * have a pseudo-header.
+ */
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup_printf("libpcap: Nokia IPSO ATM file has a %u-byte packet, too small to have even an ATM pseudo-header\n",
+ packet_size);
+ return FALSE;
+ }
+ if (!libpcap_read_nokiaatm_pseudoheader(wth->fh,
+ &wth->pseudo_header, err))
+ return FALSE; /* Read error */
- /*
- * Don't count the pseudo-header as part of the packet.
- */
- orig_size -= sizeof (struct sunatm_hdr);
- packet_size -= sizeof (struct sunatm_hdr);
- wth->data_offset += sizeof (struct sunatm_hdr);
+ /*
+ * Don't count the pseudo-header as part of the
+ * packet.
+ */
+ orig_size -= sizeof (struct nokiaatm_hdr);
+ packet_size -= sizeof (struct nokiaatm_hdr);
+ wth->data_offset += sizeof (struct nokiaatm_hdr);
+ } else {
+ /*
+ * SunATM.
+ */
+ if (packet_size < sizeof (struct sunatm_hdr)) {
+ /*
+ * Uh-oh, the packet isn't big enough to even
+ * have a pseudo-header.
+ */
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup_printf("libpcap: SunATM file has a %u-byte packet, too small to have even an ATM pseudo-header\n",
+ packet_size);
+ return FALSE;
+ }
+ if (!libpcap_read_sunatm_pseudoheader(wth->fh,
+ &wth->pseudo_header, err))
+ return FALSE; /* Read error */
+
+ /*
+ * Don't count the pseudo-header as part of the
+ * packet.
+ */
+ orig_size -= sizeof (struct sunatm_hdr);
+ packet_size -= sizeof (struct sunatm_hdr);
+ wth->data_offset += sizeof (struct sunatm_hdr);
+ }
break;
case WTAP_ENCAP_ETHERNET:
@@ -1113,14 +1182,29 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
wth->phdr.len = orig_size;
wth->phdr.pkt_encap = wth->file_encap;
- /*
- * If this is ATM LANE traffic, try to guess what type of LANE
- * traffic it is based on the packet contents.
- */
- if (wth->file_encap == WTAP_ENCAP_ATM_PDUS &&
- wth->pseudo_header.atm.type == TRAF_LANE) {
- atm_guess_lane_type(buffer_start_ptr(wth->frame_buffer),
- wth->phdr.caplen, &wth->pseudo_header);
+ if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) {
+ if (wth->file_type == WTAP_FILE_PCAP_NOKIA) {
+ /*
+ * Nokia IPSO ATM.
+ *
+ * Guess the traffic type based on the packet
+ * contents.
+ */
+ atm_guess_traffic_type(buffer_start_ptr(wth->frame_buffer),
+ wth->phdr.caplen, &wth->pseudo_header);
+ } else {
+ /*
+ * SunATM.
+ *
+ * If this is ATM LANE traffic, try to guess what
+ * type of LANE traffic it is based on the packet
+ * contents.
+ */
+ if (wth->pseudo_header.atm.type == TRAF_LANE) {
+ atm_guess_lane_type(buffer_start_ptr(wth->frame_buffer),
+ wth->phdr.caplen, &wth->pseudo_header);
+ }
+ }
}
return TRUE;
@@ -1137,10 +1221,24 @@ libpcap_seek_read(wtap *wth, long seek_off,
switch (wth->file_encap) {
case WTAP_ENCAP_ATM_PDUS:
- if (!libpcap_read_atm_pseudoheader(wth->random_fh, pseudo_header,
- err)) {
- /* Read error */
- return FALSE;
+ if (wth->file_type == WTAP_FILE_PCAP_NOKIA) {
+ /*
+ * Nokia IPSO ATM.
+ */
+ if (!libpcap_read_nokiaatm_pseudoheader(wth->random_fh,
+ pseudo_header, err)) {
+ /* Read error */
+ return FALSE;
+ }
+ } else {
+ /*
+ * SunATM.
+ */
+ if (!libpcap_read_sunatm_pseudoheader(wth->random_fh,
+ pseudo_header, err)) {
+ /* Read error */
+ return FALSE;
+ }
}
break;
@@ -1166,13 +1264,27 @@ libpcap_seek_read(wtap *wth, long seek_off,
if (!libpcap_read_rec_data(wth->random_fh, pd, length, err))
return FALSE; /* failed */
- /*
- * If this is ATM LANE traffic, try to guess what type of LANE
- * traffic it is based on the packet contents.
- */
- if (wth->file_encap == WTAP_ENCAP_ATM_PDUS &&
- pseudo_header->atm.type == TRAF_LANE)
- atm_guess_lane_type(pd, length, pseudo_header);
+ if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) {
+ if (wth->file_type == WTAP_FILE_PCAP_NOKIA) {
+ /*
+ * Nokia IPSO ATM.
+ *
+ * Guess the traffic type based on the packet
+ * contents.
+ */
+ atm_guess_traffic_type(pd, length, pseudo_header);
+ } else {
+ /*
+ * SunATM.
+ *
+ * If this is ATM LANE traffic, try to guess what
+ * type of LANE traffic it is based on the packet
+ * contents.
+ */
+ if (pseudo_header->atm.type == TRAF_LANE)
+ atm_guess_lane_type(pd, length, pseudo_header);
+ }
+ }
return TRUE;
}
@@ -1301,7 +1413,7 @@ adjust_header(wtap *wth, struct pcaprec_hdr *hdr)
}
static void
-libpcap_get_atm_pseudoheader(const struct sunatm_hdr *atm_phdr,
+libpcap_get_sunatm_pseudoheader(const struct sunatm_hdr *atm_phdr,
union wtap_pseudo_header *pseudo_header)
{
guint8 vpi;
@@ -1310,11 +1422,6 @@ libpcap_get_atm_pseudoheader(const struct sunatm_hdr *atm_phdr,
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) {
case 0x01: /* LANE */
@@ -1381,8 +1488,8 @@ libpcap_get_atm_pseudoheader(const struct sunatm_hdr *atm_phdr,
}
static gboolean
-libpcap_read_atm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
- int *err)
+libpcap_read_sunatm_pseudoheader(FILE_T fh,
+ union wtap_pseudo_header *pseudo_header, int *err)
{
struct sunatm_hdr atm_phdr;
int bytes_read;
@@ -1396,7 +1503,42 @@ libpcap_read_atm_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header
return FALSE;
}
- libpcap_get_atm_pseudoheader(&atm_phdr, pseudo_header);
+ libpcap_get_sunatm_pseudoheader(&atm_phdr, pseudo_header);
+
+ return TRUE;
+}
+
+static gboolean
+libpcap_read_nokiaatm_pseudoheader(FILE_T fh,
+ union wtap_pseudo_header *pseudo_header, int *err)
+{
+ struct nokiaatm_hdr atm_phdr;
+ int bytes_read;
+ guint8 vpi;
+ guint16 vci;
+
+ errno = WTAP_ERR_CANT_READ;
+ bytes_read = file_read(&atm_phdr, 1, sizeof (struct nokiaatm_hdr), fh);
+ if (bytes_read != sizeof (struct nokiaatm_hdr)) {
+ *err = file_error(fh);
+ if (*err == 0)
+ *err = WTAP_ERR_SHORT_READ;
+ return FALSE;
+ }
+
+ vpi = atm_phdr.vpi;
+ vci = pntohs(&atm_phdr.vci);
+
+ pseudo_header->atm.vpi = vpi;
+ pseudo_header->atm.vci = vci;
+ pseudo_header->atm.channel = (atm_phdr.flags & 0x80) ? 0 : 1;
+
+ /* We don't have this information */
+ pseudo_header->atm.flags = 0;
+ pseudo_header->atm.cells = 0;
+ pseudo_header->atm.aal5t_u2u = 0;
+ pseudo_header->atm.aal5t_len = 0;
+ pseudo_header->atm.aal5t_chksum = 0;
return TRUE;
}
@@ -1561,7 +1703,7 @@ wtap_process_pcap_packet(gint linktype, const struct pcap_pkthdr *phdr,
*err = WTAP_ERR_BAD_RECORD;
return NULL;
}
- libpcap_get_atm_pseudoheader((const struct sunatm_hdr *)pd,
+ libpcap_get_sunatm_pseudoheader((const struct sunatm_hdr *)pd,
pseudo_header);
/*