From 7925fd5f2a01f918847cab3eb6e0839755def2be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stig=20Bj=C3=B8rlykke?= Date: Sun, 20 Apr 2008 11:53:31 +0000 Subject: [PATCH] From Rolf Fiedler (bug 2408): This extends the EyeSDN wiretap module to be able to support: - DSS1/Q.931 - PPP - LAPB/X.25 - ATM raw cells - SS7 MTP2 svn path=/trunk/; revision=25123 --- epan/dissectors/Makefile.common | 1 + epan/dissectors/packet-l1-events.c | 152 +++++++++++++++++++++++++++++ wiretap/eyesdn.c | 102 +++++++++++++++---- wiretap/eyesdn.h | 8 ++ wiretap/wtap.h | 7 ++ 5 files changed, 249 insertions(+), 21 deletions(-) create mode 100644 epan/dissectors/packet-l1-events.c diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common index 2108868e78..a890f93002 100644 --- a/epan/dissectors/Makefile.common +++ b/epan/dissectors/Makefile.common @@ -513,6 +513,7 @@ CLEAN_DISSECTOR_SRC = \ packet-lapbether.c \ packet-lapd.c \ packet-laplink.c \ + packet-l1-events.c \ packet-ldp.c \ packet-lge_monitor.c \ packet-linx.c \ diff --git a/epan/dissectors/packet-l1-events.c b/epan/dissectors/packet-l1-events.c new file mode 100644 index 0000000000..123e88a529 --- /dev/null +++ b/epan/dissectors/packet-l1-events.c @@ -0,0 +1,152 @@ +/* packet-l1-events.c + * Routines for text-based layer 1 message + * + * (C) Rolf Fiedler 2008, based on packet-text-media.c by Olivier Biot, 2004. + * + * $Id$ + * + * Refer to the AUTHORS file or the AUTHORS section in the man page + * for contacting the author(s) of this file. + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ + +/* Edit this file with 4-space tabs */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include +#include +#include + + +/* + * dissector for line-based text messages from layer 1 + */ + +/* Filterable header fields */ +static gint proto_l1_events = -1; + +/* Subtrees */ +static gint ett_l1_events = -1; + +/* Dissector handles */ +static dissector_handle_t l1_events_handle; + +static void +dissect_l1_events(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *subtree; + proto_item *ti; + gint offset = 0, next_offset; + gint len; + const char *data_name; + + data_name = pinfo->match_string; + if (! (data_name && data_name[0])) { + /* + * No information from "match_string" + */ + data_name = (char *)(pinfo->private_data); + if (! (data_name && data_name[0])) { + /* + * No information from "private_data" + */ + data_name = NULL; + } + } + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "Layer1"); + if (check_col(pinfo->cinfo, COL_DEF_SRC)) + col_set_str(pinfo->cinfo, COL_DEF_SRC, + pinfo->pseudo_header->l1event.uton? "TE" : "NT"); + if (check_col(pinfo->cinfo, COL_INFO)) { + len = tvb_find_line_end(tvb, 0, + tvb_ensure_length_remaining(tvb, 0), + &next_offset, FALSE); + if(len>0) + col_set_str(pinfo->cinfo, COL_INFO, + tvb_format_text(tvb, 0, len)); + } + if (tree) { + ti = proto_tree_add_item(tree, proto_l1_events, + tvb, 0, -1, FALSE); + if (data_name) + proto_item_append_text(ti, ": %s", data_name); + subtree = proto_item_add_subtree(ti, ett_l1_events); + /* Read the media line by line */ + while (tvb_reported_length_remaining(tvb, offset) != 0) { + /* + * XXX - we need to be passed the parameters + * of the content type via "pinfo->private_data", + * so that we know the character set. We'd + * have to handle that character set, which + * might be a multibyte character set such + * as "iso-10646-ucs-2", or might require other + * special processing. + */ + len = tvb_find_line_end(tvb, offset, + tvb_ensure_length_remaining(tvb, offset), + &next_offset, FALSE); + if (len == -1) + break; + + /* We use next_offset - offset instead of len in the + * call to tvb_format_text() so it will include the + * line terminator(s) (\r and/or \n) in the display. + */ + proto_tree_add_text(subtree, tvb, offset, next_offset - offset, + "%s", tvb_format_text(tvb, offset, + next_offset - offset)); + offset = next_offset; + } + } +} + +void +proto_register_l1_events(void) +{ + static gint *ett[] = { + &ett_l1_events, + }; + + proto_register_subtree_array(ett, array_length(ett)); + + proto_l1_events = proto_register_protocol( + "Layer 1 Event Messages", /* Long name */ + "Layer 1 Events", /* Short name */ + "data-l1-events"); /* Filter name */ + register_dissector("data-l1-events", dissect_l1_events, + proto_l1_events); +} + +void +proto_reg_handoff_l1_events(void) +{ + l1_events_handle = create_dissector_handle( + dissect_l1_events, proto_l1_events); + + dissector_add("wtap_encap", WTAP_ENCAP_LAYER1_EVENT, l1_events_handle); /* for text msgs from trace files */ +} diff --git a/wiretap/eyesdn.c b/wiretap/eyesdn.c index a8f768b824..3ea86e3395 100644 --- a/wiretap/eyesdn.c +++ b/wiretap/eyesdn.c @@ -43,9 +43,8 @@ * Each Frame starts with the 0xff Flag byte * - Bytes 0-2: timestamp (long usec in network byte order) * - Bytes 3-7: timestamp (40bits sec since 1970 in network byte order) - * - Byte 8: channel (0 for D channel, 1-30 for B1-B30, - * 128 ATM cells, 129 ATM layer indications) - * - Byte 9: Sender (0 NT, 1 TE) + * - Byte 8: channel (0 for D channel, 1-30 for B1-B30) + * - Byte 9: Sender Bit 0(0 NT, 1 TE), Protocol in Bits 7:1, see enum * - Byte 10-11: frame size in bytes * - Byte 12-n: Frame Payload * @@ -58,10 +57,15 @@ */ -static int esc_read(guint8 *buf, int len, FILE_T fh) +static int esc_read(guint8 *buf, int len, FILE_T fh, int seekback) { int i; int value; + gint64 cur_off; + int err; + + if(seekback) cur_off = file_tell(fh); + else cur_off=0; // suppress uninitialized warning for(i=0; idata_offset = 0; - wth->file_encap = WTAP_ENCAP_ISDN; + wth->file_encap = WTAP_ENCAP_PER_PACKET; wth->file_type = WTAP_FILE_EYESDN; wth->snapshot_length = 0; /* not known */ wth->subtype_read = eyesdn_read; @@ -234,7 +243,7 @@ parse_eyesdn_rec_hdr(wtap *wth, FILE_T fh, * for a packet. Read in that header and extract the useful * information. */ - if (esc_read(hdr, EYESDN_HDR_LENGTH, fh) != EYESDN_HDR_LENGTH) { + if (esc_read(hdr, EYESDN_HDR_LENGTH, fh, 0) != EYESDN_HDR_LENGTH) { *err = file_error(fh); if (*err == 0) *err = WTAP_ERR_SHORT_READ; @@ -260,20 +269,73 @@ parse_eyesdn_rec_hdr(wtap *wth, FILE_T fh, pkt_len = ((unsigned long) hdr[10]); pkt_len = (pkt_len << 8) | ((unsigned long) hdr[11]); - /* sanity checks */ - if((channel>30)&&(channel<128)) { - *err = WTAP_ERR_BAD_RECORD; - *err_info = g_strdup_printf("eyesdn: bad channel number %u", - channel); - return -1; - } + switch(direction >> 1) { + default: + case EYESDN_ENCAP_ISDN: // ISDN + pseudo_header->isdn.uton = direction & 1; + pseudo_header->isdn.channel = channel; + if(channel) { // bearer channels + if(wth) { + wth->phdr.pkt_encap = WTAP_ENCAP_ISDN; // recognises PPP + pseudo_header->isdn.uton=!pseudo_header->isdn.uton; // bug + } + } else { // D channel + if(wth) { + wth->phdr.pkt_encap = WTAP_ENCAP_ISDN; + } + } + break; + case EYESDN_ENCAP_MSG: // Layer 1 message + if(wth) { + wth->phdr.pkt_encap = WTAP_ENCAP_LAYER1_EVENT; + } + pseudo_header->l1event.uton = (direction & 1); + break; + case EYESDN_ENCAP_LAPB: // X.25 via LAPB + if(wth) { + wth->phdr.pkt_encap = WTAP_ENCAP_LAPB; + } + pseudo_header->x25.flags = (direction & 1) ? 0 : 0x80; + break; + case EYESDN_ENCAP_ATM: { // ATM cells +#define CELL_LEN 53 + unsigned char cell[CELL_LEN]; + if(pkt_len != CELL_LEN) { + *err = WTAP_ERR_BAD_RECORD; + *err_info = g_strdup_printf("eyesdn: ATM cell has a length " + "!= 53 (%u)", pkt_len); + return -1; + } - if(direction>1) { - *err = WTAP_ERR_BAD_RECORD; - *err_info = g_strdup_printf("eyesdn: bad direction value %u", - direction); - return -1; + if (esc_read(cell, CELL_LEN, fh, 1) != CELL_LEN) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + + if(wth) { + wth->phdr.pkt_encap = WTAP_ENCAP_ATM_PDUS_UNTRUNCATED; + } + pseudo_header->atm.flags=ATM_RAW_CELL; + pseudo_header->atm.aal=AAL_UNKNOWN; + pseudo_header->atm.type=TRAF_UMTS_FP; + pseudo_header->atm.subtype=TRAF_ST_UNKNOWN; + pseudo_header->atm.vpi=((cell[0]&0xf)<<4) + (cell[0]&0xf); + pseudo_header->atm.vci=((cell[0]&0xf)<<4) + cell[0]; // from cell + pseudo_header->atm.channel=direction & 1; } + break; + case EYESDN_ENCAP_MTP2: // SS7 frames + pseudo_header->mtp2.sent = direction & 1; + pseudo_header->mtp2.annex_a_used = MTP2_ANNEX_A_USED_UNKNOWN; + pseudo_header->mtp2.link_number = channel; + if(wth) { + wth->phdr.pkt_encap = WTAP_ENCAP_MTP2; + } + break; + } + if(pkt_len > EYESDN_MAX_PACKET_LEN) { *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup_printf("eyesdn: File has %u-byte packet, bigger than maximum of %u", @@ -287,8 +349,6 @@ parse_eyesdn_rec_hdr(wtap *wth, FILE_T fh, wth->phdr.caplen = pkt_len; wth->phdr.len = pkt_len; } - pseudo_header->isdn.uton = direction; - pseudo_header->isdn.channel = channel; return pkt_len; } @@ -301,7 +361,7 @@ parse_eyesdn_packet_data(FILE_T fh, int pkt_len, guint8* buf, int *err, int bytes_read; errno = WTAP_ERR_CANT_READ; - bytes_read = esc_read(buf, pkt_len, fh); + bytes_read = esc_read(buf, pkt_len, fh, 0); if (bytes_read != pkt_len) { if (bytes_read == -2) { *err = file_error(fh); diff --git a/wiretap/eyesdn.h b/wiretap/eyesdn.h index 63b6cbaf59..43cbf231e6 100644 --- a/wiretap/eyesdn.h +++ b/wiretap/eyesdn.h @@ -26,4 +26,12 @@ int eyesdn_open(wtap *wth, int *err, gchar **err_info); +enum EyeSDN_TYPES { + EYESDN_ENCAP_ISDN=0, + EYESDN_ENCAP_MSG, + EYESDN_ENCAP_LAPB, + EYESDN_ENCAP_ATM, + EYESDN_ENCAP_MTP2 +}; + #endif diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 97b8e5e446..0856e716fa 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -204,6 +204,7 @@ extern "C" { #define WTAP_ENCAP_LIN 107 #define WTAP_ENCAP_MOST 108 #define WTAP_ENCAP_CAN20B 109 +#define WTAP_ENCAP_LAYER1_EVENT 110 #define WTAP_NUM_ENCAP_TYPES wtap_get_num_encap_types() @@ -730,6 +731,11 @@ struct bthci_phdr { #define BTHCI_CHANNEL_SCO 3 #define BTHCI_CHANNEL_EVENT 4 +/* pseudo header for WTAP_ENCAP_LAYER1_EVENT */ +struct l1event_phdr { + gboolean uton; +}; + union wtap_pseudo_header { struct eth_phdr eth; struct x25_phdr x25; @@ -749,6 +755,7 @@ union wtap_pseudo_header { struct erf_mc_phdr erf; struct sita_phdr sita; struct bthci_phdr bthci; + struct l1event_phdr l1event; }; struct wtap_nstime {