forked from osmocom/wireshark
669db206cb
Also move ncp222.py, x11-fields, process-x11-fields.pl, make-reg-dotc, and make-reg-dotc.py. Adjust #include lines in files that include packet-*.h files. svn path=/trunk/; revision=11410
1687 lines
60 KiB
C
1687 lines
60 KiB
C
/* packet-bssgp.c
|
|
* Routines for BSSGP (BSS GPRS Protocol ETSI GSM 08.18 version 6.7.1 TS 101 343 ) dissection
|
|
* Copyright 2000, Josef Korelus <jkor@quick.cz>
|
|
*
|
|
* $Id$
|
|
*
|
|
* Ethereal - Network traffic analyzer
|
|
* By Gerald Combs <gerald@ethereal.com>
|
|
* 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.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
# include <sys/types.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
# include <netinet/in.h>
|
|
#endif
|
|
|
|
#include <glib.h>
|
|
|
|
#ifdef NEED_SNPRINTF_H
|
|
# include "snprintf.h"
|
|
#endif
|
|
|
|
#include <epan/packet.h>
|
|
/*#include "packet-bssgp.h"*/
|
|
|
|
|
|
/*PDU Type GSM 08.18 version 6.7.1 table 11.27 page 53*/
|
|
#define DL_UNITDATA 0x0
|
|
#define UL_UNITDATA 0x1
|
|
#define RA_CAPABILITY 0X2
|
|
#define PTM_UNITDAT 0X3
|
|
#define PAGING_PS 0X6
|
|
#define PAGING_CS 0x7
|
|
#define RA_CAPABILITY_UPDATE 0X8
|
|
#define RA_CAPABILITY_UPDATE_ACK 0X9
|
|
#define RADIO_STATUS 0xa
|
|
#define SUSPEND 0xb
|
|
#define SUSPEND_ACK 0xc
|
|
#define SUSPEND_NACK 0xd
|
|
#define RESUME 0xe
|
|
#define RESUME_ACK 0xf
|
|
#define RESUME_NACK 0x10
|
|
#define BVC_BLOCK 0x20
|
|
#define BVC_BLOCK_ACK 0x21
|
|
#define BVC_RESET 0X22
|
|
#define BVC_RESET_ACK 0X23
|
|
#define BVC_UNBLOCK 0x24
|
|
#define BVC_UNBLOCK_ACK 0x25
|
|
#define FLOW_CONTROL_BVC 0x26
|
|
#define FLOW_CONTROL_BVC_ACK 0x27
|
|
#define FLOW_CONTROL_MS 0x28
|
|
#define FLOW_CONTROL_MS_ACK 0x29
|
|
#define FLUSH_LL 0x2a
|
|
#define FLUSH_LL_ACK 0x2b
|
|
#define LLC_DISCARDED 0x2c
|
|
#define SGSN_INVOKE_TRACE 0x40
|
|
#define STATUS 0x41
|
|
|
|
|
|
#define BSSGP_M 1
|
|
#define BSSGP_O 2
|
|
#define BSSGP_C 3
|
|
|
|
#define QOSO5CR 0x20
|
|
#define QOSO5T 0x10
|
|
#define QOSO5A 0x08
|
|
#define LOW3B 0x07
|
|
#define ODD_EVEN_INDIC 0x08
|
|
/*GSM 08.18 version 6.7.1 table 11.27*/
|
|
|
|
static const value_string tab_bssgp_pdu_type[] = {
|
|
{ DL_UNITDATA, "DL-UNITDATA" },
|
|
{ UL_UNITDATA, "UL-UNITDATA" },
|
|
{ RA_CAPABILITY, "RA_CAPABILITY" },
|
|
{ PTM_UNITDAT, "PTM-UNITDATA" },
|
|
{ PAGING_PS, "PAGING PS" },
|
|
{ PAGING_CS, "PAGING CS" },
|
|
{ RA_CAPABILITY_UPDATE, "RA-CAPABILITY-UPDATE" },
|
|
{ RA_CAPABILITY_UPDATE_ACK, "RA-CAPABILITY-UPDATE-ACK" },
|
|
{ RADIO_STATUS, "RADIO-STATUS" },
|
|
{ SUSPEND, "SUSPEND" },
|
|
{ SUSPEND_ACK, "SUSPEND-ACK" },
|
|
{ SUSPEND_NACK, "SUSPEND-NACK" },
|
|
{ RESUME, "RESUME" },
|
|
{ RESUME_ACK, "RESUME-ACK" },
|
|
{ RESUME_NACK, "RESUME-NACK" },
|
|
{ BVC_BLOCK, "BVC-BLOCK" },
|
|
{ BVC_BLOCK_ACK, "BVC-BLOCK-ACK" },
|
|
{ BVC_RESET, "BVC-RESET" },
|
|
{ BVC_RESET_ACK, "BVC-RESET-ACK" },
|
|
{ BVC_UNBLOCK, "BVC-UNBLOCK" },
|
|
{ BVC_UNBLOCK_ACK, "BVC_UNBLOCK_ACK" },
|
|
{ FLOW_CONTROL_BVC, "FLOW-CONTROL-BVC" },
|
|
{ FLOW_CONTROL_BVC_ACK, "FLOW-CONTROL-BVC-ACK" },
|
|
{ FLOW_CONTROL_MS, "FLOW-CONTROL-MS" },
|
|
{ FLOW_CONTROL_MS_ACK, "FLOW-CONTROL-MS-ACK" },
|
|
{ FLUSH_LL, "FLUSH-LL" },
|
|
{ FLUSH_LL_ACK, "FLUSH-LL-ACK" },
|
|
{ LLC_DISCARDED, "LLC-DISCARDED" },
|
|
{ SGSN_INVOKE_TRACE, "SGSN_INVOKE_TRACE" },
|
|
{ STATUS, "STATUS" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const value_string bssgp_iei[] = {
|
|
{ 0x0, "Alignment Octets" },
|
|
{ 0x1, "Bmax default MS" },
|
|
{ 0x2, "BSS Area Indication" },
|
|
{ 0x3, "Bucket Leak Rate" },
|
|
{ 0x4, "BVCI" },
|
|
{ 0x5, "BVC Bucket Size" },
|
|
{ 0x6, "BVC Measurment" },
|
|
{ 0x7, "Cause" },
|
|
{ 0x8, "Cell Identifier" },
|
|
{ 0x9, "Channel needed" },
|
|
{ 0xa, "DRX Parameters" },
|
|
{ 0xb, "eMLPP-Priority" },
|
|
{ 0xc, "Flush Action" },
|
|
{ 0xd, "IMSI" },
|
|
{ 0xe, "LLC-PDU"},
|
|
{ 0xf, "LLC Frames Discarded" },
|
|
{ 0x10, "Location Area" },
|
|
{ 0x11, "Mobile Id" },
|
|
{ 0x12, "MS Bucket Size" },
|
|
{ 0x13, "MS Radio Access Capability" },
|
|
{ 0x14, "OMC Id" },
|
|
{ 0x15, "PDU In Error" },
|
|
{ 0x16, "PDU Lifetime" },
|
|
{ 0x17, "Priority" },
|
|
{ 0x18, "QoS Profile" },
|
|
{ 0x19, "Radio Cause" },
|
|
{ 0x1a, "RA-Cap-UPD-Cause" },
|
|
{ 0x1b, "Routeing Area" },
|
|
{ 0x1c, "R_default_MS" },
|
|
{ 0x1d, "Suspend Reference Number" },
|
|
{ 0x1e, "Tag" },
|
|
{ 0x1f, "TLLI" },
|
|
{ 0x20, "TMSI" },
|
|
{ 0x21, "Trace Reference" },
|
|
{ 0x22, "Trace Type" },
|
|
{ 0x23, "Transaction Id" },
|
|
{ 0x24, "Trigger Id" },
|
|
{ 0x25, "Number of octets affected" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const value_string bssgp_cause[] = {
|
|
{ 0x0, "Processor overload" },
|
|
{ 0x1, "Equipment failure" },
|
|
{ 0x2, "Transit network service failure" },
|
|
{ 0x3, "Network service transmission capacity modified from zero kbps to greater than zero" },
|
|
{ 0x4, "Unknown MS" },
|
|
{ 0x5, "BVCI unknown" },
|
|
{ 0x6, "Cell traffic congestion" },
|
|
{ 0x7, "SGSN congestion" },
|
|
{ 0x8, "O&M intervention" },
|
|
{ 0x9, "BVCI-blocked" },
|
|
{ 0x20, "Semantically incorect PDU" },
|
|
{ 0x21, "Invalid mandatory information" },
|
|
{ 0x22, "Missing mandatory information" },
|
|
{ 0x23, "Missing conditional IE" },
|
|
{ 0x24, "Unexpected conditional IE" },
|
|
{ 0x25, "Conditional IE error" },
|
|
{ 0x26, "PDU not compatible with protocol state" },
|
|
{ 0x27, "Protocol error-unspecified" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
#define TOI_IMSI 0x01
|
|
#define TOI_IMEI 0x02
|
|
#define TOI_IMEISV 0x03
|
|
#define TOI_TMSI_P_TMSI 0x04
|
|
#define TOI_NO_IDENTITY 0x00
|
|
|
|
static const value_string type_of_identity[] = {
|
|
{ TOI_IMSI, "IMSI" },
|
|
{ TOI_IMEI, "IMEI" },
|
|
{ TOI_IMEISV, "IMEISV" },
|
|
{ TOI_TMSI_P_TMSI, "TMSI/P-TMSI" },
|
|
{ TOI_NO_IDENTITY, "No identity" },
|
|
{ 0, NULL },
|
|
};
|
|
static const value_string radio_cause[] = {
|
|
{ 0x0, "Radio contact lost with the MS" },
|
|
{ 0x1, "Radio link quality insufficient to continue communication" },
|
|
{ 0x2, "cell-reselction ordered" },
|
|
{ 0, NULL },
|
|
};
|
|
static const true_false_string cr_string = {
|
|
"The SDU does not contain a LLC ACK or SACK command/response frame type",
|
|
"The SDU contains a LLC ACK or SACK command/response frame type",
|
|
};
|
|
static const true_false_string t_string = {
|
|
"The SDU contains data",
|
|
"The SDU contains signalling "
|
|
};
|
|
static const true_false_string a_string = {
|
|
"Radio interface uses RLC/MAC-UNITDATA functionality",
|
|
"Radio interface uses RLC/MAC ARQ functionality"
|
|
};
|
|
static const true_false_string imsi_odd_even = {
|
|
"even number of identity digits and also when the TMSI/P-TMSI is used",
|
|
"odd number of identity digits"
|
|
};
|
|
static const value_string prec_dl[] = {
|
|
{ 0, "High priority"},
|
|
{ 1, "Normal priority"},
|
|
{ 2, "Low priority"},
|
|
{ 3, "Reserved:Taken like Low priority"},
|
|
{ 4, "Reserved:Taken like Low priority"},
|
|
{ 0, NULL},
|
|
};
|
|
static const value_string prec[] = {
|
|
{ 0, "Radio priority 1" },
|
|
{ 1, "Radio priority 2" },
|
|
{ 2, "Radio priority 3" },
|
|
{ 3, "Radio priority 4" },
|
|
{ 4, "Radio priority Unknown" },
|
|
{ 0, NULL },
|
|
};
|
|
static const value_string prec_both[] = {
|
|
{ 0, "High priority/Radio priority 1"},
|
|
{ 1, "Normal priority/Radio priority 2"},
|
|
{ 2, "Low priority/Radio priority 3"},
|
|
{ 3, "Reserved/Radio priority 4"},
|
|
{ 4, "Reserved/Radio priority Unknown"},
|
|
{ 0, NULL},
|
|
};
|
|
|
|
/* Initialize the protocol and registered fields */
|
|
static int proto_bssgp = -1;
|
|
static int hf_bssgp_pdu_type= -1;
|
|
static int hf_bssgp_cause = -1;
|
|
static int hf_bssgp_cid = -1;
|
|
static int hf_bssgp_imsi = -1;
|
|
static int hf_bssgp_imsi_toi = -1;
|
|
static int hf_bssgp_imsi_even_odd_indic = -1;
|
|
static int hf_bssgp_imsi_lsix = -1;
|
|
static int hf_bssgp_tlli = -1;
|
|
/*static int hf_bssgp_tag = -1;
|
|
static int hf_bssgp_tlli_old = -1;
|
|
static int hf_bssgp_aligment = -1;
|
|
static int hf_bssgp_drx_param = -1;
|
|
static int hf_bssgp_ms_radio_cap = -1;
|
|
*/
|
|
static int hf_bssgp_qos = -1;
|
|
static int hf_bssgp_pbr = -1;
|
|
static int hf_bssgp_pdu_lifetime = -1;
|
|
/*static int hf_bssgp_priority = -1;
|
|
static int hf_bssgp_llc_pdu = -1;
|
|
static int hf_bssgp_ptmsi = -1;
|
|
*/
|
|
static int hf_bssgp_bvci = -1;
|
|
/*static int hf_bssgp_la = -1;
|
|
*/
|
|
static int hf_bssgp_ra_mccmnc = -1;
|
|
static int hf_bssgp_ra_lac = -1;
|
|
static int hf_bssgp_ra_rac = -1;
|
|
/*static int hf_bssgp_bss_area = -1;
|
|
static int hf_bssgp_channel_needed = -1;
|
|
static int hf_bssgp_emlpp_priority = -1;
|
|
static int hf_bssgp_ra_cap_upd_cause = -1;
|
|
*/
|
|
static int hf_bssgp_radio_cause = -1;
|
|
/*static int hf_bssgp_sus_ref_num = -1;
|
|
*/
|
|
static int hf_bssgp_bvci_new = -1;
|
|
/*static int hf_bssgp_flush_action = -1;
|
|
static int hf_bssgp_num_oct_affect = -1;
|
|
static int hf_bssgp_llc_disc = -1;
|
|
*/
|
|
static int hf_bssgp_bvc_buck_size = -1;
|
|
static int hf_bssgp_buck_leak_rate = -1;
|
|
static int hf_bssgp_bmax_def_ms = -1;
|
|
static int hf_bssgp_r_defau_ms = -1;
|
|
/*static int hf_bssgp_bvc_measur = -1;
|
|
static int hf_bssgp_ms_buck_size = -1;
|
|
static int hf_bssgp_trace_type = -1;
|
|
static int hf_bssgp_trace_ref = -1;
|
|
static int hf_bssgp_trigg_id = -1;
|
|
static int hf_bssgp_mobile_id = -1;
|
|
static int hf_bssgp_omc_id = -1;
|
|
static int hf_bssgp_transactionid = -1;
|
|
*/
|
|
static int hf_bssgp_ietype = -1;
|
|
static int hf_bssgp_qos_cr = -1;
|
|
static int hf_bssgp_qos_t = -1;
|
|
static int hf_bssgp_qos_a = -1;
|
|
static int hf_bssgp_qos_prec = -1;
|
|
static int hf_bssgp_frdsc = -1;
|
|
static int hf_bssgp_noaff = -1;
|
|
/*static int hf_bssgp_FIELDABBREV = -1;*/
|
|
|
|
/*static dissector_handle_t data_handle;
|
|
*/
|
|
static dissector_handle_t llcgprs_handle;
|
|
|
|
/* Initialize the subtree pointers */
|
|
static gint ett_bssgp = -1;
|
|
static gint ett_bssgp_tlli = -1;
|
|
static gint ett_bssgp_qos = -1;
|
|
static gint ett_bssgp_o5 = -1;
|
|
static gint ett_bssgp_lft = -1;
|
|
static gint ett_bssgp_racc = -1;
|
|
static gint ett_prio_tree = -1;
|
|
static gint ett_drx_tree = -1;
|
|
static gint ett_bssgp_imsi = -1;
|
|
static gint ett_bssgp_imsi_stru_tree = -1;
|
|
static gint ett_algn_tree = -1;
|
|
static gint ett_b_llc_tree = -1;
|
|
static gint ett_celid_tree = -1;
|
|
static gint ett_tag_tree = -1;
|
|
static gint ett_bsize_tree = -1;
|
|
static gint ett_bucklr_tree = -1;
|
|
static gint ett_bmaxms_tree = -1;
|
|
static gint ett_rdefms_tree = -1;
|
|
static gint ett_bvci_tree = -1;
|
|
static gint ett_bvcin_tree = -1;
|
|
static gint ett_cause_tree = -1;
|
|
static gint ett_frdsc_tree = -1;
|
|
static gint ett_noaff_tree = -1;
|
|
static gint ett_racaus_tree = -1;
|
|
static gint ett_ra_tree = -1;
|
|
/*Functions for decoding IEs of BSSGP V6.7.1 */
|
|
typedef struct {
|
|
int type;
|
|
packet_info *pinfo;
|
|
proto_tree *tree;
|
|
int k;
|
|
} dec_fu_param_stru_t;
|
|
static int dcd_bssgp_algn ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_bmaxms ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
/*static int dcd_bssgp_bss_aind ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
static int dcd_bssgp_bucklr ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_bvci ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_bvci_n ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_bvc_bsize ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
/*static int dcd_bssgp_bvc_meas ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
static int dcd_bssgp_cause ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_cellid ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
/*static int dcd_bssgp_chan_need ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
static int dcd_bssgp_drx ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
/*static int dcd_bssgp_emlpp_prio ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_flush_act ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
static int dcd_bssgp_imsi ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_llc_pdu ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_llc_frdsc ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
/*static int dcd_bssgp_la ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_mid ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_ms_buck ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
static int dcd_bssgp_radio_acc ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
/*static int dcd_bssgp_omc_id ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
/*static int dcd_bssgp_pdu_err ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
static int dcd_bssgp_pdu_life ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_prio ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_qos ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_radio_caus ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
/*static int dcd_bssgp_racap_upd ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
static int dcd_bssgp_ra ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_r_def_ms ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
/*static int dcd_bssgp_sus_ref_num( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
static int dcd_bssgp_tag ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_tlli ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
/*static int dcd_bssgp_tlli_o ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
/*static int dcd_bssgp_tmsi ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
/*static int dcd_bssgp_trace_ref ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
/*static int dcd_bssgp_trace_type ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
/*static int dcd_bssgp_trans_id ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
/*static int dcd_bssgp_trig_id ( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
*/
|
|
static int dcd_bssgp_num_oct_aff( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static int dcd_bssgp_not_yet_dcd( tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm );
|
|
static void mccmnc(guint32 mcmn, char buf[]);
|
|
/*---------------------------------------------------------*/
|
|
typedef struct _bssgp_ie {
|
|
guint8 code;
|
|
guint8 presence;
|
|
guint8 type;
|
|
/* int (*decode)(tvbuff_t *, int, int, packet_info *, proto_tree *);
|
|
*/
|
|
int (*decode)(tvbuff_t *, int, dec_fu_param_stru_t *);
|
|
} bssgp_ie_t;
|
|
typedef struct _bssgp_pdu {
|
|
guint8 pdu;
|
|
bssgp_ie_t infe[12];
|
|
} _bssgp_pdu_t;
|
|
/*------------------------------------------------------------*/
|
|
static _bssgp_pdu_t bssgp_pdu[] = {
|
|
{
|
|
DL_UNITDATA, {
|
|
{ 0x1f, BSSGP_M, 3, dcd_bssgp_tlli },
|
|
{ 0x18, BSSGP_M, 3, dcd_bssgp_qos },
|
|
{ 0x16, BSSGP_M, 4, dcd_bssgp_pdu_life },
|
|
{ 0x13, BSSGP_O, 4, dcd_bssgp_radio_acc },
|
|
{ 0x17, BSSGP_O, 4, dcd_bssgp_prio },
|
|
{ 0x0a, BSSGP_O, 4, dcd_bssgp_drx },
|
|
{ 0x0d, BSSGP_O, 4, dcd_bssgp_imsi },
|
|
/* { 0x1f, BSSGP_O, 4, dcd_bssgp_tlli_o },
|
|
*/
|
|
{ 0x1f, BSSGP_O, 4, dcd_bssgp_not_yet_dcd},
|
|
{ 0x00, BSSGP_O, 4, dcd_bssgp_algn },
|
|
{ 0x0e, BSSGP_M, 4, dcd_bssgp_llc_pdu },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
|
|
},
|
|
{
|
|
UL_UNITDATA, {
|
|
{ 0x1f, BSSGP_M, 3, dcd_bssgp_tlli },
|
|
{ 0x18, BSSGP_M, 3, dcd_bssgp_qos },
|
|
{ 0x08, BSSGP_M, 4, dcd_bssgp_cellid },
|
|
{ 0x00, BSSGP_O, 4, dcd_bssgp_algn },
|
|
{ 0x0e, BSSGP_M, 4, dcd_bssgp_llc_pdu },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
RA_CAPABILITY, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x13, BSSGP_M, 4, dcd_bssgp_radio_acc },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
PAGING_PS, {
|
|
{ 0x0d, BSSGP_M, 4, dcd_bssgp_imsi },
|
|
{ 0x0a, BSSGP_O, 4, dcd_bssgp_drx },
|
|
{ 0x04, BSSGP_C, 4, dcd_bssgp_bvci },
|
|
/* { 0x10, BSSGP_C, 4, dcd_bssgp_la },
|
|
*/
|
|
{ 0x10, BSSGP_C, 4, dcd_bssgp_not_yet_dcd},
|
|
{ 0x1b, BSSGP_C, 4, dcd_bssgp_ra },
|
|
/* { 0x02, BSSGP_C, 4, dcd_bssgp_bss_aind },
|
|
*/
|
|
{ 0x02, BSSGP_C, 4, dcd_bssgp_not_yet_dcd},
|
|
{ 0x18, BSSGP_M, 4, dcd_bssgp_qos },
|
|
/* { 0x20, BSSGP_O, 4, dcd_bssgp_tmsi },
|
|
*/
|
|
{ 0x20, BSSGP_O, 4, dcd_bssgp_not_yet_dcd},
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
PAGING_CS, {
|
|
{ 0x0d, BSSGP_M, 4, dcd_bssgp_imsi },
|
|
{ 0x0a, BSSGP_M, 4, dcd_bssgp_drx },
|
|
{ 0x04, BSSGP_C, 4, dcd_bssgp_bvci },
|
|
/* { 0x10, BSSGP_C, 4, dcd_bssgp_la },
|
|
*/
|
|
{ 0x10, BSSGP_C, 4, dcd_bssgp_not_yet_dcd},
|
|
{ 0x1b, BSSGP_C, 4, dcd_bssgp_ra },
|
|
/* { 0x02, BSSGP_C, 4, dcd_bssgp_bss_aind },
|
|
*/
|
|
{ 0x02, BSSGP_C, 4, dcd_bssgp_not_yet_dcd},
|
|
{ 0x1f, BSSGP_O, 4, dcd_bssgp_tlli },
|
|
/* { 0x09, BSSGP_O, 4, dcd_bssgp_chan_need },
|
|
*/
|
|
{ 0x09, BSSGP_O, 4, dcd_bssgp_not_yet_dcd},
|
|
/* { 0x0b, BSSGP_O, 4, dcd_bssgp_emlpp_prio },
|
|
*/
|
|
{ 0x0b, BSSGP_O, 4, dcd_bssgp_not_yet_dcd},
|
|
/* { 0x20, BSSGP_O, 4, dcd_bssgp_tmsi },
|
|
*/
|
|
{ 0x20, BSSGP_O, 4, dcd_bssgp_not_yet_dcd},
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
RA_CAPABILITY_UPDATE, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x1e, BSSGP_M, 4, dcd_bssgp_tag },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
|
|
},
|
|
{
|
|
RA_CAPABILITY_UPDATE_ACK, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x1e, BSSGP_M, 4, dcd_bssgp_tag },
|
|
{ 0x0d, BSSGP_O, 4, dcd_bssgp_imsi },
|
|
/* { 0x1a, BSSGP_M, 4, dcd_bssgp_racap_upd },
|
|
*/
|
|
{ 0x1a, BSSGP_M, 4, dcd_bssgp_not_yet_dcd},
|
|
{ 0x13, BSSGP_C, 4, dcd_bssgp_radio_acc },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
RADIO_STATUS, {
|
|
{ 0x1f, BSSGP_C, 4, dcd_bssgp_tlli },
|
|
/* { 0x20, BSSGP_C, 4, dcd_bssgp_tmsi },
|
|
*/
|
|
{ 0x20, BSSGP_C, 4, dcd_bssgp_not_yet_dcd},
|
|
{ 0x0d, BSSGP_C, 4, dcd_bssgp_imsi },
|
|
{ 0x19, BSSGP_M, 4, dcd_bssgp_radio_caus },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
SUSPEND, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x1b, BSSGP_M, 4, dcd_bssgp_ra },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
SUSPEND_ACK, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x1b, BSSGP_M, 4, dcd_bssgp_ra },
|
|
/* { 0x1d, BSSGP_M, 4, dcd_bssgp_sus_ref_num },
|
|
*/
|
|
{ 0x1d, BSSGP_M, 4, dcd_bssgp_not_yet_dcd},
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
SUSPEND_NACK, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x1b, BSSGP_M, 4, dcd_bssgp_ra },
|
|
{ 0x07, BSSGP_O, 4, dcd_bssgp_cause },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
RESUME, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x1b, BSSGP_M, 4, dcd_bssgp_ra },
|
|
/* { 0x1d, BSSGP_M, 4, dcd_bssgp_sus_ref_num },
|
|
*/
|
|
{ 0x1d, BSSGP_M, 4, dcd_bssgp_not_yet_dcd},
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
RESUME_ACK, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x1b, BSSGP_M, 4, dcd_bssgp_ra },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
RESUME_NACK, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x1b, BSSGP_M, 4, dcd_bssgp_ra },
|
|
{ 0x07, BSSGP_O, 4, dcd_bssgp_cause },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
BVC_BLOCK, {
|
|
{ 0x04, BSSGP_M, 4, dcd_bssgp_bvci },
|
|
{ 0x07, BSSGP_M, 4, dcd_bssgp_cause },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
BVC_BLOCK_ACK, {
|
|
{ 0x04, BSSGP_M, 4, dcd_bssgp_bvci },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
BVC_RESET, {
|
|
{ 0x04, BSSGP_M, 4, dcd_bssgp_bvci },
|
|
{ 0x07, BSSGP_M, 4, dcd_bssgp_cause },
|
|
{ 0x08, BSSGP_C, 4, dcd_bssgp_cellid },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
BVC_RESET_ACK, {
|
|
{ 0x04, BSSGP_M, 4, dcd_bssgp_bvci },
|
|
{ 0x08, BSSGP_C, 4, dcd_bssgp_cellid },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
BVC_UNBLOCK, {
|
|
{ 0x04, BSSGP_M, 4, dcd_bssgp_bvci },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
BVC_UNBLOCK_ACK, {
|
|
{ 0x04, BSSGP_M, 4, dcd_bssgp_bvci },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
FLOW_CONTROL_BVC, {
|
|
{ 0x1e, BSSGP_M, 4, dcd_bssgp_tag },
|
|
{ 0x05, BSSGP_M, 4, dcd_bssgp_bvc_bsize },
|
|
{ 0x03, BSSGP_M, 4, dcd_bssgp_bucklr },
|
|
{ 0x01, BSSGP_M, 4, dcd_bssgp_bmaxms },
|
|
{ 0x1c, BSSGP_M, 4, dcd_bssgp_r_def_ms },
|
|
/* { 0x06, BSSGP_O, 4, dcd_bssgp_bvc_meas }, */
|
|
{ 0x06, BSSGP_O, 4, dcd_bssgp_not_yet_dcd },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
FLOW_CONTROL_BVC_ACK, {
|
|
{ 0x1e, BSSGP_M, 4, dcd_bssgp_tag },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
FLOW_CONTROL_MS, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x1e, BSSGP_M, 4, dcd_bssgp_tag },
|
|
/* { 0x12, BSSGP_M, 4, dcd_bssgp_ms_buck},
|
|
*/
|
|
{ 0x12, BSSGP_M, 4, dcd_bssgp_not_yet_dcd},
|
|
{ 0x03, BSSGP_M, 4, dcd_bssgp_bucklr },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
FLOW_CONTROL_MS_ACK, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x1e, BSSGP_M, 4, dcd_bssgp_tag },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
FLUSH_LL, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x04, BSSGP_M, 4, dcd_bssgp_bvci },
|
|
{ 0x04, BSSGP_O, 4, dcd_bssgp_bvci_n },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
FLUSH_LL_ACK, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
/* { 0x0c, BSSGP_M, 4, dcd_bssgp_flush_act },
|
|
*/
|
|
{ 0x0c, BSSGP_M, 4, dcd_bssgp_not_yet_dcd },
|
|
{ 0x04, BSSGP_C, 4, dcd_bssgp_bvci_n },
|
|
{ 0x25, BSSGP_M, 4, dcd_bssgp_num_oct_aff },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
LLC_DISCARDED, {
|
|
{ 0x1f, BSSGP_M, 4, dcd_bssgp_tlli },
|
|
{ 0x0f, BSSGP_M, 4, dcd_bssgp_llc_frdsc },
|
|
{ 0x04, BSSGP_M, 4, dcd_bssgp_bvci },
|
|
{ 0x25, BSSGP_M, 4, dcd_bssgp_num_oct_aff },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
SGSN_INVOKE_TRACE, {
|
|
/* { 0x22, BSSGP_M, 4, dcd_bssgp_trace_type },
|
|
{ 0x21, BSSGP_M, 4, dcd_bssgp_trace_ref },
|
|
{ 0x24, BSSGP_O, 4, dcd_bssgp_trig_id },
|
|
{ 0x11, BSSGP_O, 4, dcd_bssgp_mid },
|
|
{ 0x14, BSSGP_O, 4, dcd_bssgp_omc_id },
|
|
{ 0x23, BSSGP_O, 4, dcd_bssgp_trans_id },
|
|
*/
|
|
{ 0x22, BSSGP_M, 4, dcd_bssgp_not_yet_dcd },
|
|
{ 0x21, BSSGP_M, 4, dcd_bssgp_not_yet_dcd },
|
|
{ 0x24, BSSGP_O, 4, dcd_bssgp_not_yet_dcd },
|
|
{ 0x11, BSSGP_O, 4, dcd_bssgp_not_yet_dcd },
|
|
{ 0x14, BSSGP_O, 4, dcd_bssgp_not_yet_dcd },
|
|
{ 0x23, BSSGP_O, 4, dcd_bssgp_not_yet_dcd },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
STATUS, {
|
|
{ 0x07, BSSGP_M, 4, dcd_bssgp_cause },
|
|
{ 0x04, BSSGP_C, 4, dcd_bssgp_bvci },
|
|
/* { 0x15, BSSGP_O, 4, dcd_bssgp_pdu_err },
|
|
*/
|
|
{ 0x15, BSSGP_O, 4, dcd_bssgp_not_yet_dcd },
|
|
{ 0,0,0,NULL }
|
|
}
|
|
},
|
|
{
|
|
0, {
|
|
{ 0,0,0,NULL }
|
|
}
|
|
}
|
|
};
|
|
/*-----------------------------------------------------------------------------------------------------------------*/
|
|
static void mccmnc(guint32 mcmn, char buf[]){
|
|
typedef struct {
|
|
guint32 mnc1 : 4 ;
|
|
guint32 mnc2 : 4 ;
|
|
guint32 mcc3 : 4 ;
|
|
guint32 mnc3 : 4 ;
|
|
guint32 mcc1 : 4 ;
|
|
guint32 mcc2 : 4 ;
|
|
} stru_mncmcc;
|
|
typedef union {
|
|
guint32 i;
|
|
stru_mncmcc s;
|
|
} u_mncmcc;
|
|
u_mncmcc *r_mncmcc;
|
|
guint8 pom =0,i=0 ;
|
|
r_mncmcc = (u_mncmcc *)&mcmn;
|
|
for (i=0;i<8;i++){
|
|
switch (i) {
|
|
case 0 :
|
|
pom = r_mncmcc->s.mcc1;
|
|
break;
|
|
case 1 :
|
|
pom = r_mncmcc->s.mcc2;
|
|
break;
|
|
case 2 :
|
|
pom = r_mncmcc->s.mcc3;
|
|
break;
|
|
case 3 :
|
|
pom = 0x61;/* 0x61 because i need space " " (0x61-1)^0x40*/
|
|
break;
|
|
case 4 :
|
|
pom = r_mncmcc->s.mnc1;
|
|
break;
|
|
case 5 :
|
|
pom = r_mncmcc->s.mnc2;
|
|
break;
|
|
case 6 :
|
|
pom = r_mncmcc->s.mnc3;
|
|
pom = (pom == 0xf)?0x41: pom;/* 0x41 because i need null on the end of string (0x41-1)^0x40*/
|
|
break;
|
|
case 7 :
|
|
pom = 0x41;
|
|
break;
|
|
|
|
}
|
|
pom = (pom > 9)?(pom-1) ^ 0x40: pom ^ 0x30;
|
|
buf[i] = pom;
|
|
}
|
|
}
|
|
static int dcd_bssgp_not_yet_dcd(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, pom=0,k=2;
|
|
guint16 llen=0;
|
|
|
|
pom = tvb_get_guint8(tvb,offset+1);
|
|
if ( pom >= 128 ){
|
|
llen = pom & 0x7f;
|
|
k = 2;
|
|
}
|
|
else{
|
|
llen = tvb_get_ntohs( tvb, offset+1);
|
|
k=3;
|
|
}
|
|
if (dprm_p->tree){
|
|
code = tvb_get_guint8(tvb,offset);
|
|
proto_tree_add_uint_format(dprm_p->tree,hf_bssgp_ietype,tvb,offset,llen+k,code,"IE type: %s (%#.2x) ....Not yet decoded",match_strval(code,bssgp_iei),code);
|
|
}
|
|
return llen+k;
|
|
}
|
|
static int dcd_bssgp_algn(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *algn_tree=NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
if (dprm_p->tree){
|
|
code = tvb_get_guint8(tvb,offset);
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2, "%u Aligment octets", len+2 );
|
|
algn_tree = proto_item_add_subtree(ti, ett_algn_tree);
|
|
proto_tree_add_uint_format(algn_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_text(algn_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
static int dcd_bssgp_bmaxms(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0;
|
|
guint16 bucket=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *bmaxms_tree=NULL;
|
|
|
|
if (dprm_p->tree){
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
code = tvb_get_guint8(tvb,offset);
|
|
bucket = tvb_get_ntohs(tvb,offset+2);
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2, "%s: %u bytes", match_strval(code,bssgp_iei),100*bucket);
|
|
bmaxms_tree = proto_item_add_subtree(ti, ett_bmaxms_tree);
|
|
proto_tree_add_uint_format(bmaxms_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_uint_format(bmaxms_tree, hf_bssgp_bmax_def_ms,tvb,offset+2,len,bucket,"%s in 100 octet increments: %u (%#.2x)",match_strval(code,bssgp_iei),bucket,bucket);
|
|
proto_tree_add_text(bmaxms_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
/*static int dcd_bssgp_bss_aind(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
static int dcd_bssgp_bucklr(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0;
|
|
guint16 bucket=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *bucklr_tree=NULL;
|
|
|
|
bucket = tvb_get_ntohs(tvb,offset+2);
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
code = tvb_get_guint8(tvb,offset);
|
|
|
|
if (check_col((dprm_p->pinfo)->cinfo, COL_INFO)){
|
|
col_append_fstr( (dprm_p->pinfo)->cinfo, COL_INFO, ", %s: %u bits/sec",match_strval(code,bssgp_iei),bucket*100 );
|
|
}
|
|
if (dprm_p->tree){
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2, "Bucket Leak Rate(R): %u bits/sec", 100*bucket);
|
|
bucklr_tree = proto_item_add_subtree(ti, ett_bucklr_tree);
|
|
proto_tree_add_uint_format(bucklr_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_uint_format(bucklr_tree, hf_bssgp_buck_leak_rate,tvb,offset+2,len,bucket,"%s in 100 bits/sec increments: %u (%#.2x)",match_strval(code,bssgp_iei),bucket,bucket);
|
|
proto_tree_add_text(bucklr_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
static int dcd_bssgp_bvci(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0;
|
|
guint16 bucket=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *bvci_tree=NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
code = tvb_get_guint8(tvb,offset);
|
|
bucket = tvb_get_ntohs(tvb,offset+2);
|
|
if (check_col((dprm_p->pinfo)->cinfo, COL_INFO)){
|
|
col_append_fstr( (dprm_p->pinfo)->cinfo, COL_INFO, ", %s: %u",match_strval(code,bssgp_iei),bucket );
|
|
}
|
|
if (dprm_p->tree){
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2, "%s: %u", match_strval(code,bssgp_iei), bucket);
|
|
bvci_tree = proto_item_add_subtree(ti, ett_bvci_tree);
|
|
proto_tree_add_uint_format(bvci_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_uint_format(bvci_tree, hf_bssgp_bvci,tvb,offset+2,len,bucket,"%s: %u (%#.2x)",match_strval(code,bssgp_iei),bucket,bucket);
|
|
proto_tree_add_text(bvci_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
static int dcd_bssgp_bvci_n(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0;
|
|
guint16 bucket=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *bvcin_tree=NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
code = tvb_get_guint8(tvb,offset);
|
|
bucket = tvb_get_ntohs(tvb,offset+2);
|
|
if (check_col((dprm_p->pinfo)->cinfo, COL_INFO)){
|
|
col_append_fstr( (dprm_p->pinfo)->cinfo, COL_INFO, " New %s: %u",match_strval(code,bssgp_iei),bucket );
|
|
}
|
|
if (dprm_p->tree){
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2, "New %s: %u", match_strval(code,bssgp_iei), bucket);
|
|
bvcin_tree = proto_item_add_subtree(ti, ett_bvcin_tree);
|
|
proto_tree_add_uint_format(bvcin_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s(New) %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_uint_format(bvcin_tree, hf_bssgp_bvci_new,tvb,offset+2,len,bucket,"New %s: %u (%#.2x)",match_strval(code,bssgp_iei),bucket,bucket);
|
|
proto_tree_add_text(bvcin_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
static int dcd_bssgp_bvc_bsize(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0;
|
|
guint16 bucket=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *bsize_tree=NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
code = tvb_get_guint8(tvb,offset);
|
|
bucket = tvb_get_ntohs(tvb,offset+2);
|
|
if (check_col((dprm_p->pinfo)->cinfo, COL_INFO)){
|
|
col_append_fstr( (dprm_p->pinfo)->cinfo, COL_INFO, ", %s: %u bytes",match_strval(code,bssgp_iei),bucket*100 );
|
|
}
|
|
if (dprm_p->tree){
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2, "BVC Bucket Size: %u bytes", 100*bucket);
|
|
bsize_tree = proto_item_add_subtree(ti, ett_bsize_tree);
|
|
proto_tree_add_uint_format(bsize_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_uint_format(bsize_tree, hf_bssgp_bvc_buck_size,tvb,offset+2,len,bucket,"%s in 100 octet increments: %u (%#.2x)",match_strval(code,bssgp_iei),bucket,bucket);
|
|
proto_tree_add_text(bsize_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
/*static int dcd_bssgp_bvc_meas(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
return 4;
|
|
};
|
|
*/
|
|
static int dcd_bssgp_cause(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0,cause=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *cause_tree=NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
code = tvb_get_guint8(tvb,offset);
|
|
cause = tvb_get_guint8(tvb,offset+2);
|
|
if (check_col((dprm_p->pinfo)->cinfo, COL_INFO)){
|
|
col_append_fstr( (dprm_p->pinfo)->cinfo, COL_INFO, ", %s: %s",match_strval(code,bssgp_iei),match_strval(cause,bssgp_cause));
|
|
}
|
|
if (dprm_p->tree){
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2, "%s: %s", match_strval(code,bssgp_iei),match_strval(cause,bssgp_cause));
|
|
cause_tree = proto_item_add_subtree(ti, ett_cause_tree);
|
|
proto_tree_add_uint_format(cause_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_uint_format(cause_tree, hf_bssgp_cause,tvb,offset+2,len,cause,"%s: %s (%#.2x)",match_strval(code,bssgp_iei),match_strval(cause,bssgp_cause),cause);
|
|
proto_tree_add_text(cause_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
|
|
static int dcd_bssgp_cellid(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
char mccmnc_str[8];
|
|
guint32 mnccc;
|
|
guint16 lac,cid;
|
|
guint8 len=8, code=0,rac;
|
|
proto_item *ti = NULL;
|
|
proto_tree *celid_tree = NULL;
|
|
|
|
if (dprm_p->tree){
|
|
code = tvb_get_guint8(tvb,offset);
|
|
mnccc = tvb_get_ntoh24(tvb,offset+2);
|
|
lac = tvb_get_ntohs(tvb,offset+5);
|
|
rac = tvb_get_guint8(tvb,offset+7);
|
|
cid = tvb_get_ntohs(tvb,offset+8);
|
|
mccmnc(mnccc, mccmnc_str);
|
|
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2, "Cell Identifier: %s %u %u %u",mccmnc_str,lac,rac,cid);
|
|
celid_tree = proto_item_add_subtree(ti, ett_celid_tree);
|
|
proto_tree_add_uint_format(celid_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_string_format(celid_tree,hf_bssgp_ra_mccmnc,tvb,offset+2,3,mccmnc_str,"MCC MNC: %s",mccmnc_str);
|
|
proto_tree_add_uint_format(celid_tree,hf_bssgp_ra_lac,tvb,offset+5,2,lac,"LAC: %u",lac);
|
|
proto_tree_add_uint_format(celid_tree,hf_bssgp_ra_rac,tvb,offset+7,1,rac,"RAC: %u",rac);
|
|
proto_tree_add_uint_format(celid_tree,hf_bssgp_cid,tvb,offset+8,2,cid,"Cell Id: %u",cid);
|
|
proto_tree_add_text(celid_tree,tvb,offset+1,1,"Length:%u",len);
|
|
|
|
}
|
|
|
|
return len+2;
|
|
}
|
|
|
|
/*static int dcd_bssgp_chan_need(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
static int dcd_bssgp_drx(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *drx_tree=NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
if (dprm_p->tree){
|
|
code = tvb_get_guint8(tvb,offset);
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, 4,"DRX Parameters");
|
|
drx_tree = proto_item_add_subtree(ti, ett_drx_tree);
|
|
proto_tree_add_uint_format(drx_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_text(drx_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
|
|
}
|
|
|
|
/*static int dcd_bssgp_emlpp_prio(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
|
|
/*static int dcd_bssgp_flush_act(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
|
|
static int dcd_bssgp_imsi(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 nextb=0, first_b=0, toi=0, i, k;
|
|
guint8 num=0,code=0,len=0;
|
|
char buf[17],imsi_mccn[6],imsi_val[11], toibuf[9];
|
|
proto_item *ti=NULL, *ti2=NULL;
|
|
proto_tree *imsi_tree = NULL, *imsi_stru_tree = NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
first_b = tvb_get_guint8(tvb,offset+2);
|
|
if (dprm_p->tree){
|
|
code = tvb_get_guint8(tvb,offset);
|
|
decode_bitfield_value(toibuf,toi,LOW3B,8);
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset,len+2 ,"IMSI");
|
|
imsi_tree = proto_item_add_subtree(ti, ett_bssgp_imsi);
|
|
proto_tree_add_uint_format(imsi_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_text(imsi_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
toi = first_b & LOW3B;
|
|
switch (toi) {
|
|
|
|
case TOI_IMSI:
|
|
case TOI_IMEI:
|
|
case TOI_IMEISV:
|
|
num = first_b >> 4;
|
|
buf[0] = num + '0';
|
|
for (i=1,k=1;i<len;i++){
|
|
nextb = tvb_get_guint8(tvb, offset+2+i);
|
|
num = nextb & 0x0f;
|
|
buf[k] = num + '0';
|
|
k++;
|
|
if (i < len - 1 || (first_b & ODD_EVEN_INDIC)) {
|
|
/*
|
|
* Either this isn't the last octet
|
|
* of the number, or it is, but there's
|
|
* an odd number of digits, so the last
|
|
* nibble is part of the number.
|
|
*/
|
|
num = nextb >> 4;
|
|
buf[k] = num + '0';
|
|
k++;
|
|
}
|
|
buf[k] = '\0';
|
|
switch (i*2){
|
|
case 4:
|
|
memcpy(&imsi_mccn,&buf,6);
|
|
break;
|
|
case 14:
|
|
memcpy(&imsi_val, &buf[5],11);
|
|
break;
|
|
}
|
|
|
|
}
|
|
if (check_col((dprm_p->pinfo)->cinfo, COL_INFO)){
|
|
col_append_fstr( (dprm_p->pinfo)->cinfo, COL_INFO,
|
|
", %s: %s %s",
|
|
val_to_str(toi,type_of_identity,"Unknown TOI (0x%x)"),
|
|
imsi_mccn, imsi_val );
|
|
}
|
|
|
|
if (dprm_p->tree){
|
|
proto_item_append_text(ti, ": %s", buf);
|
|
ti2 = proto_tree_add_text(imsi_tree,tvb,offset+2,len,"Mobile identity: %s",buf);
|
|
imsi_stru_tree = proto_item_add_subtree( ti2, ett_bssgp_imsi_stru_tree);
|
|
proto_tree_add_uint(imsi_stru_tree,hf_bssgp_imsi_toi,tvb,offset+2,1,first_b);
|
|
proto_tree_add_boolean(imsi_stru_tree,hf_bssgp_imsi_even_odd_indic,tvb,offset+2,1,first_b);
|
|
proto_tree_add_string(imsi_stru_tree,hf_bssgp_imsi,tvb,offset+2,len,buf);
|
|
proto_tree_add_string_hidden(imsi_stru_tree,hf_bssgp_imsi_lsix,tvb,offset+2,len,imsi_val);
|
|
}
|
|
break;
|
|
}
|
|
return len+2;
|
|
}
|
|
|
|
static int dcd_bssgp_llc_pdu(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, pom=0,k=0;
|
|
guint16 llen=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *b_llc_tree=NULL;
|
|
|
|
pom = tvb_get_guint8(tvb,offset+1);
|
|
if ( pom >= 128 ){
|
|
llen = pom & 0x7f;
|
|
k = 2;
|
|
}
|
|
else{
|
|
llen = tvb_get_ntohs( tvb, offset+1);
|
|
k=3;
|
|
}
|
|
|
|
if (check_col((dprm_p->pinfo)->cinfo, COL_INFO)){
|
|
col_append_fstr( (dprm_p->pinfo)->cinfo, COL_INFO, ", LLC PDU length %u bytes", llen );
|
|
}
|
|
|
|
if (dprm_p->tree){
|
|
code = tvb_get_guint8(tvb,offset);
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset,llen+2 ,"LLC PDU %u bytes", llen);
|
|
b_llc_tree = proto_item_add_subtree(ti, ett_b_llc_tree);
|
|
proto_tree_add_uint_format(b_llc_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_text(b_llc_tree,tvb,offset+1,k-1,"Length:%u",llen);
|
|
}
|
|
|
|
dprm_p->k=offset+k;
|
|
return llen+k;
|
|
}
|
|
|
|
static int dcd_bssgp_llc_frdsc(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0,frdsc=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *frdsc_tree=NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
frdsc = tvb_get_guint8(tvb,offset+2);
|
|
code = tvb_get_guint8(tvb,offset);
|
|
if (check_col((dprm_p->pinfo)->cinfo, COL_INFO)){
|
|
col_append_fstr( (dprm_p->pinfo)->cinfo, COL_INFO, ", %s: %u",match_strval(code,bssgp_iei), frdsc);
|
|
}
|
|
if (dprm_p->tree){
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2, "%s: %u", match_strval(code,bssgp_iei), frdsc);
|
|
frdsc_tree = proto_item_add_subtree(ti, ett_frdsc_tree);
|
|
proto_tree_add_uint_format(frdsc_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_uint_format(frdsc_tree, hf_bssgp_frdsc,tvb,offset+2,len,frdsc,"%s: %u",match_strval(code,bssgp_iei),frdsc);
|
|
proto_tree_add_text(frdsc_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
|
|
/*static int dcd_bssgp_la(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
|
|
/*static int dcd_bssgp_mid(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
|
|
/*static int dcd_bssgp_ms_buck(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
|
|
static int dcd_bssgp_radio_acc(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0,len=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *racc_tree = NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
if (dprm_p->tree){
|
|
code = tvb_get_guint8(tvb,offset);
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset,len+2 ,"MS Radio Access Capability: ");
|
|
racc_tree = proto_item_add_subtree(ti, ett_bssgp_racc);
|
|
proto_tree_add_uint_format(racc_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_text(racc_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
|
|
/*static int dcd_bssgp_omc_id(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
|
|
/*static int dcd_bssgp_pdu_err(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
|
|
static int dcd_bssgp_pdu_life(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
gfloat ms_lifetime;
|
|
guint16 lifetime;
|
|
guint8 code=0, len=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *lft_tree=NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
if (dprm_p->tree){
|
|
code = tvb_get_guint8(tvb,offset);
|
|
lifetime = tvb_get_ntohs(tvb,offset+2);
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, 4,"PDU Lifetime (s): ");
|
|
lft_tree = proto_item_add_subtree(ti, ett_bssgp_lft);
|
|
proto_tree_add_uint_format(lft_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_text(lft_tree,tvb,offset+1,1,"Length:%u",len);
|
|
if (lifetime == 0xFFFF){
|
|
proto_item_append_text(ti,"infinite delay");
|
|
proto_tree_add_uint_format(lft_tree,hf_bssgp_pdu_lifetime,tvb,offset+2,2,lifetime,"PDU Life time: infinite delay (%#.4x centi seconds)", lifetime);
|
|
}
|
|
else{
|
|
ms_lifetime = (gfloat) (lifetime/100);
|
|
proto_item_append_text(ti,"%f",ms_lifetime);
|
|
proto_tree_add_uint_format(lft_tree,hf_bssgp_pdu_lifetime,tvb,offset+2,2,lifetime,"PDU Life time: %fs (%#.4x centi seconds)", ms_lifetime, lifetime);
|
|
}
|
|
}
|
|
return 4;
|
|
}
|
|
|
|
static int dcd_bssgp_prio(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *prio_tree=NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
if (dprm_p->tree){
|
|
code = tvb_get_guint8(tvb,offset);
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, 4,"Priority");
|
|
prio_tree = proto_item_add_subtree(ti, ett_prio_tree);
|
|
proto_tree_add_uint_format(prio_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_text(prio_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
|
|
static int dcd_bssgp_qos(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint16 blr=0;
|
|
guint32 bps=0;
|
|
char buf[16];
|
|
gint8 disp=0, opet=0, code=0,len=0,start=0,pre=0;
|
|
proto_item *ti=NULL, *ti2=NULL;
|
|
proto_tree *qos_tree=NULL,*o5_tree;
|
|
switch (dprm_p->type){
|
|
case 3:
|
|
break;
|
|
case 4:
|
|
code = tvb_get_guint8(tvb,offset);
|
|
disp++;
|
|
len = tvb_get_guint8(tvb,offset+disp);
|
|
disp++;
|
|
len = len & 0x7f;
|
|
break;
|
|
}
|
|
start=disp;
|
|
blr = tvb_get_ntohs(tvb, offset+disp);
|
|
disp = disp+2;
|
|
opet = tvb_get_guint8(tvb,offset+disp);
|
|
disp++;
|
|
if (dprm_p->tree){
|
|
bps = 100*blr/8;
|
|
decode_bitfield_value(buf,opet,LOW3B,8);
|
|
pre = opet & LOW3B;
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset,len+disp,"QoS Profile IE");
|
|
qos_tree = proto_item_add_subtree(ti,ett_bssgp_qos);
|
|
switch (dprm_p->type){
|
|
case 4:
|
|
proto_tree_add_uint_format(qos_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_text(qos_tree,tvb,offset+1,1,"Length:%u",len);
|
|
case 3:
|
|
if (blr){
|
|
proto_tree_add_uint_format(qos_tree,hf_bssgp_pbr,tvb,offset+start,2,blr,"Peak bit rate: %u bytes/s, (%#.4x)in 100bits/sec increments",bps,blr);
|
|
}
|
|
else{
|
|
proto_tree_add_uint_format(qos_tree,hf_bssgp_pbr,tvb,offset+start,2,blr,"Peak bit rate: best effort (%#.4x)in 100bits/sec increments",blr);
|
|
}
|
|
ti2 = proto_tree_add_item(qos_tree,hf_bssgp_qos,tvb,offset+(disp-1),1,FALSE);
|
|
o5_tree = proto_item_add_subtree(ti2, ett_bssgp_o5);
|
|
proto_tree_add_boolean(o5_tree,hf_bssgp_qos_cr,tvb,offset+(disp-1),1,opet);
|
|
proto_tree_add_boolean(o5_tree,hf_bssgp_qos_t,tvb,offset+(disp-1),1,opet);
|
|
proto_tree_add_boolean(o5_tree,hf_bssgp_qos_a,tvb,offset+(disp-1),1,opet);
|
|
if(tvb_get_guint8(tvb,0)){
|
|
proto_tree_add_uint_format(o5_tree,hf_bssgp_qos_prec,tvb,offset+(disp-1),1,pre,"%s %s", buf,match_strval(pre,prec));
|
|
|
|
}
|
|
else{
|
|
proto_tree_add_uint_format(o5_tree,hf_bssgp_qos_prec,tvb,offset+(disp-1),1,pre,"%s %s", buf,match_strval(pre,prec_dl));
|
|
}
|
|
}
|
|
|
|
}
|
|
return disp;
|
|
}
|
|
|
|
static int dcd_bssgp_radio_caus(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0,racaus=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *racaus_tree=NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
racaus = tvb_get_guint8(tvb,offset+2);
|
|
code = tvb_get_guint8(tvb,offset);
|
|
if (check_col((dprm_p->pinfo)->cinfo, COL_INFO)){
|
|
col_append_fstr( (dprm_p->pinfo)->cinfo, COL_INFO, ", %s: %s",match_strval(code,bssgp_iei), val_to_str(racaus,radio_cause,"%u reserved value"));
|
|
}
|
|
if (dprm_p->tree){
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2, "%s: %s", match_strval(code,bssgp_iei), val_to_str(racaus,radio_cause,"%u reserved value, if received , it shall be handled as ""radio contact lost with MS"""));
|
|
racaus_tree = proto_item_add_subtree(ti, ett_racaus_tree);
|
|
proto_tree_add_uint_format(racaus_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_uint_format(racaus_tree, hf_bssgp_radio_cause,tvb,offset+2,len,racaus,"%s: %#.2x",match_strval(code,bssgp_iei),racaus);
|
|
proto_tree_add_text(racaus_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
|
|
/*static int dcd_bssgp_racap_upd(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
|
|
static int dcd_bssgp_ra(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint16 lac;
|
|
guint32 mnccc;
|
|
guint8 rac, len = 0,code=0 ;
|
|
char st_mccn[8];
|
|
proto_item *ti=NULL;
|
|
proto_tree *ra_tree = NULL;
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
if (dprm_p->tree){
|
|
code = tvb_get_guint8(tvb,offset);
|
|
mnccc = tvb_get_ntoh24(tvb,offset+2);
|
|
lac = tvb_get_ntohs(tvb,offset+5);
|
|
rac = tvb_get_guint8(tvb,offset+7);
|
|
mccmnc(mnccc, st_mccn);
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset,len+2, "Routing area: %s %u %u",st_mccn,lac,rac);
|
|
ra_tree = proto_item_add_subtree(ti, ett_ra_tree);
|
|
proto_tree_add_uint_format(ra_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_string_format(ra_tree,hf_bssgp_ra_mccmnc,tvb,offset+2,3,st_mccn,"MCC MNC: %s",st_mccn);
|
|
proto_tree_add_uint_format(ra_tree,hf_bssgp_ra_lac,tvb,offset+5,2,lac,"LAC: %u",lac);
|
|
proto_tree_add_uint_format(ra_tree,hf_bssgp_ra_rac,tvb,offset+7,1,rac,"RAC: %u",rac);
|
|
proto_tree_add_text(ra_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
|
|
static int dcd_bssgp_r_def_ms(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0;
|
|
guint16 bucket=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *rdefms_tree=NULL;
|
|
|
|
if (dprm_p->tree){
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
code = tvb_get_guint8(tvb,offset);
|
|
bucket = tvb_get_ntohs(tvb,offset+2);
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2, "%s: %u bits/sec", match_strval(code,bssgp_iei),100*bucket);
|
|
rdefms_tree = proto_item_add_subtree(ti, ett_rdefms_tree);
|
|
proto_tree_add_uint_format(rdefms_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_uint_format(rdefms_tree, hf_bssgp_r_defau_ms,tvb,offset+2,len,bucket,"%s in 100 bits/sec increments: %u (%#.2x)",match_strval(code,bssgp_iei),bucket,bucket);
|
|
proto_tree_add_text(rdefms_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
|
|
/*static int dcd_bssgp_sus_ref_num(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
|
|
static int dcd_bssgp_tag(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0,tag=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *tag_tree=NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
if (dprm_p->tree){
|
|
code = tvb_get_guint8(tvb,offset);
|
|
tag = tvb_get_guint8(tvb,offset+2);
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2,"Tag: %u", tag);
|
|
tag_tree = proto_item_add_subtree(ti, ett_tag_tree);
|
|
proto_tree_add_uint_format(tag_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_text(tag_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
|
|
static int dcd_bssgp_tlli(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint32 tlli;
|
|
guint8 len=0, code=0, disp=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *tlli_tree=NULL;
|
|
switch (dprm_p->type){
|
|
case 3:
|
|
disp = 0;
|
|
break;
|
|
case 4:
|
|
code = tvb_get_guint8(tvb, offset);
|
|
disp++;
|
|
len = tvb_get_guint8(tvb,offset+disp);
|
|
len = len & 0x7f;
|
|
disp++;
|
|
break;
|
|
}
|
|
tlli = tvb_get_ntohl(tvb, offset+disp);
|
|
if (check_col((dprm_p->pinfo)->cinfo, COL_INFO)){
|
|
col_append_fstr( (dprm_p->pinfo)->cinfo, COL_INFO,", TLLI: %X", tlli);
|
|
}
|
|
if (dprm_p->tree){
|
|
switch (dprm_p->type){
|
|
case 3:
|
|
proto_tree_add_uint_format(dprm_p->tree,hf_bssgp_tlli,tvb,offset,4,tlli,"TLLI: %#.4x", tlli );
|
|
break;
|
|
case 4:
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset,len+disp,"TLLI: %#.4x",tlli);
|
|
tlli_tree =proto_item_add_subtree(ti,ett_bssgp_tlli);
|
|
proto_tree_add_uint_format(tlli_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
|
|
proto_tree_add_text(tlli_tree,tvb,offset+1,1,"Length:%u",len);
|
|
proto_tree_add_uint_format(tlli_tree,hf_bssgp_tlli,tvb,offset+disp,len,tlli,"TLLI: %#.4x", tlli );
|
|
|
|
}
|
|
}
|
|
return 4 + disp;
|
|
}
|
|
/*static int dcd_bssgp_tlli_o(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
return 6;
|
|
};
|
|
*/
|
|
|
|
/*static int dcd_bssgp_tmsi(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
/*static int dcd_bssgp_trace_ref(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
/*static int dcd_bssgp_trace_type(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
/*static int dcd_bssgp_trans_id(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
/*static int dcd_bssgp_trig_id(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
};
|
|
*/
|
|
static int dcd_bssgp_num_oct_aff(tvbuff_t *tvb, int offset, dec_fu_param_stru_t *dprm_p){
|
|
guint8 code=0, len=0;
|
|
guint32 bucket=0;
|
|
proto_item *ti=NULL;
|
|
proto_tree *noaff_tree=NULL;
|
|
|
|
len = tvb_get_guint8(tvb,offset+1) & 0x7f;
|
|
if (dprm_p->tree){
|
|
code = tvb_get_guint8(tvb,offset);
|
|
bucket = tvb_get_ntoh24(tvb,offset+2);
|
|
ti = proto_tree_add_text(dprm_p->tree,tvb,offset, len+2, "%s: %u", match_strval(code,bssgp_iei), bucket);
|
|
noaff_tree = proto_item_add_subtree(ti, ett_noaff_tree);
|
|
proto_tree_add_uint_format(noaff_tree,hf_bssgp_ietype,tvb,offset,1,code,"IE type: %s %#.2x",match_strval(code,bssgp_iei),code);
|
|
proto_tree_add_uint_format(noaff_tree, hf_bssgp_noaff,tvb,offset+2,len,bucket,"%s: %u (%#.2x)",match_strval(code,bssgp_iei),bucket,bucket);
|
|
proto_tree_add_text(noaff_tree,tvb,offset+1,1,"Length:%u",len);
|
|
}
|
|
return len+2;
|
|
}
|
|
|
|
|
|
/* Code to actually dissect the packets */
|
|
static void
|
|
dissect_bssgp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|
{
|
|
static dec_fu_param_stru_t decp , *decodeparam=&decp;
|
|
guint8 pdutype, i, j , iele , stay;
|
|
guint16 offset=1;
|
|
tvbuff_t *next_tvb;
|
|
|
|
/* Set up structures needed to add the protocol subtree and manage it */
|
|
proto_item *ti=NULL;
|
|
proto_tree *bssgp_tree=NULL;
|
|
|
|
pdutype=tvb_get_guint8(tvb,0);
|
|
/* Make entries in Protocol column and Info column on summary display */
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL))
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "BSSGP");
|
|
|
|
/* This field shows up as the "Info" column in the display; you should make
|
|
it, if possible, summarize what's in the packet, so that a user looking
|
|
at the list of packets can tell what type of packet it is. See section 1.5
|
|
for more information.
|
|
|
|
If you are setting it to a constant string, use "col_set_str()", as
|
|
it's more efficient than the other "col_set_XXX()" calls.
|
|
|
|
If you're setting it to a string you've constructed, or will be
|
|
appending to the column later, use "col_add_str()".
|
|
|
|
"col_add_fstr()" can be used instead of "col_add_str()"; it takes
|
|
"printf()"-like arguments. Don't use "col_add_fstr()" with a format
|
|
string of "%s" - just use "col_add_str()" or "col_set_str()", as it's
|
|
more efficient than "col_add_fstr()".
|
|
|
|
If you will be fetching any data from the packet before filling in
|
|
the Info column, clear that column first, in case the calls to fetch
|
|
data from the packet throw an exception because they're fetching data
|
|
past the end of the packet, so that the Info column doesn't have data
|
|
left over from the previous dissector; do
|
|
*/
|
|
if (check_col(pinfo->cinfo, COL_INFO)) {
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
col_add_str(pinfo->cinfo, COL_INFO,match_strval(pdutype,tab_bssgp_pdu_type));
|
|
}
|
|
/* In the interest of speed, if "tree" is NULL, don't do any work not
|
|
necessary to generate protocol tree items. */
|
|
/* if (tree) { */
|
|
|
|
/* NOTE: The offset and length values in the call to
|
|
"proto_tree_add_item()" define what data bytes to highlight in the hex
|
|
display window when the line in the protocol tree display
|
|
corresponding to that item is selected.
|
|
|
|
tvb_length(tvb) is a handy way to highlight all data from the offset to
|
|
the end of the packet. */
|
|
|
|
/* create display subtree for the protocol */
|
|
/* ti = proto_tree_add_item(tree, proto_bssgp, tvb, 0, tvb_length(tvb), FALSE );
|
|
|
|
bssgp_tree = proto_item_add_subtree(ti, ett_bssgp);
|
|
*/
|
|
decodeparam->pinfo=pinfo;
|
|
decodeparam->tree=tree;
|
|
i = 0;
|
|
stay = 1;
|
|
while (bssgp_pdu[i].infe[0].presence && stay){
|
|
if (bssgp_pdu[i].pdu == pdutype) {
|
|
j = 0;
|
|
stay = 0;
|
|
if (tree){
|
|
ti = proto_tree_add_protocol_format(tree, proto_bssgp, tvb, 0, tvb_length(tvb),"BSS GPRS protocol PDU type: %s (%#.2x)", match_strval(pdutype,tab_bssgp_pdu_type), pdutype);
|
|
bssgp_tree = proto_item_add_subtree(ti, ett_bssgp);
|
|
proto_tree_add_uint_format(bssgp_tree, hf_bssgp_pdu_type, tvb, 0, offset, pdutype, "PDU type: %s (%#.2x)",match_strval(pdutype,tab_bssgp_pdu_type), pdutype );
|
|
decodeparam->tree=bssgp_tree;
|
|
}
|
|
while (bssgp_pdu[i].infe[j].presence){
|
|
switch(bssgp_pdu[i].infe[j].type){
|
|
case 3:
|
|
decodeparam->type=3;
|
|
offset=offset+( *bssgp_pdu[i].infe[j].decode)(tvb, offset, decodeparam );
|
|
j++;
|
|
break;
|
|
case 4:
|
|
decodeparam->type=4;
|
|
if (offset >= tvb_length(tvb)) {
|
|
j++;
|
|
break;
|
|
}
|
|
iele = tvb_get_guint8( tvb, offset);
|
|
while ((bssgp_pdu[i].infe[j].code != iele) && bssgp_pdu[i].infe[j].presence ) {
|
|
if (bssgp_pdu[i].infe[j].presence > 1) j++;
|
|
else break;
|
|
}
|
|
if (bssgp_pdu[i].infe[j].presence){
|
|
offset=offset+( *bssgp_pdu[i].infe[j].decode)(tvb, offset, decodeparam );
|
|
if (iele == 0x0e ){
|
|
next_tvb = tvb_new_subset(tvb, decodeparam->k, -1, -1);
|
|
call_dissector(llcgprs_handle, next_tvb, pinfo, tree);
|
|
/* call_dissector(data_handle, next_tvb, pinfo, tree);
|
|
*/
|
|
}
|
|
j++;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
i++;
|
|
};
|
|
|
|
/* add an item to the subtree, see section 1.6 for more information */
|
|
/*
|
|
proto_tree_add_uint(tree, hf_bssgp_FIELDABBREV, tvb, offset, len, value);
|
|
*/
|
|
/* proto_tree_add_uint_format(bssgp_tree, hf_bssgp_pdu_type, tvb, 0, 1, pdutype, "PDU type: %s (%#.2x)",match_strval(pdutype,tab_bssgp_pdu_type), pdutype );
|
|
*/
|
|
|
|
/* Continue adding tree items to process the packet here */
|
|
|
|
|
|
/* }*/
|
|
|
|
/* If this protocol has a sub-dissector call it here, see section 1.8 */
|
|
}
|
|
|
|
|
|
/* Register the protocol with Ethereal */
|
|
|
|
/* this format is require because a script is used to build the C function
|
|
that calls all the protocol registration.
|
|
*/
|
|
|
|
void
|
|
proto_register_bssgp(void)
|
|
{
|
|
static hf_register_info hf[] = {
|
|
{ &hf_bssgp_pdu_type,
|
|
{ "PDU", "bssgp.pdu",
|
|
FT_UINT8, BASE_HEX, VALS(tab_bssgp_pdu_type), 0x0,
|
|
"BSSGP PDU", HFILL }},
|
|
{&hf_bssgp_tlli,
|
|
{ "TLLI","bssgp.tlli",FT_UINT32, BASE_HEX, NULL,0x0,"Current TLLI",HFILL}},
|
|
{&hf_bssgp_ietype,
|
|
{"IE Type", "bssgp.ietype", FT_UINT8, BASE_HEX, VALS(bssgp_iei),0x0,"Information element", HFILL }},
|
|
{&hf_bssgp_pbr,
|
|
{"QoS_Profile","bssgp.pbr",FT_UINT16, BASE_HEX, NULL, 0x0, "Peak bit rate",HFILL }},
|
|
{&hf_bssgp_qos,
|
|
{"Last byte QoS Profile","bssgp.qos",FT_UINT8, BASE_HEX, NULL, 0x0,"5th byte of QoS profile(contains Precedence..)",HFILL}},
|
|
{&hf_bssgp_qos_cr,
|
|
{"C/R bit","bssgp.qos.cr",FT_BOOLEAN,8, TFS(&cr_string),QOSO5CR,"The SDU contains LLC ACK/SACK command/responce frame type",HFILL }},
|
|
{&hf_bssgp_qos_t,
|
|
{"T bit", "bssgp.qos.t", FT_BOOLEAN, 8, TFS( &t_string) , QOSO5T, "The SDU contains signaling/data" , HFILL}},
|
|
{&hf_bssgp_qos_a,
|
|
{"A bit" , "bssgp.qos.a" , FT_BOOLEAN,8, TFS( &a_string), QOSO5A, "Radio interface uses ARQ/UNITDATA functionality",HFILL}},
|
|
{&hf_bssgp_qos_prec,
|
|
{"Precedence", "bssgp.qos.prec", FT_UINT8,BASE_HEX ,VALS(prec_both), 0x0,"Precedence coding", HFILL }},
|
|
{&hf_bssgp_pdu_lifetime,
|
|
{"PDU Lifetime","bssgp.lft", FT_UINT16, BASE_HEX, NULL, 0x0, "PDU Lifetime for PDU inside the BSS",HFILL}},
|
|
{&hf_bssgp_imsi,
|
|
{"IMSI","bssgp.imsi", FT_STRING, BASE_DEC, NULL, 0x0, "International Mobile Subscriber Identity",HFILL}},
|
|
{&hf_bssgp_imsi_toi,
|
|
{ "Type of Mobile identity", "bssgp.mobid", FT_UINT8, BASE_HEX, VALS(type_of_identity), LOW3B, "Type of mobile identity",HFILL }},
|
|
{&hf_bssgp_imsi_even_odd_indic,
|
|
{ "Odd/even indication", "bssgp.oei", FT_BOOLEAN, 8, TFS(&imsi_odd_even), ODD_EVEN_INDIC, "Odd/even indication",HFILL }},
|
|
{&hf_bssgp_imsi_lsix,
|
|
{"IMSI last ten numbers","bssgp.imsi.last10num",FT_STRING, BASE_NONE, NULL, 0x0, "Last ten numbers of IMSI",HFILL}},
|
|
{&hf_bssgp_bvc_buck_size,
|
|
{"Bmax(in 100 oct incr)","bssgp.bmax", FT_UINT16, BASE_HEX, NULL, 0x0, "BVC Bucket Size in 100 octet increments",HFILL}},
|
|
{&hf_bssgp_buck_leak_rate,
|
|
{"Bucket Leak Rate","bssgp.R", FT_UINT16, BASE_HEX, NULL, 0x0, "Bucket Leak Rate in 100 bits/sec increments",HFILL}},
|
|
{&hf_bssgp_bmax_def_ms,
|
|
{"Bmax default MS","bssgp.bmaxms", FT_UINT16, BASE_HEX, NULL, 0x0, "Default bucket size in 100 octetsincrement for an MS",HFILL}},
|
|
{&hf_bssgp_r_defau_ms,
|
|
{"R default MS","bssgp.Rms", FT_UINT16, BASE_HEX,NULL, 0x0, "Dfeault bucket leak rate to be applied to a flow control bucket for an MS", HFILL}},
|
|
{&hf_bssgp_bvci,
|
|
{"BVCI","bssgp.bvci",FT_UINT16, BASE_HEX, NULL, 0x0, "BSSGP Virtual Connection Identifier", HFILL}},
|
|
{&hf_bssgp_cause,
|
|
{"Cause","bssgp.cause", FT_UINT8, BASE_HEX, NULL,0x0, " Cause information element indicates the reason for an exception condition",HFILL }},
|
|
{&hf_bssgp_bvci_new,{"BVCI(New)","bssgp.bvci.new",FT_UINT16, BASE_HEX, NULL, 0x0, "BSSGP Virtual Connection Identifier", HFILL}},
|
|
{&hf_bssgp_frdsc,
|
|
{"LLC frames discarded","bssgp.llcdisc.frames", FT_UINT8, BASE_HEX, NULL, 0x0,"LLC frames that have been discarded inside BSS", HFILL}},
|
|
{&hf_bssgp_noaff,
|
|
{"Number of octets affected","bssgp.noaff", FT_UINT24, BASE_HEX,NULL,0x0,"It indicates,for MS,the number of octets transferred or deleted by BSS",HFILL}},
|
|
{&hf_bssgp_radio_cause,
|
|
{"Radio Cause","bssgp.racase", FT_UINT8, BASE_HEX, NULL, 0x0, "Reason for an exception condition on the radio interface",HFILL}},
|
|
{&hf_bssgp_ra_mccmnc,
|
|
{"MCC and MNC","bssgp.ra.mccmnc", FT_STRING, BASE_DEC, NULL, 0x0, "Mobile country code and Mobile network code", HFILL}},
|
|
{&hf_bssgp_ra_lac,
|
|
{"LAC","bssgp.ra.lac",FT_UINT16, BASE_HEX, NULL, 0x0, "Location area code",HFILL }},
|
|
{&hf_bssgp_ra_rac,
|
|
{"RAC","bssgp.ra.rac",FT_UINT8, BASE_HEX, NULL, 0x0, "Routing area code", HFILL }},
|
|
{&hf_bssgp_cid,
|
|
{"Cell id","bssgp.cid",FT_UINT16, BASE_HEX, NULL, 0x0, "Cell identity", HFILL }},
|
|
};
|
|
|
|
/* Setup protocol subtree array */
|
|
static gint *ett[] = {
|
|
&ett_bssgp,
|
|
&ett_bssgp_tlli,
|
|
&ett_bssgp_qos,
|
|
&ett_bssgp_o5,
|
|
&ett_bssgp_lft,
|
|
&ett_bssgp_racc,
|
|
&ett_prio_tree,
|
|
&ett_drx_tree,
|
|
&ett_bssgp_imsi,
|
|
&ett_bssgp_imsi_stru_tree,
|
|
&ett_algn_tree,
|
|
&ett_b_llc_tree,
|
|
&ett_celid_tree,
|
|
&ett_tag_tree,
|
|
&ett_bsize_tree,
|
|
&ett_bucklr_tree,
|
|
&ett_bmaxms_tree,
|
|
&ett_rdefms_tree,
|
|
&ett_bvci_tree,
|
|
&ett_bvcin_tree,
|
|
&ett_cause_tree,
|
|
&ett_frdsc_tree,
|
|
&ett_noaff_tree,
|
|
&ett_racaus_tree,
|
|
&ett_ra_tree
|
|
};
|
|
|
|
/* Register the protocol name and description */
|
|
proto_bssgp = proto_register_protocol("BSS GPRS Protocol",
|
|
"BSSGP", "bssgp");
|
|
|
|
/* Required function calls to register the header fields and subtrees used */
|
|
proto_register_field_array(proto_bssgp, hf, array_length(hf));
|
|
proto_register_subtree_array(ett, array_length(ett));
|
|
register_dissector("bssgp", dissect_bssgp, proto_bssgp);
|
|
}
|
|
|
|
|
|
/* If this dissector uses sub-dissector registration add a registration routine.
|
|
This format is required because a script is used to find these routines and
|
|
create the code that calls these routines.
|
|
*/
|
|
void
|
|
proto_reg_handoff_bssgp(void)
|
|
{
|
|
/* dissector_handle_t bssgp_handle;
|
|
|
|
bssgp_handle = create_dissector_handle(dissect_bssgp,
|
|
proto_bssgp);
|
|
*/
|
|
/* dissector_add("fr.nspduname", NS_UNITDATA, bssgp_handle);*/
|
|
/* dissector_add("fr.nspduname", 0x0, bssgp_handle);
|
|
*/
|
|
/* dissector_add("fr.ietf", 0x0, bssgp_handle);
|
|
*/
|
|
/* data_handle = find_dissector("data");
|
|
*/
|
|
llcgprs_handle = find_dissector ("llcgprs");
|
|
}
|