Ethereal-dev: [Ethereal-dev] Patch to support vISDN (repost)
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Daniele Orlandi <daniele@xxxxxxxxxxx>
Date: Wed, 1 Mar 2006 00:38:56 +0100
Hello, Someone reported that the patches may have been truncated so I'm resending them, along with URLs to online copies: http://www.orlandi.com/ethereal-visdn.diff http://www.orlandi.com/ethereal-encap-table.diff The attached patch adds support for LAPD frames captured using vISDN thru libpcap. The support has already been included in libpcap. The patch adds a new wiretap encapsulation, the necessary glue to decode SLL-encapsulated frames, and some minor change in the LAPD dissector in order to support the remote-to-remote frames captured on the ISDN E-Channel. Please apply ethereal-encap-table.diff before, as it fixes a misalignment in the encapsulation names table. Let me know if the patches need some adjustment. Thank you, Bye, -- Daniele Orlandi
diff -ur ethereal/wiretap/wtap.c ethereal-encap-table/wiretap/wtap.c
--- ethereal/wiretap/wtap.c 2006-02-20 11:58:18.000000000 +0100
+++ ethereal-encap-table/wiretap/wtap.c 2006-02-20 12:40:33.000000000 +0100
@@ -286,6 +286,9 @@
/* WTAP_ENCAP_NETTL_RAW_ICMPV6 */
{ "Raw ICMPv6 with nettl headers", "raw-icmpv6-nettl" },
+ /* UNUSED */
+ { "", "" },
+
/* WTAP_ENCAP_GPRS_LLC */
{ "GPRS LLC", "gprs-llc" },
@@ -328,6 +331,9 @@
/* WTAP_ENCAP_NETTL_X25 */
{ "X25 with nettl headers", "x25-nettl" },
+ /* WTAP_ENCAP_K12 */
+ { "K12 protocol analyzer", "k12" },
+
/* WTAP_ENCAP_JUNIPER_MLPPP */
{ "Juniper MLPPP", "juniper-mlppp" },
diff -ur ethereal-encap-table/capture-wpcap.c ethereal-visdn/capture-wpcap.c
--- ethereal-encap-table/capture-wpcap.c 2006-02-20 11:58:22.000000000 +0100
+++ ethereal-visdn/capture-wpcap.c 2006-02-20 12:03:29.000000000 +0100
@@ -359,6 +359,9 @@
#ifdef DLT_LINUX_IRDA
DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
#endif
+#ifdef DLT_LINUX_LAPD
+ DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"),
+#endif
#ifdef DLT_LANE8023
DLT_CHOICE(DLT_LANE8023, "Linux 802.3 LANE"),
#endif
diff -ur ethereal-encap-table/epan/column.c ethereal-visdn/epan/column.c
--- ethereal-encap-table/epan/column.c 2006-02-20 11:57:58.000000000 +0100
+++ ethereal-visdn/epan/column.c 2006-02-20 12:07:17.000000000 +0100
@@ -50,7 +50,7 @@
"%rd", "%ud", "%hd", "%rhd", "%uhd", "%nd", "%rnd",
"%und", "%S", "%rS", "%uS", "%D", "%rD", "%uD", "%p",
"%i", "%L", "%B", "%XO", "%XR", "%I", "%c", "%Xs",
- "%Xd", "%V", "%x", "%e", "%H", "%P", "%y", "%v"
+ "%Xd", "%V", "%x", "%e", "%H", "%P", "%y", "%v", "%E"
};
if (fmt < 0 || fmt >= NUM_COL_FMTS)
@@ -109,6 +109,7 @@
"HP-UX Device ID",
"DCE/RPC call (cn_call_id / dg_seqnum)",
"802.1Q VLAN id",
+ "TEI",
};
const gchar *
@@ -209,6 +210,9 @@
case COL_8021Q_VLAN_ID:
fmt_list[COL_8021Q_VLAN_ID] = TRUE;
break;
+ case COL_TEI:
+ fmt_list[COL_TEI] = TRUE;
+ break;
default:
break;
}
@@ -429,6 +433,9 @@
case COL_8021Q_VLAN_ID:
return "0000";
break;
+ case COL_TEI:
+ return "127";
+ break;
default: /* COL_INFO */
return "Source port: kerberos-master Destination port: kerberos-master";
break;
@@ -578,6 +585,9 @@
case 'v':
return COL_8021Q_VLAN_ID;
break;
+ case 'E':
+ return COL_TEI;
+ break;
}
cptr++;
}
diff -ur ethereal-encap-table/epan/column_info.h ethereal-visdn/epan/column_info.h
--- ethereal-encap-table/epan/column_info.h 2006-02-20 11:57:59.000000000 +0100
+++ ethereal-visdn/epan/column_info.h 2006-02-20 12:08:13.000000000 +0100
@@ -99,6 +99,7 @@
COL_HPUX_DEVID, /* HP-UX Nettl Device ID */
COL_DCE_CALL, /* DCE/RPC call id OR datagram sequence number */
COL_8021Q_VLAN_ID, /* 802.1Q vlan ID */
+ COL_TEI, /* q.921 TEI */
NUM_COL_FMTS /* Should always be last */
};
diff -ur ethereal-encap-table/epan/dissectors/packet-frame.c ethereal-visdn/epan/dissectors/packet-frame.c
--- ethereal-encap-table/epan/dissectors/packet-frame.c 2006-02-20 11:57:56.000000000 +0100
+++ ethereal-visdn/epan/dissectors/packet-frame.c 2006-02-20 12:03:29.000000000 +0100
@@ -141,6 +141,13 @@
pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ?
P2P_DIR_SENT : P2P_DIR_RECV;
break;
+
+ case WTAP_ENCAP_LINUX_LAPD:
+ pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 ||
+ pinfo->pseudo_header->lapd.pkttype == 4) ?
+ P2P_DIR_SENT : P2P_DIR_RECV;
+ break;
+
case WTAP_ENCAP_MTP2_WITH_PHDR:
pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ?
P2P_DIR_SENT : P2P_DIR_RECV;
Only in ethereal-visdn/epan/dissectors: packet-frame.c.orig
diff -ur ethereal-encap-table/epan/dissectors/packet-lapd.c ethereal-visdn/epan/dissectors/packet-lapd.c
--- ethereal-encap-table/epan/dissectors/packet-lapd.c 2006-02-20 11:57:56.000000000 +0100
+++ ethereal-visdn/epan/dissectors/packet-lapd.c 2006-02-20 12:03:29.000000000 +0100
@@ -80,6 +80,7 @@
#define LAPD_CR 0x0200 /* Command/Response bit */
#define LAPD_EA1 0x0100 /* First Address Extension bit */
#define LAPD_TEI 0x00fe /* Terminal Endpoint Identifier */
+#define LAPD_TEI_SHIFT 1
#define LAPD_EA2 0x0001 /* Second Address Extension bit */
static const value_string lapd_sapi_vals[] = {
@@ -123,9 +124,11 @@
proto_item *lapd_ti, *addr_ti;
guint16 control;
int lapd_header_len;
- guint16 address, cr, sapi;
- gboolean is_response;
+ guint16 address, cr, sapi, tei;
+ gboolean is_response = 0;
tvbuff_t *next_tvb;
+ char *srcname = "?";
+ char *dstname = "?";
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "LAPD");
@@ -134,25 +137,61 @@
address = tvb_get_ntohs(tvb, 0);
cr = address & LAPD_CR;
+ tei = (address & LAPD_TEI) >> LAPD_TEI_SHIFT;
sapi = (address & LAPD_SAPI) >> LAPD_SAPI_SHIFT;
lapd_header_len = 2; /* address */
- if (pinfo->p2p_dir == P2P_DIR_SENT) {
- is_response = cr ? TRUE : FALSE;
- if(check_col(pinfo->cinfo, COL_RES_DL_DST))
- col_set_str(pinfo->cinfo, COL_RES_DL_DST, "Network");
- if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
- col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "User");
+ if (check_col(pinfo->cinfo, COL_TEI))
+ col_add_fstr(pinfo->cinfo, COL_TEI, "%u", tei);
+
+ if (pinfo->fd->lnk_t == WTAP_ENCAP_LINUX_LAPD) {
+ /* frame is captured via libpcap */
+ if (pinfo->pseudo_header->lapd.pkttype == 4 /*PACKET_OUTGOING*/) {
+ if (pinfo->pseudo_header->lapd.we_network) {
+ is_response = cr ? FALSE : TRUE;
+ srcname = "Local Network";
+ dstname = "Remote User";
+ } else {
+ srcname = "Local User";
+ dstname = "Remote Network";
+ }
+ }
+ else if (pinfo->pseudo_header->lapd.pkttype == 3 /*PACKET_OTHERHOST*/) {
+ // We must be a TE, sniffing what other TE transmit
+
+ is_response = cr ? TRUE : FALSE;
+ srcname = "Remote User";
+ dstname = "Remote Network";
+ }
+ else {
+ // The frame is incoming
+ if (pinfo->pseudo_header->lapd.we_network) {
+ is_response = cr ? TRUE : FALSE;
+ srcname = "Remote User";
+ dstname = "Local Network";
+ } else {
+ is_response = cr ? FALSE : TRUE;
+ srcname = "Remote Network";
+ dstname = "Local User";
+ }
+ }
}
- else {
- /* XXX - what if the direction is unknown? */
+ else if (pinfo->p2p_dir == P2P_DIR_SENT) {
is_response = cr ? FALSE : TRUE;
- if(check_col(pinfo->cinfo, COL_RES_DL_DST))
- col_set_str(pinfo->cinfo, COL_RES_DL_DST, "User");
- if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
- col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "Network");
+ srcname = "Network";
+ dstname = "User";
+ }
+ else if (pinfo->p2p_dir == P2P_DIR_RECV) {
+ is_response = cr ? TRUE : FALSE;
+ srcname = "User";
+ dstname = "Network";
}
+ if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
+ col_set_str(pinfo->cinfo, COL_RES_DL_SRC, srcname);
+ if(check_col(pinfo->cinfo, COL_RES_DL_DST))
+ col_set_str(pinfo->cinfo, COL_RES_DL_DST, dstname);
+
if (tree) {
lapd_ti = proto_tree_add_item(tree, proto_lapd, tvb, 0, -1,
FALSE);
@@ -293,4 +332,9 @@
{
data_handle = find_dissector("data");
tei_handle = find_dissector("tei");
+
+ dissector_handle_t lapd_handle;
+
+ lapd_handle = create_dissector_handle(dissect_lapd, proto_lapd);
+ dissector_add("wtap_encap", WTAP_ENCAP_LINUX_LAPD, lapd_handle);
}
diff -ur ethereal-encap-table/wiretap/libpcap.c ethereal-visdn/wiretap/libpcap.c
--- ethereal-encap-table/wiretap/libpcap.c 2006-02-20 11:58:18.000000000 +0100
+++ ethereal-visdn/wiretap/libpcap.c 2006-02-20 12:38:41.000000000 +0100
@@ -81,6 +81,21 @@
guint16 link_number;
};
+#ifndef ETH_P_LAPD
+#define ETH_P_LAPD 0x0030
+#endif
+
+/*
+ * The fake link-layer header of LAPD packets
+ */
+struct lapd_sll_hdr {
+ guint16 sll_pkttype; /* packet type */
+ guint16 sll_hatype;
+ guint16 sll_halen;
+ guint8 sll_addr[8];
+ guint16 sll_protocol; /* protocol, should be ETH_P_LAPD */
+};
+
/* See source to the "libpcap" library for information on the "libpcap"
file format. */
@@ -119,6 +134,10 @@
union wtap_pseudo_header *pseudo_header);
static gboolean libpcap_read_mtp2_pseudoheader(FILE_T fh,
union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info);
+static gboolean libpcap_get_lapd_pseudoheader(const struct lapd_sll_hdr *lapd_phdr,
+ union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info);
+static gboolean libpcap_read_lapd_pseudoheader(FILE_T fh,
+ union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info);
static gboolean libpcap_read_rec_data(FILE_T fh, guchar *pd, int length,
int *err);
static void libpcap_close(wtap *wth);
@@ -379,6 +398,8 @@
{ 172, WTAP_GCOM_TIE1 },
{ 173, WTAP_GCOM_SERIAL },
+ { 177, WTAP_ENCAP_LINUX_LAPD },
+
/* Ethernet frames prepended with meta-information */
{ 178, WTAP_ENCAP_JUNIPER_ETHER },
/* PPP frames prepended with meta-information */
@@ -1296,6 +1317,29 @@
packet_size -= sizeof (struct mtp2_hdr);
wth->data_offset += sizeof (struct mtp2_hdr);
break;
+
+ case WTAP_ENCAP_LINUX_LAPD:
+ if (packet_size < sizeof (struct lapd_sll_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: LAPD file has a %u-byte packet, too small to have even a LAPD pseudo-header\n",
+ packet_size);
+ return FALSE;
+ }
+ if (!libpcap_read_lapd_pseudoheader(wth->fh, &wth->pseudo_header,
+ err, err_info))
+ return FALSE; /* Read error */
+
+ /*
+ * Don't count the pseudo-header as part of the packet.
+ */
+ orig_size -= sizeof (struct lapd_sll_hdr);
+ packet_size -= sizeof (struct lapd_sll_hdr);
+ wth->data_offset += sizeof (struct lapd_sll_hdr);
+ break;
}
buffer_assure_space(wth->frame_buffer, packet_size);
@@ -1406,6 +1450,14 @@
return FALSE;
}
break;
+
+ case WTAP_ENCAP_LINUX_LAPD:
+ if (!libpcap_read_lapd_pseudoheader(wth->random_fh, pseudo_header,
+ err, err_info)) {
+ /* Read error */
+ return FALSE;
+ }
+ break;
}
/*
@@ -1760,6 +1812,43 @@
}
static gboolean
+libpcap_get_lapd_pseudoheader(const struct lapd_sll_hdr *lapd_phdr,
+ union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
+{
+ if (pntohs(&lapd_phdr->sll_protocol) != ETH_P_LAPD) {
+ *err = WTAP_ERR_BAD_RECORD;
+ if (err_info != NULL)
+ *err_info = g_strdup("libpcap: LAPD capture has a packet with an invalid sll_protocol field\n");
+ return FALSE;
+ }
+
+ pseudo_header->lapd.pkttype = pntohs(&lapd_phdr->sll_pkttype);
+ pseudo_header->lapd.we_network = !!lapd_phdr->sll_addr[0];
+
+ return TRUE;
+}
+
+static gboolean
+libpcap_read_lapd_pseudoheader(FILE_T fh, union wtap_pseudo_header *pseudo_header,
+ int *err, gchar **err_info)
+{
+ struct lapd_sll_hdr lapd_phdr;
+ int bytes_read;
+
+ errno = WTAP_ERR_CANT_READ;
+ bytes_read = file_read(&lapd_phdr, 1, sizeof (struct lapd_sll_hdr), fh);
+ if (bytes_read != sizeof (struct lapd_sll_hdr)) {
+ *err = file_error(fh);
+ if (*err == 0)
+ *err = WTAP_ERR_SHORT_READ;
+ return FALSE;
+ }
+
+ return libpcap_get_lapd_pseudoheader(&lapd_phdr, pseudo_header, err,
+ err_info);
+}
+
+static gboolean
libpcap_read_rec_data(FILE_T fh, guchar *pd, int length, int *err)
{
int bytes_read;
@@ -1944,6 +2033,28 @@
whdr->caplen -= sizeof (struct mtp2_hdr);
pd += sizeof (struct mtp2_hdr);
}
+ else if (linktype == WTAP_ENCAP_LINUX_LAPD) {
+ if (whdr->caplen < sizeof (struct lapd_sll_hdr)) {
+ /*
+ * Uh-oh, the packet isn't big enough to even
+ * have a pseudo-header.
+ */
+ g_message("libpcap: LAPD capture has a %u-byte packet, too small to have even an LAPD pseudo-header\n",
+ whdr->caplen);
+ *err = WTAP_ERR_BAD_RECORD;
+ return NULL;
+ }
+ if (!libpcap_get_lapd_pseudoheader((const struct lapd_sll_hdr *)pd,
+ pseudo_header, err, NULL))
+ return NULL;
+
+ /*
+ * Don't count the pseudo-header as part of the packet.
+ */
+ whdr->len -= sizeof (struct lapd_sll_hdr);
+ whdr->caplen -= sizeof (struct lapd_sll_hdr);
+ pd += sizeof (struct lapd_sll_hdr);
+ }
return pd;
}
#endif
@@ -2056,6 +2167,7 @@
size_t nwritten;
struct sunatm_hdr atm_hdr;
struct irda_sll_hdr irda_hdr;
+ struct lapd_sll_hdr lapd_hdr;
struct mtp2_hdr mtp2_hdr;
int hdrsize;
@@ -2063,6 +2175,8 @@
hdrsize = sizeof (struct sunatm_hdr);
else if (wdh->encap == WTAP_ENCAP_IRDA)
hdrsize = sizeof (struct irda_sll_hdr);
+ else if (wdh->encap == WTAP_ENCAP_LINUX_LAPD)
+ hdrsize = sizeof (struct lapd_sll_hdr);
else
hdrsize = 0;
@@ -2224,6 +2338,24 @@
}
wdh->bytes_dumped += sizeof(mtp2_hdr);
}
+ else if (wdh->encap == WTAP_ENCAP_LINUX_LAPD) {
+ /*
+ * Write the LAPD header.
+ */
+ memset(&lapd_hdr, 0, sizeof(lapd_hdr));
+ lapd_hdr.sll_pkttype = phtons(&pseudo_header->lapd.pkttype);
+ lapd_hdr.sll_protocol = g_htons(ETH_P_LAPD);
+ lapd_hdr.sll_addr[0] = pseudo_header->lapd.we_network?0x01:0x00;
+ nwritten = fwrite(&lapd_hdr, 1, sizeof(lapd_hdr), wdh->fh);
+ if (nwritten != sizeof(lapd_hdr)) {
+ if (nwritten == 0 && ferror(wdh->fh))
+ *err = errno;
+ else
+ *err = WTAP_ERR_SHORT_WRITE;
+ return FALSE;
+ }
+ wdh->bytes_dumped += sizeof(lapd_hdr);
+ }
nwritten = wtap_dump_file_write(wdh, pd, phdr->caplen);
if (nwritten != phdr->caplen) {
diff -ur ethereal-encap-table/wiretap/wtap.c ethereal-visdn/wiretap/wtap.c
--- ethereal-encap-table/wiretap/wtap.c 2006-02-20 12:40:33.000000000 +0100
+++ ethereal-visdn/wiretap/wtap.c 2006-02-20 12:03:29.000000000 +0100
@@ -351,6 +351,9 @@
/* WTAP_ENCAP_JUNIPER_CHDLC */
{ "Juniper C-HDLC", "juniper-chdlc" },
+
+ /* WTAP_ENCAP_LINUX_LAPD */
+ { "LAPD", "lapd" },
};
/* Name that should be somewhat descriptive. */
diff -ur ethereal-encap-table/wiretap/wtap.h ethereal-visdn/wiretap/wtap.h
--- ethereal-encap-table/wiretap/wtap.h 2006-02-20 11:58:18.000000000 +0100
+++ ethereal-visdn/wiretap/wtap.h 2006-02-20 12:04:31.000000000 +0100
@@ -178,9 +178,10 @@
#define WTAP_ENCAP_JUNIPER_FRELAY 86
#define WTAP_ENCAP_JUNIPER_CHDLC 87
#define WTAP_ENCAP_JUNIPER_GGSN 88
+#define WTAP_ENCAP_LINUX_LAPD 89
/* last WTAP_ENCAP_ value + 1 */
-#define WTAP_NUM_ENCAP_TYPES 89
+#define WTAP_NUM_ENCAP_TYPES 90
/* File types that can be read by wiretap.
We support writing some many of these file types, too, so we
@@ -496,6 +497,11 @@
#define K12_PORT_DS1 0x00100008
#define K12_PORT_ATMPVC 0x01020000
+struct lapd_phdr {
+ guint16 pkttype; /* packet type */
+ guint8 we_network;
+};
+
union wtap_pseudo_header {
struct eth_phdr eth;
struct x25_phdr x25;
@@ -509,6 +515,7 @@
struct nettl_phdr nettl;
struct mtp2_phdr mtp2;
struct k12_phdr k12;
+ struct lapd_phdr lapd;
};
struct wtap_nstime {
- Prev by Date: Re: [Ethereal-dev] Re: Preparing for 1.0
- Next by Date: Re: [Ethereal-dev] how to set display filter to get this
- Previous by thread: Re: [Ethereal-dev] how to set display filter to get this
- Next by thread: [Ethereal-dev] how to compile svn code
- Index(es):





