* Copyright 2001, Michal Melerowicz <michal.melerowicz@nokia.com>
* Nicolas Balkota <balkota@mac.com>
*
- * $Id: packet-gtp.c,v 1.39 2002/10/26 06:13:33 guy Exp $
+ * $Id: packet-gtp.c,v 1.53 2003/02/07 19:57:19 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
#include <epan/packet.h>
#include "packet-gtp.h"
#include "packet-ipv6.h"
-#include "ppptypes.h"
+#include "packet-ppp.h"
#include "prefs.h"
/*
static int gtpv0_port = 0;
static int gtpv1c_port = 0;
static int gtpv1u_port = 0;
-static gboolean ppp_reorder = TRUE;
/* Definition of flags masks */
#define GTP_VER_MASK 0xE0
#define GTP_MSG_DATA_TRANSF_RESP 0xF1
#define GTP_MSG_TPDU 0xFF
-#define GTP_PPP_0x00 0x00
-#define GTP_PPP_0xC0 0xC0
-#define GTP_PPP_0x80 0x80
-#define GTP_PPP_0xC2 0xC2
-#define GTP_PPP_REQ_ERROR 0xFF
-
static const value_string message_type[] = {
{ GTP_MSG_UNKNOWN, "For future use" },
{ GTP_MSG_ECHO_REQ, "Echo request" },
static const value_string gtp_val[] = {
{ GTP_EXT_CAUSE, "Cause of operation" },
- { GTP_EXT_IMSI, "IMSI " },
+ { GTP_EXT_IMSI, "IMSI" },
{ GTP_EXT_RAI, "Routing Area Identity" },
{ GTP_EXT_TLLI, "Temporary Logical Link Identity" },
{ GTP_EXT_PTMSI, "Packet TMSI" },
{ GTP_EXT_RAB_CNTXT, "RAB context" }, /* 3G */
{ GTP_EXT_RP_SMS, "Radio Priority for MO SMS" }, /* 3G */
{ GTP_EXT_RP, "Radio Priority" }, /* 3G */
- { GTP_EXT_PKT_FLOW_ID, "Packet Flow ID " }, /* 3G */
+ { GTP_EXT_PKT_FLOW_ID, "Packet Flow ID" }, /* 3G */
{ GTP_EXT_CHRG_CHAR, "Charging characteristics" }, /* 3G */
{ GTP_EXT_TRACE_REF, "Trace references" }, /* 3G */
{ GTP_EXT_TRACE_TYPE, "Trace type" }, /* 3G */
{ GTPv1_EXT_MS_REASON, "MS not reachable reason" }, /* 3G */
{ GTP_EXT_TR_COMM, "Packet transfer command" }, /* charging */
{ GTP_EXT_CHRG_ID, "Charging ID" },
- { GTP_EXT_USER_ADDR, "End user address " },
+ { GTP_EXT_USER_ADDR, "End user address" },
{ GTP_EXT_MM_CNTXT, "MM context" },
{ GTP_EXT_PDP_CNTXT, "PDP context" },
{ GTP_EXT_APN, "Access Point Name" },
{ GTP_EXT_TARGET_ID, "Target (RNC) identification" }, /* 3G */
{ GTP_EXT_UTRAN_CONT, "UTRAN transparent field" }, /* 3G */
{ GTP_EXT_RAB_SETUP, "RAB setup information" }, /* 3G */
- { GTP_EXT_HDR_LIST, "Extension Header Types List " }, /* 3G */
- { GTP_EXT_TRIGGER_ID, "Trigger Id " }, /* 3G */
- { GTP_EXT_OMC_ID, "OMC Identity " }, /* 3G */
+ { GTP_EXT_HDR_LIST, "Extension Header Types List" }, /* 3G */
+ { GTP_EXT_TRIGGER_ID, "Trigger Id" }, /* 3G */
+ { GTP_EXT_OMC_ID, "OMC Identity" }, /* 3G */
{ GTP_EXT_REL_PACK, "Sequence numbers of released packets IE" }, /* charging */
{ GTP_EXT_CAN_PACK, "Sequence numbers of canceled packets IE" }, /* charging */
{ GTP_EXT_CHRG_ADDR, "Charging Gateway address" },
{ GTP_EXT_DATA_REQ, "Data record packet" }, /* charging */
{ GTP_EXT_DATA_RESP, "Requests responded" }, /* charging */
{ GTP_EXT_NODE_ADDR, "Address of recommended node" }, /* charging */
- { GTP_EXT_PRIV_EXT, "Private Extension " },
+ { GTP_EXT_PRIV_EXT, "Private Extension" },
{ 0, NULL }
};
{ 0x10, "Channel mode modify" },
{ 0x12, "RR status" },
{ 0x17, "Channel mode modify ack" },
- { 0x14, "Frequency redefinition " },
+ { 0x14, "Frequency redefinition" },
{ 0x15, "Measurement report" },
{ 0x16, "Classmark change" },
{ 0x13, "Classmark enquiry" },
};
static dissector_handle_t ip_handle;
+static dissector_handle_t ipv6_handle;
static dissector_handle_t ppp_handle;
+static dissector_handle_t data_handle;
static int decode_gtp_cause (tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
static int decode_gtp_imsi (tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
return p;
}
+static gchar *
+imsi_to_str(const guint8 *ad) {
+
+ static gchar *str[16];
+ gchar *p;
+ guint8 i, j = 0;
+
+ p = (gchar *)&str[0];
+ for (i=0;i<8;i++) {
+ if ((ad[i] & 0x0F) <= 9) p[j++] = (ad[i] & 0x0F) + 0x30;
+ if (((ad[i] >> 4) & 0x0F) <= 9) p[j++] = ((ad[i] >> 4) & 0x0F) + 0x30;
+ }
+ p[j] = 0;
+
+ return p;
+}
+
static gchar *
msisdn_to_str(const guint8 *ad, int len) {
static int
decode_gtp_imsi(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) {
- guint8 tid_val[8];
- gchar *tid_str;
+ guint8 imsi_val[8];
+ gchar *imsi_str;
- tvb_memcpy(tvb, tid_val, offset+1, 8);
- tid_val[1] = tid_val[1] & 0x0F;
- tid_str = id_to_str(tid_val);
+ tvb_memcpy(tvb, imsi_val, offset+1, 8);
+ imsi_str = imsi_to_str (imsi_val);
- proto_tree_add_string(tree, gtp_version ? hf_gtpv1_imsi : hf_gtpv0_imsi, tvb, offset, 9, tid_str);
+ proto_tree_add_string(tree, gtp_version ? hf_gtpv1_imsi : hf_gtpv0_imsi, tvb, offset, 9, imsi_str);
return 9;
}
}
-/* GPRS: 12.15
+/* GPRS: 12.15 v7.6.0, chapter 7.3.3, page 45
* UMTS: 33.015
*/
static int
guint8 tr_command;
- tr_command = tvb_get_ntohl(tvb, offset+1);
+ tr_command = tvb_get_guint8(tvb, offset+1);
proto_tree_add_uint(tree, gtp_version ? hf_gtpv1_tr_comm : hf_gtpv0_tr_comm, tvb, offset, 2, tr_command);
guint16 length, quint_len, net_cap, con_len;
guint8 cksn, count, sec_mode, cipher, trans_id, proto_disc, message, drx_split, drx_len, drx_ccch, non_drx_timer;
- guint32 kc[4], ik[4];
proto_tree *ext_tree_mm;
proto_item *te;
} else {
proto_tree_add_text(ext_tree_mm, tvb, offset+4, 1, "Ciphering: GEA/%u", cipher);
}
- tvb_memcpy(tvb, (guint8 *)&kc, offset+5, 16);
- proto_tree_add_text(ext_tree_mm, tvb, offset+5, 16, "Ciphering key CK: %x%x%x%x", kc[0], kc[1], kc[2], kc[3]);
- tvb_memcpy(tvb, (guint8 *)&ik, offset+21, 16);
- proto_tree_add_text(ext_tree_mm, tvb, offset+21, 16, "Integrity key CK: %x%x%x%x", ik[0], ik[1], ik[2], ik[3]);
+ proto_tree_add_text(ext_tree_mm, tvb, offset+5, 16, "Ciphering key CK: %s", tvb_bytes_to_str(tvb, offset+5, 16));
+ proto_tree_add_text(ext_tree_mm, tvb, offset+21, 16, "Integrity key CK: %s", tvb_bytes_to_str(tvb, offset+21, 16));
quint_len = tvb_get_ntohs(tvb, offset+37);
proto_tree_add_text(ext_tree_mm, tvb, offset+37, 2, "Quintuplets length: %x", quint_len);
} else {
proto_tree_add_text(ext_tree_mm, tvb, offset+4, 1, "Ciphering: GEA/%u", cipher);
}
- tvb_memcpy(tvb, (guint8 *)&kc, offset+5, 8);
- proto_tree_add_text(ext_tree_mm, tvb, offset+5, 8, "Ciphering key Kc: %x%x", kc[0], kc[1]);
+ proto_tree_add_text(ext_tree_mm, tvb, offset+5, 8, "Ciphering key Kc: %s", tvb_bytes_to_str(tvb, offset+5, 8));
offset = offset + decode_triplet(tvb, offset+13, ext_tree_mm, count) + 13;
break;
case 2:
- tvb_memcpy(tvb, (guint8 *)&kc, offset+5, 16);
- proto_tree_add_text(ext_tree_mm, tvb, offset+5, 16, "Ciphering key CK: %x%x%x%x", kc[0], kc[1], kc[2], kc[3]);
- tvb_memcpy(tvb, (guint8 *)&ik, offset+21, 16);
- proto_tree_add_text(ext_tree_mm, tvb, offset+21, 16, "Integrity key CK: %x%x%x%x", ik[0], ik[1], ik[2], ik[3]);
+ proto_tree_add_text(ext_tree_mm, tvb, offset+5, 16, "Ciphering key CK: %s", tvb_bytes_to_str(tvb, offset+5, 16));
+ proto_tree_add_text(ext_tree_mm, tvb, offset+21, 16, "Integrity key CK: %s", tvb_bytes_to_str(tvb, offset+21, 16));
quint_len = tvb_get_ntohs(tvb, offset+37);
proto_tree_add_text(ext_tree_mm, tvb, offset+37, 2, "Quintuplets length: %x", quint_len);
} else {
proto_tree_add_text(ext_tree_mm, tvb, offset+4, 1, "Ciphering: GEA/%u", cipher);
}
- tvb_memcpy(tvb, (guint8 *)&kc, offset+5, 8);
- proto_tree_add_text(ext_tree_mm, tvb, offset+5, 8, "Ciphering key Kc: %x%x", kc[0], kc[1]);
+ proto_tree_add_text(ext_tree_mm, tvb, offset+5, 8, "Ciphering key Kc: %s", tvb_bytes_to_str(tvb, offset+5, 8));
quint_len = tvb_get_ntohs(tvb, offset+13);
proto_tree_add_text(ext_tree_mm, tvb, offset+13, 2, "Quintuplets length: %x", quint_len);
guint8 utf8_type = 1;
/* In RADIUS messages the QoS has a version field of two octets prepended.
+ * As of 29.061 v.3.a.0, there is an hyphen between "Release Indicator" and
+ * <release specific QoS IE UTF-8 encoding>. Even if it sounds rather
+ * inconsistent and unuseful, I will check hyphen presence here and
+ * will signal its presence.
* */
guint8 version_buffer[2];
+ guint8 hyphen;
/* Will keep the value that will be returned
* */
version_buffer[1] = tvb_get_guint8(tvb, offset + 2);
proto_tree_add_text (ext_tree_qos, tvb, offset + 1, 2, "Version: %c%c", version_buffer[0], version_buffer[1]);
+ /* Hyphen handling */
+ hyphen = tvb_get_guint8(tvb, offset + 3);
+ if (hyphen == ((guint8) '-'))
+ {
+ /* Hyphen is present, put in protocol tree */
+ proto_tree_add_text (ext_tree_qos, tvb, offset + 3, 1, "Hyphen separator: -");
+ offset++; /* "Get rid" of hyphen */
+ }
+
/* Now, we modify offset here and in order to use type later
* effectively.*/
offset += 2;
decode_gtp_proto_conf(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) {
guint16 length, proto_offset;
- guint8 *ptr, conf, proto_len, tmp, msg, cnt = 1;
+ guint16 proto_id;
+ guint8 conf, proto_len, cnt = 1;
tvbuff_t *next_tvb;
proto_tree *ext_tree_proto;
proto_item *te;
+ gboolean save_writable;
length = tvb_get_ntohs(tvb, offset + 1);
for (;;) {
if (proto_offset >= length) break;
+ proto_id = tvb_get_ntohs (tvb, offset);
proto_len = tvb_get_guint8 (tvb, offset + 2);
proto_offset += proto_len + 3; /* 3 = proto id + length byte */
- if ((proto_len > 0) && ppp_reorder) {
-
- /* this part changes layout of GTP payload:
- * it swaps "length field" with "protocol header" */
-
- ptr = (guint8 *)tvb_get_ptr(tvb, offset, 3);
-
- tmp = ptr[2];
- ptr[2] = ptr[1];
- ptr[1] = ptr[0];
- ptr[0] = tmp;
-
- proto_tree_add_text (ext_tree_proto, tvb, offset, 3, "[WARNING] Next 3 bytes were swapped to allow processing PPP section");
- proto_tree_add_text (ext_tree_proto, tvb, offset, 1, "Protocol %u length: %u", cnt, proto_len);
-
- next_tvb = tvb_new_subset (tvb, offset + 1, proto_len + 2, proto_len + 2);
- call_dissector(ppp_handle, next_tvb, pinfo, ext_tree_proto);
-
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "GTP");
-
- if (check_col(pinfo->cinfo, COL_INFO)) {
-
- msg = tvb_get_guint8(tvb, 1);
-
- col_set_str(pinfo->cinfo, COL_INFO, val_to_str(msg, message_type, "Unknown"));
+ if (proto_len > 0) {
+
+ proto_tree_add_text (ext_tree_proto, tvb, offset, 2, "Protocol %u ID: %s (0x%04x)",
+ cnt, val_to_str(proto_id, ppp_vals, "Unknown"),
+ proto_id);
+ proto_tree_add_text (ext_tree_proto, tvb, offset+2, 1, "Protocol %u length: %u", cnt, proto_len);
+
+ /*
+ * Don't allow the dissector for the configuration
+ * protocol in question to update the columns - this
+ * is GTP, not PPP.
+ */
+ save_writable = col_get_writable(pinfo->cinfo);
+ col_set_writable(pinfo->cinfo, FALSE);
+
+ /*
+ * XXX - should we have our own dissector table,
+ * solely for configuration protocols, so that bogus
+ * values don't cause us to dissect the protocol
+ * data as, for example, IP?
+ */
+ next_tvb = tvb_new_subset (tvb, offset + 3, proto_len, proto_len);
+ if (!dissector_try_port(ppp_subdissector_table,
+ proto_id, next_tvb, pinfo, ext_tree_proto)) {
+ call_dissector(data_handle, next_tvb, pinfo,
+ ext_tree_proto);
}
+
+ col_set_writable(pinfo->cinfo, save_writable);
}
offset += proto_len + 3;
decode_gtp_tft(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) {
guint16 length, port1, port2, tos;
- guint8 tft_flags, tft_code, no_packet_filters, i, pf_id, pf_eval, pf_len, pf_content_id, pf_offset, proto, spare;
+ guint8 tft_flags, tft_code, no_packet_filters, i, pf_id, pf_eval, pf_len, pf_content_id, proto, spare;
+ guint pf_offset;
guint32 mask_ipv4, addr_ipv4, ipsec_id, label;
struct e_in6_addr addr_ipv6, mask_ipv6;
proto_tree *ext_tree_tft, *ext_tree_tft_pf, *ext_tree_tft_flags;
gtpv0_hdr.length = g_ntohs(gtpv0_hdr.length);
gtpv0_hdr.seq_no = g_ntohs(gtpv0_hdr.seq_no);
+ gtpv0_hdr.flow_label = g_ntohs(gtpv0_hdr.flow_label);
proto_tree_add_uint(gtpv0_tree, hf_gtpv0_message_type, tvb, 1, 1, gtpv0_hdr.message);
proto_tree_add_uint(gtpv0_tree, hf_gtpv0_length, tvb, 2, 2, gtpv0_hdr.length);
proto_tree_add_uint(gtpv0_tree, hf_gtpv0_seq_number, tvb, 4, 2, gtpv0_hdr.seq_no);
}
}
-/* next part dissects sublayers of GTP
- * right now it's only IP */
+/* next part dissects sublayers of GTP */
if ((gtpv0_hdr.message == GTP_MSG_TPDU) && gtp_tpdu) {
- next_tvb = tvb_new_subset(tvb, 20, -1, -1);
- call_dissector(ip_handle, next_tvb, pinfo, tree);
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_append_str_gtp(pinfo->cinfo, COL_PROTOCOL, "GTP");
+ guint8 sub_proto;
+
+ sub_proto = tvb_get_guint8(tvb,GTPv0_HDR_LENGTH);
+
+ if ((sub_proto >= 0x45) && (sub_proto <= 0x4e)) {
+ /* this is most likely an IPv4 packet */
+ /* we can exclude 0x40 - 0x44 because the minimum header size is 20 octets */
+ /* 0x4f is excluded because PPP protocol type "IPv6 header compression"
+ with protocol field compression is more likely than a plain IPv4 packet with 60 octet header size */
+
+ next_tvb = tvb_new_subset(tvb, GTPv0_HDR_LENGTH, -1, -1);
+ call_dissector(ip_handle, next_tvb, pinfo, tree);
+ } else
+ if ((sub_proto & 0xf0) == 0x60) {
+ /* this is most likely an IPv6 packet */
+ next_tvb = tvb_new_subset(tvb, GTPv0_HDR_LENGTH, -1, -1);
+ call_dissector(ipv6_handle, next_tvb, pinfo, tree);
+ } else {
+ /* this seems to be a PPP packet */
+ guint8 acfield_len = 0;
+
+ if (sub_proto == 0xff) {
+ /* this might be an address field, even it shouldn't be here */
+ guint8 control_field = tvb_get_guint8(tvb,GTPv0_HDR_LENGTH + 1);
+ if (control_field == 0x03) {
+ /* now we are pretty sure that address and control field are mistakenly inserted -> ignore it for PPP dissection */
+ acfield_len = 2;
+ }
+ }
+ next_tvb = tvb_new_subset(tvb, GTPv0_HDR_LENGTH + acfield_len, -1, -1);
+ call_dissector(ppp_handle, next_tvb, pinfo, tree);
+ }
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_append_str_gtp(pinfo->cinfo, COL_PROTOCOL, "GTP");
}
-
}
/* GTP v1 dissector */
sub_proto = tvb_get_guint8(tvb,GTPv1_HDR_LENGTH - hdr_offset);
- switch(sub_proto) {
- case GTP_PPP_0x00:
- case GTP_PPP_0xC0:
- case GTP_PPP_0x80:
- case GTP_PPP_0xC2:
- next_tvb = tvb_new_subset(tvb, GTPv1_HDR_LENGTH - hdr_offset, -1, -1);
- call_dissector(ppp_handle, next_tvb, pinfo, tree);
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_append_str_gtp(pinfo->cinfo, COL_PROTOCOL, "PPP");
- break;
-
- case GTP_PPP_REQ_ERROR:
- sub_proto = tvb_get_guint8(tvb,GTPv1_HDR_LENGTH - hdr_offset+2);
- switch(sub_proto) {
- case GTP_PPP_0x00:
- case GTP_PPP_0xC0:
- case GTP_PPP_0x80:
- case GTP_PPP_0xC2:
- next_tvb = tvb_new_subset(tvb, GTPv1_HDR_LENGTH - hdr_offset+2, -1, -1);
- call_dissector(ppp_handle, next_tvb, pinfo, tree);
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_append_str_gtp(pinfo->cinfo, COL_PROTOCOL, "PPP");
- break;
-
-
- default:
- next_tvb = tvb_new_subset(tvb, GTPv1_HDR_LENGTH - hdr_offset+2, -1, -1);
- call_dissector(ip_handle, next_tvb, pinfo, tree);
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_append_str_gtp(pinfo->cinfo, COL_PROTOCOL, "GTP-U");
- break;
- }
- break;
- default:
- next_tvb = tvb_new_subset(tvb, GTPv1_HDR_LENGTH - hdr_offset, -1, -1);
- call_dissector(ip_handle, next_tvb, pinfo, tree);
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_append_str_gtp(pinfo->cinfo, COL_PROTOCOL, "GTP-U");
- break;
- }
+ if ((sub_proto >= 0x45) && (sub_proto <= 0x4e)) {
+ /* this is most likely an IPv4 packet */
+ /* we can exclude 0x40 - 0x44 because the minimum header size is 20 octets */
+ /* 0x4f is excluded because PPP protocol type "IPv6 header compression"
+ with protocol field compression is more likely than a plain IPv4 packet with 60 octet header size */
+
+ next_tvb = tvb_new_subset(tvb, GTPv1_HDR_LENGTH - hdr_offset, -1, -1);
+ call_dissector(ip_handle, next_tvb, pinfo, tree);
+ } else
+ if ((sub_proto & 0xf0) == 0x60)
+ {
+ /* this is most likely an IPv6 packet */
+ next_tvb = tvb_new_subset(tvb, GTPv1_HDR_LENGTH - hdr_offset, -1, -1);
+ call_dissector(ipv6_handle, next_tvb, pinfo, tree);
+ } else {
+ /* this seems to be a PPP packet */
+ guint8 acfield_len = 0;
+
+ if (sub_proto == 0xff) {
+ /* this might be an address field, even it shouldn't be here */
+ guint8 control_field;
+ control_field = tvb_get_guint8(tvb,GTPv1_HDR_LENGTH - hdr_offset + 1);
+ if (control_field == 0x03)
+ {
+ /* now we are pretty sure that address and control field are mistakenly inserted -> ignore it for PPP dissection */
+ acfield_len = 2;
+ }
+ }
+ next_tvb = tvb_new_subset(tvb, GTPv1_HDR_LENGTH - hdr_offset + acfield_len, -1, -1);
+ call_dissector(ppp_handle, next_tvb, pinfo, tree);
+ }
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_append_str_gtp(pinfo->cinfo, COL_PROTOCOL, "GTP-U");
}
}
{ &hf_gtpv0_ms_valid, { "MS validated", "gtpv0.ms_valid", FT_BOOLEAN, BASE_NONE,NULL, 0, "MS validated", HFILL }},
{ &hf_gtpv0_recovery, { "Recovery", "gtpv0.recovery", FT_UINT8, BASE_DEC, NULL, 0, "Restart counter", HFILL }},
{ &hf_gtpv0_sel_mode, { "Selection mode", "gtpv0.sel_mode", FT_UINT8, BASE_DEC, VALS(sel_mode_type), 0, "Selection Mode", HFILL }},
- { &hf_gtpv0_ext_flow_label, { "Flow Label Data I", "gtpv0.ext_flow_label", FT_UINT16, BASE_DEC, NULL, 0, "Flow label data", HFILL }},
- { &hf_gtpv0_flow_sig, { "Flow label Signalling", "gtpv0.flow_sig", FT_UINT16, BASE_DEC, NULL, 0, "Flow label signalling", HFILL }},
+ { &hf_gtpv0_ext_flow_label, { "Flow Label Data I", "gtpv0.ext_flow_label", FT_UINT16, BASE_HEX, NULL, 0, "Flow label data", HFILL }},
+ { &hf_gtpv0_flow_sig, { "Flow label Signalling", "gtpv0.flow_sig", FT_UINT16, BASE_HEX, NULL, 0, "Flow label signalling", HFILL }},
{ &hf_gtpv0_nsapi, { "NSAPI ", "gtpv0.nsapi", FT_UINT8, BASE_DEC, NULL, 0, "Network layer Service Access Point Identifier", HFILL }},
{ &hf_gtpv0_flow_ii, { "Flow Label Data II ","gtpv0.flow_ii", FT_UINT16, BASE_DEC, NULL, 0, "Downlink flow label data", HFILL }},
{ &hf_gtpv0_ms_reason, { "MS not reachable reason", "gtpv0.ms_reason", FT_UINT8, BASE_DEC, VALS(ms_not_reachable_type), 0, "MS Not Reachable Reason", HFILL }},
{ &hf_gtpv1_teid_cp, { "TEID Control Plane", "gtpv1.teid_cp", FT_UINT32, BASE_HEX, NULL, 0, "Tunnel Endpoint Identifier Control Plane", HFILL }},
{ &hf_gtpv1_nsapi, { "NSAPI", "gtpv1.nsapi", FT_UINT8, BASE_DEC, NULL, 0, "Network layer Service Access Point Identifier", HFILL }},
{ &hf_gtpv1_teid_ii, { "TEID Data II", "gtpv1.teid_ii", FT_UINT32, BASE_HEX, NULL, 0, "Tunnel Endpoint Identifier Data II", HFILL }},
- { &hf_gtpv1_tear_ind, { "Teardown indication","gtpv1.tear_ind", FT_BOOLEAN, BASE_NONE,NULL, 0, "Teardown Indication", HFILL }},
+ { &hf_gtpv1_tear_ind, { "Teardown Indicator","gtpv1.tear_ind", FT_BOOLEAN, BASE_NONE,NULL, 0, "Teardown Indicator", HFILL }},
{ &hf_gtpv1_ranap_cause, { "RANAP cause", "gtpv1.ranap_cause", FT_UINT8, BASE_DEC, VALS(ranap_cause_type), 0, "RANAP cause", HFILL }},
{ &hf_gtpv1_rab_gtpu_dn, { "Downlink GTP-U seq number", "gtpv1.rab_gtp_dn", FT_UINT16, BASE_DEC, NULL, 0, "Downlink GTP-U sequence number", HFILL }},
{ &hf_gtpv1_rab_gtpu_up, { "Uplink GTP-U seq number", "gtpv1.rab_gtp_up", FT_UINT16, BASE_DEC, NULL, 0, "Uplink GTP-U sequence number", HFILL }},
gtp_module = prefs_register_protocol(proto_gtp, proto_reg_handoff_gtp);
- prefs_register_uint_preference(gtp_module, "gtpv0_port", "GTPv0 port ", "GTPv0 port (default 3386)", 10, &g_gtpv0_port);
- prefs_register_uint_preference(gtp_module, "gtpv1c_port", "GTPv1 control plane (GTP-C) port ", "GTPv1 control plane port (default 2123)", 10, &g_gtpv1c_port);
- prefs_register_uint_preference(gtp_module, "gtpv1u_port", "GTPv1 user plane (GTP-U) port ", "GTPv1 user plane port (default 2152)", 10, &g_gtpv1u_port);
- prefs_register_bool_preference(gtp_module, "gtp_dissect_tpdu", "Dissect T-PDU ", "Dissect T-PDU", >p_tpdu);
- prefs_register_enum_preference(gtp_module, "gtpv0_dissect_cdr_as", "Dissect GTP'v0 CDRs as ", "Dissect GTP'v0 CDRs as", >pv0_cdr_as, gtpv0_cdr_options, FALSE);
- prefs_register_bool_preference(gtp_module, "gtpv0_check_etsi", "Compare GTPv0 order with ETSI ", "GTPv0 ETSI order", >pv0_etsi_order);
- prefs_register_bool_preference(gtp_module, "gtpv1_check_etsi", "Compare GTPv1 order with ETSI ", "GTPv1 ETSI order", >pv1_etsi_order);
- prefs_register_bool_preference(gtp_module, "ppp_reorder", "Reorder & dissect PPP in Protocol conf. options", "Reorder & dissect PPP inside of Protocol Configuration Options, 3 bytes will be swapped to allow processing PPP section: 1 byte of length with 2 bytes of protocol id (refer to ETSI 29.060, 7.7.21 & 24.008 10.5.6.3)", &ppp_reorder);
+ prefs_register_uint_preference(gtp_module, "v0_port", "GTPv0 port", "GTPv0 port (default 3386)", 10, &g_gtpv0_port);
+ prefs_register_uint_preference(gtp_module, "v1c_port", "GTPv1 control plane (GTP-C) port", "GTPv1 control plane port (default 2123)", 10, &g_gtpv1c_port);
+ prefs_register_uint_preference(gtp_module, "v1u_port", "GTPv1 user plane (GTP-U) port", "GTPv1 user plane port (default 2152)", 10, &g_gtpv1u_port);
+ prefs_register_bool_preference(gtp_module, "dissect_tpdu", "Dissect T-PDU", "Dissect T-PDU", >p_tpdu);
+ prefs_register_enum_preference(gtp_module, "v0_dissect_cdr_as", "Dissect GTP'v0 CDRs as", "Dissect GTP'v0 CDRs as", >pv0_cdr_as, gtpv0_cdr_options, FALSE);
+ prefs_register_bool_preference(gtp_module, "v0_check_etsi", "Compare GTPv0 order with ETSI", "GTPv0 ETSI order", >pv0_etsi_order);
+ prefs_register_bool_preference(gtp_module, "v1_check_etsi", "Compare GTPv1 order with ETSI", "GTPv1 ETSI order", >pv1_etsi_order);
+ prefs_register_obsolete_preference(gtp_module, "ppp_reorder");
register_dissector("gtpv0", dissect_gtpv0, proto_gtpv0);
register_dissector("gtpv1", dissect_gtpv1, proto_gtpv1);
-
}
void
dissector_add("tcp.port", g_gtpv1c_port, gtpv1_handle);
dissector_add("udp.port", g_gtpv1u_port, gtpv1_handle);
dissector_add("tcp.port", g_gtpv1u_port, gtpv1_handle);
- dissector_add("ppp.protocol", PPP_IP, ip_handle);
ip_handle = find_dissector("ip");
+ ipv6_handle = find_dissector("ipv6");
ppp_handle = find_dissector("ppp");
+ data_handle = find_dissector("data");
}