2 * Routines for Network Service Over IP dissection
3 * Copyright 2000, Susanne Edlund <susanne.edlund@ericsson.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 /* 3GPP TS 48.016 V 5.3.0 (2004-07) Release 6 + CR013 */
16 #include <epan/packet.h>
18 #include <epan/prefs.h>
19 #include <epan/to_str.h>
20 #include <wiretap/wtap.h>
22 void proto_register_nsip(void);
23 void proto_reg_handoff_nsip(void);
26 #define NSIP_SEP ", " /* Separator string */
28 #define DEFAULT_NSIP_PORT_RANGE "2157,19999" /* Not IANA registered */
30 /* Initialize the protocol and registered fields */
31 static int proto_nsip = -1;
33 static int hf_nsip_cause = -1;
34 static int hf_nsip_ns_vci = -1;
35 static int hf_nsip_pdu_type = -1;
36 static int hf_nsip_bvci = -1;
37 static int hf_nsip_nsei = -1;
38 /* static int hf_nsip_ip4_elements = -1; */
39 /* static int hf_nsip_ip6_elements = -1; */
40 static int hf_nsip_max_num_ns_vc = -1;
41 static int hf_nsip_num_ip4_endpoints = -1;
42 static int hf_nsip_num_ip6_endpoints = -1;
43 static int hf_nsip_reset_flag = -1;
44 static int hf_nsip_reset_flag_bit = -1;
45 static int hf_nsip_reset_flag_spare = -1;
46 static int hf_nsip_ip_address_type = -1;
47 static int hf_nsip_ip_address_ipv4 = -1;
48 static int hf_nsip_ip_address_ipv6 = -1;
49 static int hf_nsip_end_flag = -1;
50 static int hf_nsip_end_flag_bit = -1;
51 static int hf_nsip_end_flag_spare = -1;
52 static int hf_nsip_control_bits = -1;
53 static int hf_nsip_control_bits_r = -1;
54 static int hf_nsip_control_bits_c = -1;
55 static int hf_nsip_control_bits_spare = -1;
56 static int hf_nsip_transaction_id = -1;
57 /* static int hf_nsip_ip_element_ip_address_ipv4 = -1; */
58 /* static int hf_nsip_ip_element_ip_address_ipv6 = -1; */
59 static int hf_nsip_ip_element_udp_port = -1;
60 static int hf_nsip_ip_element_signalling_weight = -1;
61 static int hf_nsip_ip_element_data_weight = -1;
62 static int hf_nsip_ns_pdu = -1;
63 static int hf_nsip_ns_sdu = -1;
65 /* Initialize the subtree pointers */
66 static gint ett_nsip = -1;
67 static gint ett_nsip_control_bits = -1;
68 static gint ett_nsip_reset_flag = -1;
69 static gint ett_nsip_end_flag = -1;
70 static gint ett_nsip_ip_element = -1;
71 static gint ett_nsip_ip_element_list = -1;
73 /* PDU type coding, v5.3.0, table 10.3.7.1, p 51 */
74 #define NSIP_PDU_NS_UNITDATA 0x00
75 #define NSIP_PDU_NS_RESET 0x02
76 #define NSIP_PDU_NS_RESET_ACK 0x03
77 #define NSIP_PDU_NS_BLOCK 0x04
78 #define NSIP_PDU_NS_BLOCK_ACK 0x05
79 #define NSIP_PDU_NS_UNBLOCK 0x06
80 #define NSIP_PDU_NS_UNBLOCK_ACK 0x07
81 #define NSIP_PDU_NS_STATUS 0x08
82 #define NSIP_PDU_NS_ALIVE 0x0a
83 #define NSIP_PDU_NS_ALIVE_ACK 0x0b
84 #define NSIP_PDU_SNS_ACK 0x0c
85 #define NSIP_PDU_SNS_ADD 0x0d
86 #define NSIP_PDU_SNS_CHANGEWEIGHT 0x0e
87 #define NSIP_PDU_SNS_CONFIG 0x0f
88 #define NSIP_PDU_SNS_CONFIG_ACK 0x10
89 #define NSIP_PDU_SNS_DELETE 0x11
90 #define NSIP_PDU_SNS_SIZE 0x12
91 #define NSIP_PDU_SNS_SIZE_ACK 0x13
93 static const value_string tab_nsip_pdu_types[] = {
94 { NSIP_PDU_NS_UNITDATA, "NS_UNITDATA" },
95 { NSIP_PDU_NS_RESET, "NS_RESET" },
96 { NSIP_PDU_NS_RESET_ACK, "NS_RESET_ACK" },
97 { NSIP_PDU_NS_BLOCK, "NS_BLOCK" },
98 { NSIP_PDU_NS_BLOCK_ACK, "NS_BLOCK_ACK" },
99 { NSIP_PDU_NS_UNBLOCK, "NS_UNBLOCK" },
100 { NSIP_PDU_NS_UNBLOCK_ACK, "NS_UNBLOCK_ACK" },
101 { NSIP_PDU_NS_STATUS, "NS_STATUS" },
102 { NSIP_PDU_NS_ALIVE, "NS_ALIVE" },
103 { NSIP_PDU_NS_ALIVE_ACK, "NS_ALIVE_ACK" },
104 { NSIP_PDU_SNS_ACK, "SNS_ACK" },
105 { NSIP_PDU_SNS_ADD, "SNS_ADD" },
106 { NSIP_PDU_SNS_CHANGEWEIGHT, "SNS_CHANGEWEIGHT" },
107 { NSIP_PDU_SNS_CONFIG, "SNS_CONFIG" },
108 { NSIP_PDU_SNS_CONFIG_ACK, "SNS_CONFIG_ACK" },
109 { NSIP_PDU_SNS_DELETE, "SNS_DELETE" },
110 { NSIP_PDU_SNS_SIZE, "SNS_SIZE" },
111 { NSIP_PDU_SNS_SIZE_ACK, "SNS_SIZE_ACK" },
115 /* Information element coding, v 5.3.0, table 10.3.1, p 46 */
116 #define NSIP_IE_CAUSE 0x00
117 #define NSIP_IE_NS_VCI 0x01
118 #define NSIP_IE_NS_PDU 0x02
119 #define NSIP_IE_BVCI 0x03
120 #define NSIP_IE_NSEI 0x04
121 #define NSIP_IE_IP4_ELEMENTS 0x05
122 #define NSIP_IE_IP6_ELEMENTS 0x06
123 #define NSIP_IE_MAX_NUM_NS_VC 0x07
124 #define NSIP_IE_NUM_IP4_ENDPOINTS 0x08
125 #define NSIP_IE_NUM_IP6_ENDPOINTS 0x09
126 #define NSIP_IE_RESET_FLAG 0x0a
127 #define NSIP_IE_IP_ADDRESS 0x0b
130 static const value_string tab_nsip_ieis[] = {
131 { NSIP_IE_CAUSE, "Cause" },
132 { NSIP_IE_NS_VCI, "NS-VCI" },
133 { NSIP_IE_NS_PDU, "NS PDU" },
134 { NSIP_IE_BVCI, "BVCI" },
135 { NSIP_IE_NSEI, "NSEI" },
136 { NSIP_IE_IP4_ELEMENTS, "List of IP4 Elements" },
137 { NSIP_IE_IP6_ELEMENTS, "List of IP6 Elements" },
138 { NSIP_IE_MAX_NUM_NS_VC, "Maximum Number of NC-VCs" },
139 { NSIP_IE_NUM_IP4_ENDPOINTS, "Number of IP4 Endpoints" },
140 { NSIP_IE_NUM_IP6_ENDPOINTS, "Number of IP6 Endpoints"},
141 { NSIP_IE_RESET_FLAG, "Reset Flag" },
142 { NSIP_IE_IP_ADDRESS, "IP Address" },
147 /* Cause values, v 5.3.0, table 10.3.2.1, p 47 */
148 #define NSIP_CAUSE_TRANSIT_NETWORK_FAILURE 0x00
149 #define NSIP_CAUSE_OM_INTERVENTION 0x01
150 #define NSIP_CAUSE_EQUIPMENT_FAILURE 0x02
151 #define NSIP_CAUSE_NS_VC_BLOCKED 0x03
152 #define NSIP_CAUSE_NS_VC_UNKNOWN 0x04
153 #define NSIP_CAUSE_BVCI_UNKNOWN 0x05
154 #define NSIP_CAUSE_SEMANTICALLY_INCORRECT_PDU 0x08
155 #define NSIP_CAUSE_NSIP_PDU_NOT_COMPATIBLE 0x0a
156 #define NSIP_CAUSE_PROTOCOL_ERROR 0x0b
157 #define NSIP_CAUSE_INVALID_ESSENTIAL_IE 0x0c
158 #define NSIP_CAUSE_MISSING_ESSENTIAL_IE 0x0d
159 #define NSIP_CAUSE_INVALID_NUM_IP4_ENDPOINTS 0x0e
160 #define NSIP_CAUSE_INVALID_NUM_IP6_ENDPOINTS 0x0f
161 #define NSIP_CAUSE_INVALID_NUM_NS_VC 0x10
162 #define NSIP_CAUSE_INVALID_WEIGHTS 0x11
163 #define NSIP_CAUSE_UNKNOWN_IP_ENDPOINT 0x12
164 #define NSIP_CAUSE_UNKNOWN_IP_ADDRESS 0x13
165 #define NSIP_CAUSE_IP_TEST_FAILED 0x14
167 static const value_string tab_nsip_cause_values[] = {
168 { NSIP_CAUSE_TRANSIT_NETWORK_FAILURE, "Transit network failure" },
169 { NSIP_CAUSE_OM_INTERVENTION, "O&M intervention" },
170 { NSIP_CAUSE_EQUIPMENT_FAILURE, "Equipment failure" },
171 { NSIP_CAUSE_NS_VC_BLOCKED, "NS-VC blocked" },
172 { NSIP_CAUSE_NS_VC_UNKNOWN, "NS-VC unknown" },
173 { NSIP_CAUSE_BVCI_UNKNOWN, "BVCI unknown on that NSE" },
174 { NSIP_CAUSE_SEMANTICALLY_INCORRECT_PDU, "Semantically incorrect PDU" },
175 { NSIP_CAUSE_NSIP_PDU_NOT_COMPATIBLE, "PDU not compatible with the protocol state" },
176 { NSIP_CAUSE_PROTOCOL_ERROR, "Protocol error - unspecified" },
177 { NSIP_CAUSE_INVALID_ESSENTIAL_IE, "Invalid essential IE" },
178 { NSIP_CAUSE_MISSING_ESSENTIAL_IE, "Missing essential IE" },
179 { NSIP_CAUSE_INVALID_NUM_IP4_ENDPOINTS, "Invalid number of IP4 endpoints" },
180 { NSIP_CAUSE_INVALID_NUM_IP6_ENDPOINTS, "Invalid number of IP6 endpoints" },
181 { NSIP_CAUSE_INVALID_NUM_NS_VC, "Invalid number of NS-VCs" },
182 { NSIP_CAUSE_INVALID_WEIGHTS, "Invalid weights" },
183 { NSIP_CAUSE_UNKNOWN_IP_ENDPOINT, "Unknown IP endpoint" },
184 { NSIP_CAUSE_UNKNOWN_IP_ADDRESS, "Unknown IP address" },
185 { NSIP_CAUSE_IP_TEST_FAILED, "IP test failed" },
189 /* Presence requirements of Information Elements
190 v 5.3.0, chapter 8.1.1, p. 35 */
191 #define NSIP_IE_PRESENCE_M 1 /* Mandatory */
192 #define NSIP_IE_PRESENCE_O 2 /* Conditional */
193 #define NSIP_IE_PRESENCE_C 3 /* Optional */
196 #define NSIP_IE_FORMAT_V 1
197 #define NSIP_IE_FORMAT_TV 2
198 #define NSIP_IE_FORMAT_TLV 3
200 /* IP address types, v 5.3.0, chapter 10.3.2b, p. 48 */
201 #define NSIP_IP_ADDRESS_TYPE_IPV4 1
202 #define NSIP_IP_ADDRESS_TYPE_IPV6 2
203 #define NSIP_IP_VERSION_4 4
204 #define NSIP_IP_VERSION_6 6
206 static const value_string ip_address_type_vals[] = {
208 { NSIP_IP_ADDRESS_TYPE_IPV4, "IPv4 Address" },
209 { NSIP_IP_ADDRESS_TYPE_IPV6, "IPv6 Address" },
214 #define NSIP_MASK_CONTROL_BITS_R 0x01
215 #define NSIP_MASK_CONTROL_BITS_C 0x02
216 #define NSIP_MASK_CONTROL_BITS_SPARE 0xFC
217 #define NSIP_MASK_END_FLAG 0x01
218 #define NSIP_MASK_END_FLAG_SPARE 0xFE
219 #define NSIP_MASK_RESET_FLAG 0x01
220 #define NSIP_MASK_RESET_FLAG_SPARE 0xFE
222 static dissector_handle_t bssgp_handle;
223 static dissector_handle_t nsip_handle;
225 static gboolean nsip_is_recursive = FALSE;
231 guint16 value_length; /* in bytes */
232 guint16 total_length; /* as specified, or 0 if unspecified */
239 proto_tree *nsip_tree;
240 proto_tree *parent_tree;
248 } nsip_ip_element_info_t;
250 static nsip_ip_element_info_t ipv4_element = { NSIP_IP_VERSION_4, 4, 8 };
251 static nsip_ip_element_info_t ipv6_element = { NSIP_IP_VERSION_6, 16, 20 };
254 get_value_length(nsip_ie_t *ie, build_info_t *bi) {
255 /* length indicator in bit 8, 0 => two bytes, 1 => one byte */
256 const guint8 MASK_LENGTH_INDICATOR = 0x80;
257 const guint8 MASK_ONE_BYTE_LENGTH = 0x7f;
261 length = tvb_get_guint8(bi->tvb, bi->offset);
264 if (length & MASK_LENGTH_INDICATOR) {
265 length &= MASK_ONE_BYTE_LENGTH;
270 length |= tvb_get_guint8(bi->tvb, bi->offset+1);
272 ie->value_length = length;
273 ie->total_length += length_len + length;
274 bi->offset += length_len;
278 check_correct_iei(nsip_ie_t *ie, build_info_t *bi) {
279 guint8 fetched_iei = tvb_get_guint8(bi->tvb, bi->offset);
282 if (fetched_iei != ie->iei) {
283 proto_tree_add_debug(bi->nsip_tree, bi->tvb, bi->offset, 1,
284 "Tried IEI %s (%#02x), found IEI %s (%#02x)",
285 val_to_str_const(ie->iei, tab_nsip_ieis, "Unknown"),
287 val_to_str_const(fetched_iei, tab_nsip_ieis, "Unknown"),
291 return (fetched_iei == ie->iei);
295 decode_iei_cause(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
298 cause = tvb_get_guint8(bi->tvb, bi->offset);
299 proto_tree_add_uint(bi->nsip_tree, hf_nsip_cause,
300 bi->tvb, ie_start_offset, ie->total_length,
302 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
304 val_to_str(cause, tab_nsip_cause_values, "Unknown (0x%02x)"));
306 proto_item_append_text(bi->ti, ", Cause: %s",
307 val_to_str(cause, tab_nsip_cause_values, "Unknown (0x%02x)"));
309 bi->offset += ie->value_length;
313 decode_iei_ns_vci(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
316 ns_vci = tvb_get_ntohs(bi->tvb, bi->offset);
318 proto_tree_add_uint(bi->nsip_tree, hf_nsip_ns_vci,
319 bi->tvb, ie_start_offset, ie->total_length,
321 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
322 "NS VCI: %#04x", ns_vci);
323 proto_item_append_text(bi->ti, ", NS VCI: %#04x", ns_vci);
325 bi->offset += ie->value_length;
329 decode_iei_ns_pdu(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
332 proto_tree_add_bytes_format(bi->nsip_tree, hf_nsip_ns_pdu, bi->tvb, ie_start_offset,
333 ie->total_length, NULL,
334 "NS PDU (%u bytes)", ie->value_length);
335 next_tvb = tvb_new_subset_length_caplen(bi->tvb, bi->offset, ie->value_length, -1);
337 gboolean was_recursive;
338 was_recursive = nsip_is_recursive;
339 nsip_is_recursive = TRUE;
340 call_dissector(nsip_handle, next_tvb, bi->pinfo, bi->nsip_tree);
341 nsip_is_recursive = was_recursive;
343 bi->offset += ie->value_length;
347 decode_iei_nsei(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
348 guint16 nsei = tvb_get_ntohs(bi->tvb, bi->offset);
350 proto_tree_add_uint(bi->nsip_tree, hf_nsip_nsei, bi->tvb,
351 ie_start_offset, ie->total_length, nsei);
352 bi->offset += ie->value_length;
354 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
357 proto_item_append_text(bi->ti, ", NSEI %u", nsei);
361 decode_iei_bvci(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
362 guint16 bvci = tvb_get_ntohs(bi->tvb, bi->offset);
364 proto_tree_add_uint(bi->nsip_tree, hf_nsip_bvci, bi->tvb,
365 ie_start_offset, ie->total_length, bvci);
366 bi->offset += ie->value_length;
368 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
370 proto_item_append_text(bi->ti, ", BVCI %u", bvci);
374 decode_ip_element(nsip_ip_element_info_t *element, build_info_t *bi, proto_tree * element_tree) {
377 proto_tree *field_tree;
379 field_tree = proto_tree_add_subtree(element_tree, bi->tvb, bi->offset,
380 element->total_length, ett_nsip_ip_element, &tf, "IP Element");
384 switch (element->version) {
385 case NSIP_IP_VERSION_4:
386 proto_tree_add_item(field_tree, hf_nsip_ip_address_ipv4,
387 bi->tvb, bi->offset, element->address_length,
389 proto_item_append_text(tf, ": IP address: %s",
390 tvb_ip_to_str(bi->tvb, bi->offset));
393 case NSIP_IP_VERSION_6:
394 proto_tree_add_item(field_tree, hf_nsip_ip_address_ipv6, bi->tvb,
395 bi->offset, element->address_length,
397 proto_item_append_text(tf, ": IP address: %s",
398 tvb_ip6_to_str(bi->tvb, bi->offset));
404 bi->offset += element->address_length;
408 udp_port = tvb_get_ntohs(bi->tvb, bi->offset);
409 proto_tree_add_item(field_tree, hf_nsip_ip_element_udp_port,
410 bi->tvb, bi->offset, 2, ENC_BIG_ENDIAN);
411 proto_item_append_text(tf, ", UDP Port: %u", udp_port);
416 /* Signalling weight */
417 proto_tree_add_item(field_tree, hf_nsip_ip_element_signalling_weight,
418 bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN);
424 proto_tree_add_item(field_tree, hf_nsip_ip_element_data_weight,
425 bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN);
432 decode_ip_elements(nsip_ip_element_info_t *element, nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
434 int num_elements = ie->value_length / element->total_length;
436 proto_tree *field_tree;
438 field_tree = proto_tree_add_subtree_format(bi->nsip_tree, bi->tvb, ie_start_offset,
439 ie->total_length, ett_nsip_ip_element_list, &tf,
440 "List of IP%u Elements (%u Elements)",
441 element->version, num_elements);
443 for (i = 0; i < num_elements; i++) {
444 decode_ip_element(element, bi, field_tree);
450 decode_iei_max_num_ns_vc(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
454 num_ns_vc = tvb_get_ntohs(bi->tvb, bi->offset);
456 proto_tree_add_uint(bi->nsip_tree, hf_nsip_max_num_ns_vc,
457 bi->tvb, ie_start_offset, ie->total_length,
464 decode_iei_num_ip4_endpoints(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
465 guint16 num_endpoints;
468 num_endpoints = tvb_get_ntohs(bi->tvb, bi->offset);
470 proto_tree_add_uint(bi->nsip_tree, hf_nsip_num_ip4_endpoints,
471 bi->tvb, ie_start_offset, ie->total_length,
478 decode_iei_num_ip6_endpoints(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
479 guint16 num_endpoints;
482 num_endpoints = tvb_get_ntohs(bi->tvb, bi->offset);
484 proto_tree_add_uint(bi->nsip_tree, hf_nsip_num_ip6_endpoints,
485 bi->tvb, ie_start_offset, ie->total_length,
492 decode_iei_reset_flag(nsip_ie_t *ie _U_, build_info_t *bi, int ie_start_offset _U_) {
494 static const int * reset_flags[] = {
495 &hf_nsip_reset_flag_bit,
496 &hf_nsip_reset_flag_spare,
500 flag = tvb_get_guint8(bi->tvb, bi->offset);
501 proto_tree_add_bitmask(bi->nsip_tree, bi->tvb, bi->offset, hf_nsip_reset_flag,
502 ett_nsip_reset_flag, reset_flags, ENC_NA);
504 if (flag & NSIP_MASK_RESET_FLAG) {
505 col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Reset");
511 decode_iei_ip_address(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
514 ws_in6_addr ip6_addr;
516 addr_type = tvb_get_guint8(bi->tvb, bi->offset);
517 proto_tree_add_item(bi->nsip_tree, hf_nsip_ip_address_type,
518 bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN);
520 case NSIP_IP_ADDRESS_TYPE_IPV4:
521 ie->total_length = 2 + ipv4_element.address_length;
522 ip4_addr = tvb_get_ipv4(bi->tvb, bi->offset+1);
523 proto_tree_add_ipv4(bi->nsip_tree, hf_nsip_ip_address_ipv4,
524 bi->tvb, ie_start_offset, ie->total_length,
527 case NSIP_IP_ADDRESS_TYPE_IPV6:
528 ie->total_length = 2 + ipv6_element.address_length;
529 tvb_get_ipv6(bi->tvb, bi->offset+1, &ip6_addr);
530 proto_tree_add_ipv6(bi->nsip_tree, hf_nsip_ip_address_ipv4,
531 bi->tvb, ie_start_offset, ie->total_length,
537 bi->offset += ie->value_length;
541 decode_iei_transaction_id(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
543 id = tvb_get_guint8(bi->tvb, bi->offset);
544 proto_tree_add_uint(bi->nsip_tree, hf_nsip_transaction_id,
545 bi->tvb, ie_start_offset, ie->total_length, id);
546 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
547 "Transaction Id: %d", id);
552 decode_iei_end_flag(nsip_ie_t *ie _U_, build_info_t *bi, int ie_start_offset) {
553 static const int * end_flags[] = {
554 &hf_nsip_end_flag_bit,
555 &hf_nsip_end_flag_spare,
559 proto_tree_add_bitmask(bi->nsip_tree, bi->tvb, ie_start_offset, hf_nsip_end_flag,
560 ett_nsip_end_flag, end_flags, ENC_NA);
565 decode_iei_control_bits(nsip_ie_t *ie _U_, build_info_t *bi, int ie_start_offset) {
567 static const int * flags[] = {
568 &hf_nsip_control_bits_r,
569 &hf_nsip_control_bits_c,
570 &hf_nsip_control_bits_spare,
574 control_bits = tvb_get_guint8(bi->tvb, bi->offset);
575 proto_tree_add_bitmask(bi->nsip_tree, bi->tvb, ie_start_offset, hf_nsip_control_bits,
576 ett_nsip_control_bits, flags, ENC_NA);
579 if (control_bits & NSIP_MASK_CONTROL_BITS_R) {
580 col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Req CF");
581 proto_item_append_text(bi->ti, ", Request Change Flow");
584 if (control_bits & NSIP_MASK_CONTROL_BITS_C) {
585 col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Conf CF");
586 proto_item_append_text(bi->ti, ", Confirm Change Flow");
592 decode_ie(nsip_ie_t *ie, build_info_t *bi) {
594 int org_offset = bi->offset;
596 if (tvb_captured_length_remaining(bi->tvb, bi->offset) < 1) {
599 switch (ie->format) {
600 case NSIP_IE_FORMAT_TLV:
601 if (!check_correct_iei(ie, bi)) {
604 bi->offset++; /* Account for type */
605 ie->total_length = 1;
606 get_value_length(ie, bi);
608 case NSIP_IE_FORMAT_TV:
609 if (!check_correct_iei(ie, bi)) {
612 bi->offset++; /* Account for type */
613 ie->value_length = ie->total_length - 1;
615 case NSIP_IE_FORMAT_V:
616 ie->value_length = ie->total_length;
622 decode_iei_cause(ie, bi, org_offset);
625 decode_iei_ns_vci(ie, bi, org_offset);
628 decode_iei_ns_pdu(ie, bi, org_offset);
631 decode_iei_nsei(ie, bi, org_offset);
634 decode_iei_bvci(ie, bi, org_offset);
636 case NSIP_IE_IP4_ELEMENTS:
637 decode_ip_elements(&ipv4_element, ie, bi, org_offset);
639 case NSIP_IE_IP6_ELEMENTS:
640 decode_ip_elements(&ipv6_element, ie, bi, org_offset);
642 case NSIP_IE_MAX_NUM_NS_VC:
643 decode_iei_max_num_ns_vc(ie, bi, org_offset);
645 case NSIP_IE_NUM_IP4_ENDPOINTS:
646 decode_iei_num_ip4_endpoints(ie, bi, org_offset);
648 case NSIP_IE_NUM_IP6_ENDPOINTS:
649 decode_iei_num_ip6_endpoints(ie, bi, org_offset);
651 case NSIP_IE_RESET_FLAG:
652 decode_iei_reset_flag(ie, bi, org_offset);
654 case NSIP_IE_IP_ADDRESS:
655 decode_iei_ip_address(ie, bi, org_offset);
663 decode_pdu_general(nsip_ie_t *ies, int num_ies, build_info_t *bi) {
665 for (i = 0; i < num_ies; i++) {
666 decode_ie(&ies[i], bi);
671 decode_pdu_ns_unitdata(build_info_t *bi) {
675 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Control bits */
676 { NSIP_IE_BVCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 2 },
677 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 0 },
678 /* NS SDU, length unknown */
682 decode_iei_control_bits(ies, bi, bi->offset);
683 decode_pdu_general(&ies[1], 1, bi);
685 next_tvb = tvb_new_subset_remaining(bi->tvb, bi->offset);
687 call_dissector(bssgp_handle, next_tvb, bi->pinfo, bi->parent_tree);
690 sdu_length = tvb_captured_length_remaining(bi->tvb, bi->offset);
691 proto_tree_add_bytes_format(bi->nsip_tree, hf_nsip_ns_sdu, bi->tvb, bi->offset, sdu_length,
692 NULL, "NS SDU (%u bytes)", sdu_length);
697 decode_pdu_ns_reset(build_info_t *bi) {
699 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 3 },
700 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
701 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
703 decode_pdu_general(ies, 3, bi);
707 decode_pdu_ns_reset_ack(build_info_t *bi) {
709 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
710 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
712 decode_pdu_general(ies, 2, bi);
716 decode_pdu_ns_block(build_info_t *bi) {
718 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 3 },
719 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
721 decode_pdu_general(ies, 2, bi);
725 decode_pdu_ns_block_ack(build_info_t *bi) {
726 nsip_ie_t ies[] = { { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV,
728 decode_pdu_general(ies, 1, bi);
732 decode_pdu_ns_status(build_info_t *bi) {
734 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 3 },
735 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
736 { NSIP_IE_NS_PDU, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
738 { NSIP_IE_BVCI, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 4 },
739 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
741 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
744 decode_pdu_general(ies, 6, bi);
748 decode_pdu_sns_ack(build_info_t *bi) {
750 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
751 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
752 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 3 },
753 { NSIP_IE_IP_ADDRESS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV, 0, 0 },
755 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
756 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
758 decode_pdu_general(ies, 1, bi);
759 decode_iei_transaction_id(&ies[1], bi, bi->offset);
760 decode_pdu_general(&ies[2], 4, bi);
764 decode_pdu_sns_add(build_info_t *bi) {
766 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
767 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
768 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
770 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
773 decode_pdu_general(ies, 1, bi);
774 decode_iei_transaction_id(&ies[1], bi, bi->offset);
775 decode_pdu_general(&ies[2], 2, bi);
779 decode_pdu_sns_changeweight(build_info_t *bi) {
781 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
782 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
783 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
785 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
788 decode_pdu_general(ies, 1, bi);
789 decode_iei_transaction_id(&ies[1], bi, bi->offset);
790 decode_pdu_general(&ies[2], 2, bi);
794 decode_pdu_sns_config(build_info_t *bi) {
797 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* End flag */
798 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
799 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
801 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
804 decode_iei_end_flag(ies, bi, bi->offset);
805 decode_pdu_general(&ies[1], 3, bi);
809 decode_pdu_sns_config_ack(build_info_t *bi) {
811 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
812 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 3 },
814 decode_pdu_general(ies, 2, bi);
818 decode_pdu_sns_delete(build_info_t *bi) {
820 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4}, /* CR013 */
821 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
822 { NSIP_IE_IP_ADDRESS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV, 0, 0 },
824 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
825 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
827 decode_pdu_general(ies, 1, bi);
828 decode_iei_transaction_id(&ies[1], bi, bi->offset);
829 decode_pdu_general(&ies[2], 3, bi);
833 decode_pdu_sns_size(build_info_t *bi) {
835 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
836 { NSIP_IE_RESET_FLAG, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TV, 0, 2 },
837 { NSIP_IE_MAX_NUM_NS_VC, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TV, 0, 3 },
838 { NSIP_IE_NUM_IP4_ENDPOINTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV,
840 { NSIP_IE_NUM_IP6_ENDPOINTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV,
843 decode_pdu_general(ies, 5, bi);
847 decode_pdu_sns_size_ack(build_info_t *bi) {
849 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
850 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 3 },
852 decode_pdu_general(ies, 2, bi);
856 decode_pdu(guint8 pdu_type, build_info_t *bi) {
858 case NSIP_PDU_NS_UNITDATA:
859 decode_pdu_ns_unitdata(bi);
861 case NSIP_PDU_NS_RESET:
862 decode_pdu_ns_reset(bi);
864 case NSIP_PDU_NS_RESET_ACK:
865 decode_pdu_ns_reset_ack(bi);
867 case NSIP_PDU_NS_BLOCK:
868 decode_pdu_ns_block(bi);
870 case NSIP_PDU_NS_BLOCK_ACK:
871 decode_pdu_ns_block_ack(bi);
873 case NSIP_PDU_NS_STATUS:
874 decode_pdu_ns_status(bi);
876 case NSIP_PDU_SNS_ACK:
877 decode_pdu_sns_ack(bi);
879 case NSIP_PDU_SNS_ADD:
880 decode_pdu_sns_add(bi);
882 case NSIP_PDU_SNS_CHANGEWEIGHT:
883 decode_pdu_sns_changeweight(bi);
885 case NSIP_PDU_SNS_CONFIG:
886 decode_pdu_sns_config(bi);
888 case NSIP_PDU_SNS_CONFIG_ACK:
889 decode_pdu_sns_config_ack(bi);
891 case NSIP_PDU_SNS_DELETE:
892 decode_pdu_sns_delete(bi);
894 case NSIP_PDU_SNS_SIZE:
895 decode_pdu_sns_size(bi);
897 case NSIP_PDU_SNS_SIZE_ACK:
898 decode_pdu_sns_size_ack(bi);
900 case NSIP_PDU_NS_ALIVE:
901 case NSIP_PDU_NS_ALIVE_ACK:
902 case NSIP_PDU_NS_UNBLOCK:
903 case NSIP_PDU_NS_UNBLOCK_ACK:
904 /* Only contains PDU type, which has already been decoded */
910 dissect_nsip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
912 build_info_t bi = { NULL, 0, NULL, NULL, NULL, NULL };
913 proto_tree *nsip_tree;
917 bi.parent_tree = tree;
919 if (!nsip_is_recursive) {
920 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GPRS-NS");
921 col_clear(pinfo->cinfo, COL_INFO);
924 pdu_type = tvb_get_guint8(tvb, 0);
928 bi.ti = proto_tree_add_item(tree, proto_nsip, tvb, 0, -1,
930 nsip_tree = proto_item_add_subtree(bi.ti, ett_nsip);
931 proto_tree_add_item(nsip_tree, hf_nsip_pdu_type, tvb, 0, 1, ENC_BIG_ENDIAN);
932 proto_item_append_text(bi.ti, ", PDU type: %s",
933 val_to_str_const(pdu_type, tab_nsip_pdu_types, "Unknown"));
934 bi.nsip_tree = nsip_tree;
937 if (!nsip_is_recursive) {
938 col_set_str(pinfo->cinfo, COL_INFO,
939 val_to_str_const(pdu_type, tab_nsip_pdu_types, "Unknown PDU type"));
941 col_append_sep_str(pinfo->cinfo, COL_INFO, NSIP_SEP,
942 val_to_str_const(pdu_type, tab_nsip_pdu_types, "Unknown PDU type"));
944 decode_pdu(pdu_type, &bi);
945 return tvb_captured_length(tvb);
949 proto_register_nsip(void)
951 static hf_register_info hf[] = {
953 { "Cause", "nsip.cause",
954 FT_UINT8, BASE_HEX, VALS(tab_nsip_cause_values), 0x0,
958 { "NS-VCI", "nsip.ns_vci",
959 FT_UINT16, BASE_HEX, NULL, 0x0,
960 "Network Service Virtual Link Identifier", HFILL }
963 { "PDU type", "nsip.pdu_type",
964 FT_UINT8, BASE_HEX, VALS(tab_nsip_pdu_types), 0x0,
965 "PDU type information element", HFILL }
968 { "BVCI", "nsip.bvci",
969 FT_UINT16, BASE_DEC, NULL, 0x0,
970 "BSSGP Virtual Connection Identifier", HFILL }
973 { "NSEI", "nsip.nsei",
974 FT_UINT16, BASE_DEC, NULL, 0x0,
975 "Network Service Entity Identifier", HFILL }
978 { &hf_nsip_ip4_elements,
979 { "IP4 elements", "nsip.ip4_elements",
980 FT_NONE, BASE_NONE, NULL, 0x0,
981 "List of IP4 elements", HFILL }
985 { &hf_nsip_ip6_elements,
986 { "IP6 elements", "nsip.ip6_elements",
987 FT_NONE, BASE_NONE, NULL, 0x0,
988 "List of IP6 elements", HFILL }
991 { &hf_nsip_max_num_ns_vc,
992 { "Maximum number of NS-VCs", "nsip.max_num_ns_vc",
993 FT_UINT16, BASE_DEC, NULL, 0x0,
996 { &hf_nsip_num_ip4_endpoints,
997 { "Number of IP4 endpoints", "nsip.num_ip4_endpoints",
998 FT_UINT16, BASE_DEC, NULL, 0x0,
1001 { &hf_nsip_num_ip6_endpoints,
1002 { "Number of IP6 endpoints", "nsip.num_ip6_endpoints",
1003 FT_UINT16, BASE_DEC, NULL, 0x0,
1006 { &hf_nsip_reset_flag,
1007 { "Reset flag", "nsip.reset_flag",
1008 FT_UINT8, BASE_HEX, NULL, 0,
1011 { &hf_nsip_reset_flag_bit,
1012 { "Reset flag", "nsip.reset_flag.flag",
1013 FT_BOOLEAN, 8, TFS(&tfs_set_notset), NSIP_MASK_RESET_FLAG,
1016 { &hf_nsip_reset_flag_spare,
1017 { "Reset flag spare bits", "nsip.reset_flag.spare",
1018 FT_UINT8, BASE_HEX, NULL, NSIP_MASK_RESET_FLAG_SPARE,
1021 { &hf_nsip_ip_address_type,
1022 { "IP Address Type", "nsip.ip_address_type",
1023 FT_UINT8, BASE_DEC, VALS(ip_address_type_vals), 0x0,
1026 { &hf_nsip_ip_address_ipv4,
1027 { "IP Address", "nsip.ipv4_address",
1028 FT_IPv4, BASE_NONE, NULL, 0x0,
1031 { &hf_nsip_ip_address_ipv6,
1032 { "IP Address", "nsip.ipv6_address",
1033 FT_IPv6, BASE_NONE, NULL, 0x0,
1036 { &hf_nsip_end_flag,
1037 { "End flag", "nsip.end_flag",
1038 FT_UINT8, BASE_HEX, NULL, 0x0,
1041 { &hf_nsip_end_flag_bit,
1042 { "End flag", "nsip.end_flag.flag",
1043 FT_BOOLEAN, 8, TFS(&tfs_set_notset), NSIP_MASK_END_FLAG,
1046 { &hf_nsip_end_flag_spare,
1047 { "End flag spare bits", "nsip.end_flag.spare",
1048 FT_UINT8, BASE_HEX, NULL, NSIP_MASK_END_FLAG_SPARE,
1051 { &hf_nsip_control_bits,
1052 { "NS SDU Control bits", "nsip.control_bits",
1053 FT_UINT8, BASE_HEX, NULL, 0x0,
1056 { &hf_nsip_control_bits_r,
1057 { "Request change flow", "nsip.control_bits.r",
1058 FT_BOOLEAN, 8, TFS(&tfs_set_notset), NSIP_MASK_CONTROL_BITS_R,
1061 { &hf_nsip_control_bits_c,
1062 { "Confirm change flow", "nsip.control_bits.c",
1063 FT_BOOLEAN, 8, TFS(&tfs_set_notset), NSIP_MASK_CONTROL_BITS_C,
1066 { &hf_nsip_control_bits_spare,
1067 { "Spare bits", "nsip.control_bits.spare",
1068 FT_UINT8, BASE_HEX, NULL, NSIP_MASK_CONTROL_BITS_SPARE,
1071 { &hf_nsip_transaction_id,
1072 { "Transaction ID", "nsip.transaction_id",
1073 FT_UINT8, BASE_DEC, NULL, 0x0,
1077 { &hf_nsip_ip_element_ip_address_ipv4,
1078 { "IP Address", "nsip.ip_element.ipv4_address",
1079 FT_IPv4, BASE_NONE, NULL, 0x0,
1084 { &hf_nsip_ip_element_ip_address_ipv6,
1085 { "IP Address", "nsip.ip_element.ipv6_address",
1086 FT_IPv6, BASE_NONE, NULL, 0x0,
1090 { &hf_nsip_ip_element_udp_port,
1091 { "UDP Port", "nsip.ip_element.udp_port",
1092 FT_UINT16, BASE_DEC, NULL, 0x0,
1095 { &hf_nsip_ip_element_signalling_weight,
1096 { "Signalling Weight", "nsip.ip_element.signalling_weight",
1097 FT_UINT8, BASE_DEC, NULL, 0x0,
1100 { &hf_nsip_ip_element_data_weight,
1101 { "Data Weight", "nsip.ip_element.data_weight",
1102 FT_UINT8, BASE_DEC, NULL, 0x0,
1106 { "NS PDU", "nsip.ns_pdu",
1107 FT_BYTES, BASE_NONE, NULL, 0x0,
1111 { "NS SDU", "nsip.ns_sdu",
1112 FT_BYTES, BASE_NONE, NULL, 0x0,
1117 /* Setup protocol subtree array */
1118 static gint *ett[] = {
1120 &ett_nsip_control_bits,
1121 &ett_nsip_reset_flag,
1123 &ett_nsip_ip_element,
1124 &ett_nsip_ip_element_list,
1127 module_t *nsip_module;
1129 /* Register the protocol name and description */
1130 proto_nsip = proto_register_protocol("GPRS Network Service", "GPRS-NS", "gprs-ns");
1132 /* Required function calls to register the header fields and
1134 proto_register_field_array(proto_nsip, hf, array_length(hf));
1135 proto_register_subtree_array(ett, array_length(ett));
1137 register_dissector("gprs_ns", dissect_nsip, proto_nsip);
1139 /* Register configuration options */
1140 nsip_module = prefs_register_protocol(proto_nsip, NULL);
1141 /* For reading older preference files with "nsip." preferences */
1142 prefs_register_module_alias("nsip", nsip_module);
1143 prefs_register_obsolete_preference(nsip_module, "udp.port1");
1144 prefs_register_obsolete_preference(nsip_module, "udp.port2");
1148 proto_reg_handoff_nsip(void) {
1150 nsip_handle = find_dissector_add_dependency("gprs_ns", proto_nsip);
1151 bssgp_handle = find_dissector_add_dependency("bssgp", proto_nsip);
1153 dissector_add_uint_range_with_preference("udp.port", DEFAULT_NSIP_PORT_RANGE, nsip_handle);
1154 dissector_add_uint("atm.aal5.type", TRAF_GPRS_NS, nsip_handle);
1159 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1164 * indent-tabs-mode: nil
1167 * vi: set shiftwidth=2 tabstop=8 expandtab:
1168 * :indentSize=2:tabSize=8:noTabs=true: