epan/dissectors/pidl/ C99 drsuapi
[wireshark-sm.git] / epan / dissectors / packet-nsip.c
blob2b42ba6505e1ee35971e0270650055208ff23301
1 /* packet-nsip.c
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 */
14 #include "config.h"
16 #include <epan/packet.h>
18 #include <epan/prefs.h>
19 #include <epan/to_str.h>
20 #include <epan/tfs.h>
21 #include <wsutil/array.h>
22 #include <wiretap/wtap.h>
24 void proto_register_nsip(void);
25 void proto_reg_handoff_nsip(void);
27 #define NSIP_DEBUG 0
28 #define NSIP_SEP ", " /* Separator string */
30 #define DEFAULT_NSIP_PORT_RANGE "2157,19999" /* Not IANA registered */
32 /* Initialize the protocol and registered fields */
33 static int proto_nsip;
35 static int hf_nsip_cause;
36 static int hf_nsip_ns_vci;
37 static int hf_nsip_pdu_type;
38 static int hf_nsip_bvci;
39 static int hf_nsip_nsei;
40 /* static int hf_nsip_ip4_elements; */
41 /* static int hf_nsip_ip6_elements; */
42 static int hf_nsip_max_num_ns_vc;
43 static int hf_nsip_num_ip4_endpoints;
44 static int hf_nsip_num_ip6_endpoints;
45 static int hf_nsip_reset_flag;
46 static int hf_nsip_reset_flag_bit;
47 static int hf_nsip_reset_flag_spare;
48 static int hf_nsip_ip_address_type;
49 static int hf_nsip_ip_address_ipv4;
50 static int hf_nsip_ip_address_ipv6;
51 static int hf_nsip_end_flag;
52 static int hf_nsip_end_flag_bit;
53 static int hf_nsip_end_flag_spare;
54 static int hf_nsip_control_bits;
55 static int hf_nsip_control_bits_r;
56 static int hf_nsip_control_bits_c;
57 static int hf_nsip_control_bits_spare;
58 static int hf_nsip_transaction_id;
59 /* static int hf_nsip_ip_element_ip_address_ipv4; */
60 /* static int hf_nsip_ip_element_ip_address_ipv6; */
61 static int hf_nsip_ip_element_udp_port;
62 static int hf_nsip_ip_element_signalling_weight;
63 static int hf_nsip_ip_element_data_weight;
64 static int hf_nsip_ns_pdu;
65 static int hf_nsip_ns_sdu;
67 /* Initialize the subtree pointers */
68 static int ett_nsip;
69 static int ett_nsip_control_bits;
70 static int ett_nsip_reset_flag;
71 static int ett_nsip_end_flag;
72 static int ett_nsip_ip_element;
73 static int ett_nsip_ip_element_list;
75 /* PDU type coding, v5.3.0, table 10.3.7.1, p 51 */
76 #define NSIP_PDU_NS_UNITDATA 0x00
77 #define NSIP_PDU_NS_RESET 0x02
78 #define NSIP_PDU_NS_RESET_ACK 0x03
79 #define NSIP_PDU_NS_BLOCK 0x04
80 #define NSIP_PDU_NS_BLOCK_ACK 0x05
81 #define NSIP_PDU_NS_UNBLOCK 0x06
82 #define NSIP_PDU_NS_UNBLOCK_ACK 0x07
83 #define NSIP_PDU_NS_STATUS 0x08
84 #define NSIP_PDU_NS_ALIVE 0x0a
85 #define NSIP_PDU_NS_ALIVE_ACK 0x0b
86 #define NSIP_PDU_SNS_ACK 0x0c
87 #define NSIP_PDU_SNS_ADD 0x0d
88 #define NSIP_PDU_SNS_CHANGEWEIGHT 0x0e
89 #define NSIP_PDU_SNS_CONFIG 0x0f
90 #define NSIP_PDU_SNS_CONFIG_ACK 0x10
91 #define NSIP_PDU_SNS_DELETE 0x11
92 #define NSIP_PDU_SNS_SIZE 0x12
93 #define NSIP_PDU_SNS_SIZE_ACK 0x13
95 static const value_string tab_nsip_pdu_types[] = {
96 { NSIP_PDU_NS_UNITDATA, "NS_UNITDATA" },
97 { NSIP_PDU_NS_RESET, "NS_RESET" },
98 { NSIP_PDU_NS_RESET_ACK, "NS_RESET_ACK" },
99 { NSIP_PDU_NS_BLOCK, "NS_BLOCK" },
100 { NSIP_PDU_NS_BLOCK_ACK, "NS_BLOCK_ACK" },
101 { NSIP_PDU_NS_UNBLOCK, "NS_UNBLOCK" },
102 { NSIP_PDU_NS_UNBLOCK_ACK, "NS_UNBLOCK_ACK" },
103 { NSIP_PDU_NS_STATUS, "NS_STATUS" },
104 { NSIP_PDU_NS_ALIVE, "NS_ALIVE" },
105 { NSIP_PDU_NS_ALIVE_ACK, "NS_ALIVE_ACK" },
106 { NSIP_PDU_SNS_ACK, "SNS_ACK" },
107 { NSIP_PDU_SNS_ADD, "SNS_ADD" },
108 { NSIP_PDU_SNS_CHANGEWEIGHT, "SNS_CHANGEWEIGHT" },
109 { NSIP_PDU_SNS_CONFIG, "SNS_CONFIG" },
110 { NSIP_PDU_SNS_CONFIG_ACK, "SNS_CONFIG_ACK" },
111 { NSIP_PDU_SNS_DELETE, "SNS_DELETE" },
112 { NSIP_PDU_SNS_SIZE, "SNS_SIZE" },
113 { NSIP_PDU_SNS_SIZE_ACK, "SNS_SIZE_ACK" },
114 { 0, NULL },
117 /* Information element coding, v 5.3.0, table 10.3.1, p 46 */
118 #define NSIP_IE_CAUSE 0x00
119 #define NSIP_IE_NS_VCI 0x01
120 #define NSIP_IE_NS_PDU 0x02
121 #define NSIP_IE_BVCI 0x03
122 #define NSIP_IE_NSEI 0x04
123 #define NSIP_IE_IP4_ELEMENTS 0x05
124 #define NSIP_IE_IP6_ELEMENTS 0x06
125 #define NSIP_IE_MAX_NUM_NS_VC 0x07
126 #define NSIP_IE_NUM_IP4_ENDPOINTS 0x08
127 #define NSIP_IE_NUM_IP6_ENDPOINTS 0x09
128 #define NSIP_IE_RESET_FLAG 0x0a
129 #define NSIP_IE_IP_ADDRESS 0x0b
131 #if NSIP_DEBUG
132 static const value_string tab_nsip_ieis[] = {
133 { NSIP_IE_CAUSE, "Cause" },
134 { NSIP_IE_NS_VCI, "NS-VCI" },
135 { NSIP_IE_NS_PDU, "NS PDU" },
136 { NSIP_IE_BVCI, "BVCI" },
137 { NSIP_IE_NSEI, "NSEI" },
138 { NSIP_IE_IP4_ELEMENTS, "List of IP4 Elements" },
139 { NSIP_IE_IP6_ELEMENTS, "List of IP6 Elements" },
140 { NSIP_IE_MAX_NUM_NS_VC, "Maximum Number of NC-VCs" },
141 { NSIP_IE_NUM_IP4_ENDPOINTS, "Number of IP4 Endpoints" },
142 { NSIP_IE_NUM_IP6_ENDPOINTS, "Number of IP6 Endpoints"},
143 { NSIP_IE_RESET_FLAG, "Reset Flag" },
144 { NSIP_IE_IP_ADDRESS, "IP Address" },
145 { 0, NULL },
147 #endif
149 /* Cause values, v 5.3.0, table 10.3.2.1, p 47 */
150 #define NSIP_CAUSE_TRANSIT_NETWORK_FAILURE 0x00
151 #define NSIP_CAUSE_OM_INTERVENTION 0x01
152 #define NSIP_CAUSE_EQUIPMENT_FAILURE 0x02
153 #define NSIP_CAUSE_NS_VC_BLOCKED 0x03
154 #define NSIP_CAUSE_NS_VC_UNKNOWN 0x04
155 #define NSIP_CAUSE_BVCI_UNKNOWN 0x05
156 #define NSIP_CAUSE_SEMANTICALLY_INCORRECT_PDU 0x08
157 #define NSIP_CAUSE_NSIP_PDU_NOT_COMPATIBLE 0x0a
158 #define NSIP_CAUSE_PROTOCOL_ERROR 0x0b
159 #define NSIP_CAUSE_INVALID_ESSENTIAL_IE 0x0c
160 #define NSIP_CAUSE_MISSING_ESSENTIAL_IE 0x0d
161 #define NSIP_CAUSE_INVALID_NUM_IP4_ENDPOINTS 0x0e
162 #define NSIP_CAUSE_INVALID_NUM_IP6_ENDPOINTS 0x0f
163 #define NSIP_CAUSE_INVALID_NUM_NS_VC 0x10
164 #define NSIP_CAUSE_INVALID_WEIGHTS 0x11
165 #define NSIP_CAUSE_UNKNOWN_IP_ENDPOINT 0x12
166 #define NSIP_CAUSE_UNKNOWN_IP_ADDRESS 0x13
167 #define NSIP_CAUSE_IP_TEST_FAILED 0x14
169 static const value_string tab_nsip_cause_values[] = {
170 { NSIP_CAUSE_TRANSIT_NETWORK_FAILURE, "Transit network failure" },
171 { NSIP_CAUSE_OM_INTERVENTION, "O&M intervention" },
172 { NSIP_CAUSE_EQUIPMENT_FAILURE, "Equipment failure" },
173 { NSIP_CAUSE_NS_VC_BLOCKED, "NS-VC blocked" },
174 { NSIP_CAUSE_NS_VC_UNKNOWN, "NS-VC unknown" },
175 { NSIP_CAUSE_BVCI_UNKNOWN, "BVCI unknown on that NSE" },
176 { NSIP_CAUSE_SEMANTICALLY_INCORRECT_PDU, "Semantically incorrect PDU" },
177 { NSIP_CAUSE_NSIP_PDU_NOT_COMPATIBLE, "PDU not compatible with the protocol state" },
178 { NSIP_CAUSE_PROTOCOL_ERROR, "Protocol error - unspecified" },
179 { NSIP_CAUSE_INVALID_ESSENTIAL_IE, "Invalid essential IE" },
180 { NSIP_CAUSE_MISSING_ESSENTIAL_IE, "Missing essential IE" },
181 { NSIP_CAUSE_INVALID_NUM_IP4_ENDPOINTS, "Invalid number of IP4 endpoints" },
182 { NSIP_CAUSE_INVALID_NUM_IP6_ENDPOINTS, "Invalid number of IP6 endpoints" },
183 { NSIP_CAUSE_INVALID_NUM_NS_VC, "Invalid number of NS-VCs" },
184 { NSIP_CAUSE_INVALID_WEIGHTS, "Invalid weights" },
185 { NSIP_CAUSE_UNKNOWN_IP_ENDPOINT, "Unknown IP endpoint" },
186 { NSIP_CAUSE_UNKNOWN_IP_ADDRESS, "Unknown IP address" },
187 { NSIP_CAUSE_IP_TEST_FAILED, "IP test failed" },
188 { 0, NULL },
191 /* Presence requirements of Information Elements
192 v 5.3.0, chapter 8.1.1, p. 35 */
193 #define NSIP_IE_PRESENCE_M 1 /* Mandatory */
194 #define NSIP_IE_PRESENCE_O 2 /* Conditional */
195 #define NSIP_IE_PRESENCE_C 3 /* Optional */
197 /* Format options */
198 #define NSIP_IE_FORMAT_V 1
199 #define NSIP_IE_FORMAT_TV 2
200 #define NSIP_IE_FORMAT_TLV 3
202 /* IP address types, v 5.3.0, chapter 10.3.2b, p. 48 */
203 #define NSIP_IP_ADDRESS_TYPE_IPV4 1
204 #define NSIP_IP_ADDRESS_TYPE_IPV6 2
205 #define NSIP_IP_VERSION_4 4
206 #define NSIP_IP_VERSION_6 6
208 static const value_string ip_address_type_vals[] = {
209 { 0, "Reserved" },
210 { NSIP_IP_ADDRESS_TYPE_IPV4, "IPv4 Address" },
211 { NSIP_IP_ADDRESS_TYPE_IPV6, "IPv6 Address" },
212 { 0, NULL },
216 #define NSIP_MASK_CONTROL_BITS_R 0x01
217 #define NSIP_MASK_CONTROL_BITS_C 0x02
218 #define NSIP_MASK_CONTROL_BITS_SPARE 0xFC
219 #define NSIP_MASK_END_FLAG 0x01
220 #define NSIP_MASK_END_FLAG_SPARE 0xFE
221 #define NSIP_MASK_RESET_FLAG 0x01
222 #define NSIP_MASK_RESET_FLAG_SPARE 0xFE
224 static dissector_handle_t bssgp_handle;
225 static dissector_handle_t nsip_handle;
227 static bool nsip_is_recursive;
229 typedef struct {
230 uint8_t iei;
231 uint8_t presence_req;
232 int format;
233 uint16_t value_length; /* in bytes */
234 uint16_t total_length; /* as specified, or 0 if unspecified */
235 } nsip_ie_t;
237 typedef struct {
238 tvbuff_t *tvb;
239 int offset;
240 packet_info *pinfo;
241 proto_tree *nsip_tree;
242 proto_tree *parent_tree;
243 proto_item *ti;
244 } build_info_t;
246 typedef struct {
247 int version;
248 int address_length;
249 int total_length;
250 } nsip_ip_element_info_t;
252 static nsip_ip_element_info_t ipv4_element = { NSIP_IP_VERSION_4, 4, 8 };
253 static nsip_ip_element_info_t ipv6_element = { NSIP_IP_VERSION_6, 16, 20 };
255 static void
256 get_value_length(nsip_ie_t *ie, build_info_t *bi) {
257 /* length indicator in bit 8, 0 => two bytes, 1 => one byte */
258 const uint8_t MASK_LENGTH_INDICATOR = 0x80;
259 const uint8_t MASK_ONE_BYTE_LENGTH = 0x7f;
260 uint8_t length_len;
261 uint16_t length;
263 length = tvb_get_uint8(bi->tvb, bi->offset);
264 length_len = 1;
266 if (length & MASK_LENGTH_INDICATOR) {
267 length &= MASK_ONE_BYTE_LENGTH;
269 else {
270 length_len++;
271 length <<= 8;
272 length |= tvb_get_uint8(bi->tvb, bi->offset+1);
274 ie->value_length = length;
275 ie->total_length += length_len + length;
276 bi->offset += length_len;
279 static int
280 check_correct_iei(nsip_ie_t *ie, build_info_t *bi) {
281 uint8_t fetched_iei = tvb_get_uint8(bi->tvb, bi->offset);
283 #if NSIP_DEBUG
284 if (fetched_iei != ie->iei) {
285 proto_tree_add_debug(bi->nsip_tree, bi->tvb, bi->offset, 1,
286 "Tried IEI %s (%#02x), found IEI %s (%#02x)",
287 val_to_str_const(ie->iei, tab_nsip_ieis, "Unknown"),
288 ie->iei,
289 val_to_str_const(fetched_iei, tab_nsip_ieis, "Unknown"),
290 fetched_iei);
292 #endif
293 return (fetched_iei == ie->iei);
296 static void
297 decode_iei_cause(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
298 uint8_t cause;
300 cause = tvb_get_uint8(bi->tvb, bi->offset);
301 proto_tree_add_uint(bi->nsip_tree, hf_nsip_cause,
302 bi->tvb, ie_start_offset, ie->total_length,
303 cause);
304 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
305 "Cause: %s",
306 val_to_str(cause, tab_nsip_cause_values, "Unknown (0x%02x)"));
308 proto_item_append_text(bi->ti, ", Cause: %s",
309 val_to_str(cause, tab_nsip_cause_values, "Unknown (0x%02x)"));
311 bi->offset += ie->value_length;
314 static void
315 decode_iei_ns_vci(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
316 uint16_t ns_vci;
318 ns_vci = tvb_get_ntohs(bi->tvb, bi->offset);
320 proto_tree_add_uint(bi->nsip_tree, hf_nsip_ns_vci,
321 bi->tvb, ie_start_offset, ie->total_length,
322 ns_vci);
323 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
324 "NS VCI: %#04x", ns_vci);
325 proto_item_append_text(bi->ti, ", NS VCI: %#04x", ns_vci);
327 bi->offset += ie->value_length;
330 static void
331 decode_iei_ns_pdu(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
332 tvbuff_t * next_tvb;
334 proto_tree_add_bytes_format(bi->nsip_tree, hf_nsip_ns_pdu, bi->tvb, ie_start_offset,
335 ie->total_length, NULL,
336 "NS PDU (%u bytes)", ie->value_length);
337 next_tvb = tvb_new_subset_length_caplen(bi->tvb, bi->offset, ie->value_length, -1);
338 if (nsip_handle) {
339 bool was_recursive;
340 was_recursive = nsip_is_recursive;
341 nsip_is_recursive = true;
342 call_dissector(nsip_handle, next_tvb, bi->pinfo, bi->nsip_tree);
343 nsip_is_recursive = was_recursive;
345 bi->offset += ie->value_length;
348 static void
349 decode_iei_nsei(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
350 uint16_t nsei = tvb_get_ntohs(bi->tvb, bi->offset);
352 proto_tree_add_uint(bi->nsip_tree, hf_nsip_nsei, bi->tvb,
353 ie_start_offset, ie->total_length, nsei);
354 bi->offset += ie->value_length;
356 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
357 "NSEI %u", nsei);
359 proto_item_append_text(bi->ti, ", NSEI %u", nsei);
362 static void
363 decode_iei_bvci(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
364 uint16_t bvci = tvb_get_ntohs(bi->tvb, bi->offset);
366 proto_tree_add_uint(bi->nsip_tree, hf_nsip_bvci, bi->tvb,
367 ie_start_offset, ie->total_length, bvci);
368 bi->offset += ie->value_length;
370 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
371 "BVCI %u", bvci);
372 proto_item_append_text(bi->ti, ", BVCI %u", bvci);
375 static proto_item *
376 decode_ip_element(nsip_ip_element_info_t *element, build_info_t *bi, proto_tree * element_tree) {
377 uint16_t udp_port;
378 proto_item *tf;
379 proto_tree *field_tree;
381 field_tree = proto_tree_add_subtree(element_tree, bi->tvb, bi->offset,
382 element->total_length, ett_nsip_ip_element, &tf, "IP Element");
383 if (bi->nsip_tree) {
385 /* IP address */
386 switch (element->version) {
387 case NSIP_IP_VERSION_4:
388 proto_tree_add_item(field_tree, hf_nsip_ip_address_ipv4,
389 bi->tvb, bi->offset, element->address_length,
390 ENC_BIG_ENDIAN);
391 proto_item_append_text(tf, ": IP address: %s",
392 tvb_ip_to_str(wmem_packet_scope(), bi->tvb, bi->offset));
394 break;
395 case NSIP_IP_VERSION_6:
396 proto_tree_add_item(field_tree, hf_nsip_ip_address_ipv6, bi->tvb,
397 bi->offset, element->address_length,
398 ENC_NA);
399 proto_item_append_text(tf, ": IP address: %s",
400 tvb_ip6_to_str(wmem_packet_scope(), bi->tvb, bi->offset));
401 break;
402 default:
406 bi->offset += element->address_length;
408 if (bi->nsip_tree) {
409 /* UDP port value */
410 udp_port = tvb_get_ntohs(bi->tvb, bi->offset);
411 proto_tree_add_item(field_tree, hf_nsip_ip_element_udp_port,
412 bi->tvb, bi->offset, 2, ENC_BIG_ENDIAN);
413 proto_item_append_text(tf, ", UDP Port: %u", udp_port);
415 bi->offset += 2;
417 if (bi->nsip_tree) {
418 /* Signalling weight */
419 proto_tree_add_item(field_tree, hf_nsip_ip_element_signalling_weight,
420 bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN);
422 bi->offset++;
424 if (bi->nsip_tree) {
425 /* Data weight */
426 proto_tree_add_item(field_tree, hf_nsip_ip_element_data_weight,
427 bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN);
429 bi->offset++;
430 return tf;
433 static proto_item *
434 decode_ip_elements(nsip_ip_element_info_t *element, nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
435 int i;
436 int num_elements = ie->value_length / element->total_length;
437 proto_item *tf;
438 proto_tree *field_tree;
440 field_tree = proto_tree_add_subtree_format(bi->nsip_tree, bi->tvb, ie_start_offset,
441 ie->total_length, ett_nsip_ip_element_list, &tf,
442 "List of IP%u Elements (%u Elements)",
443 element->version, num_elements);
445 for (i = 0; i < num_elements; i++) {
446 decode_ip_element(element, bi, field_tree);
448 return tf;
451 static void
452 decode_iei_max_num_ns_vc(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
453 uint16_t num_ns_vc;
455 if (bi->nsip_tree) {
456 num_ns_vc = tvb_get_ntohs(bi->tvb, bi->offset);
458 proto_tree_add_uint(bi->nsip_tree, hf_nsip_max_num_ns_vc,
459 bi->tvb, ie_start_offset, ie->total_length,
460 num_ns_vc);
462 bi->offset += 2;
465 static void
466 decode_iei_num_ip4_endpoints(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
467 uint16_t num_endpoints;
469 if (bi->nsip_tree) {
470 num_endpoints = tvb_get_ntohs(bi->tvb, bi->offset);
472 proto_tree_add_uint(bi->nsip_tree, hf_nsip_num_ip4_endpoints,
473 bi->tvb, ie_start_offset, ie->total_length,
474 num_endpoints);
476 bi->offset += 2;
479 static void
480 decode_iei_num_ip6_endpoints(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
481 uint16_t num_endpoints;
483 if (bi->nsip_tree) {
484 num_endpoints = tvb_get_ntohs(bi->tvb, bi->offset);
486 proto_tree_add_uint(bi->nsip_tree, hf_nsip_num_ip6_endpoints,
487 bi->tvb, ie_start_offset, ie->total_length,
488 num_endpoints);
490 bi->offset += 2;
493 static void
494 decode_iei_reset_flag(nsip_ie_t *ie _U_, build_info_t *bi, int ie_start_offset _U_) {
495 uint8_t flag;
496 static int * const reset_flags[] = {
497 &hf_nsip_reset_flag_bit,
498 &hf_nsip_reset_flag_spare,
499 NULL
502 flag = tvb_get_uint8(bi->tvb, bi->offset);
503 proto_tree_add_bitmask(bi->nsip_tree, bi->tvb, bi->offset, hf_nsip_reset_flag,
504 ett_nsip_reset_flag, reset_flags, ENC_NA);
506 if (flag & NSIP_MASK_RESET_FLAG) {
507 col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Reset");
509 bi->offset += 1;
512 static void
513 decode_iei_ip_address(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
514 uint8_t addr_type;
515 uint32_t ip4_addr;
516 ws_in6_addr ip6_addr;
518 addr_type = tvb_get_uint8(bi->tvb, bi->offset);
519 proto_tree_add_item(bi->nsip_tree, hf_nsip_ip_address_type,
520 bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN);
521 switch (addr_type) {
522 case NSIP_IP_ADDRESS_TYPE_IPV4:
523 ie->total_length = 2 + ipv4_element.address_length;
524 ip4_addr = tvb_get_ipv4(bi->tvb, bi->offset+1);
525 proto_tree_add_ipv4(bi->nsip_tree, hf_nsip_ip_address_ipv4,
526 bi->tvb, ie_start_offset, ie->total_length,
527 ip4_addr);
528 break;
529 case NSIP_IP_ADDRESS_TYPE_IPV6:
530 ie->total_length = 2 + ipv6_element.address_length;
531 tvb_get_ipv6(bi->tvb, bi->offset+1, &ip6_addr);
532 proto_tree_add_ipv6(bi->nsip_tree, hf_nsip_ip_address_ipv4,
533 bi->tvb, ie_start_offset, ie->total_length,
534 &ip6_addr);
535 break;
536 default:
537 return; /* error */
539 bi->offset += ie->value_length;
542 static void
543 decode_iei_transaction_id(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
544 uint8_t id;
545 id = tvb_get_uint8(bi->tvb, bi->offset);
546 proto_tree_add_uint(bi->nsip_tree, hf_nsip_transaction_id,
547 bi->tvb, ie_start_offset, ie->total_length, id);
548 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
549 "Transaction Id: %d", id);
550 bi->offset += 1;
553 static void
554 decode_iei_end_flag(nsip_ie_t *ie _U_, build_info_t *bi, int ie_start_offset) {
555 static int * const end_flags[] = {
556 &hf_nsip_end_flag_bit,
557 &hf_nsip_end_flag_spare,
558 NULL
561 proto_tree_add_bitmask(bi->nsip_tree, bi->tvb, ie_start_offset, hf_nsip_end_flag,
562 ett_nsip_end_flag, end_flags, ENC_NA);
563 bi->offset += 1;
566 static void
567 decode_iei_control_bits(nsip_ie_t *ie _U_, build_info_t *bi, int ie_start_offset) {
568 uint8_t control_bits;
569 static int * const flags[] = {
570 &hf_nsip_control_bits_r,
571 &hf_nsip_control_bits_c,
572 &hf_nsip_control_bits_spare,
573 NULL
576 control_bits = tvb_get_uint8(bi->tvb, bi->offset);
577 proto_tree_add_bitmask(bi->nsip_tree, bi->tvb, ie_start_offset, hf_nsip_control_bits,
578 ett_nsip_control_bits, flags, ENC_NA);
579 bi->offset++;
581 if (control_bits & NSIP_MASK_CONTROL_BITS_R) {
582 col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Req CF");
583 proto_item_append_text(bi->ti, ", Request Change Flow");
586 if (control_bits & NSIP_MASK_CONTROL_BITS_C) {
587 col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Conf CF");
588 proto_item_append_text(bi->ti, ", Confirm Change Flow");
593 static void
594 decode_ie(nsip_ie_t *ie, build_info_t *bi) {
596 int org_offset = bi->offset;
598 if (tvb_captured_length_remaining(bi->tvb, bi->offset) < 1) {
599 return;
601 switch (ie->format) {
602 case NSIP_IE_FORMAT_TLV:
603 if (!check_correct_iei(ie, bi)) {
604 return;
606 bi->offset++; /* Account for type */
607 ie->total_length = 1;
608 get_value_length(ie, bi);
609 break;
610 case NSIP_IE_FORMAT_TV:
611 if (!check_correct_iei(ie, bi)) {
612 return;
614 bi->offset++; /* Account for type */
615 ie->value_length = ie->total_length - 1;
616 break;
617 case NSIP_IE_FORMAT_V:
618 ie->value_length = ie->total_length;
619 default:
622 switch (ie->iei) {
623 case NSIP_IE_CAUSE:
624 decode_iei_cause(ie, bi, org_offset);
625 break;
626 case NSIP_IE_NS_VCI:
627 decode_iei_ns_vci(ie, bi, org_offset);
628 break;
629 case NSIP_IE_NS_PDU:
630 decode_iei_ns_pdu(ie, bi, org_offset);
631 break;
632 case NSIP_IE_NSEI:
633 decode_iei_nsei(ie, bi, org_offset);
634 break;
635 case NSIP_IE_BVCI:
636 decode_iei_bvci(ie, bi, org_offset);
637 break;
638 case NSIP_IE_IP4_ELEMENTS:
639 decode_ip_elements(&ipv4_element, ie, bi, org_offset);
640 break;
641 case NSIP_IE_IP6_ELEMENTS:
642 decode_ip_elements(&ipv6_element, ie, bi, org_offset);
643 break;
644 case NSIP_IE_MAX_NUM_NS_VC:
645 decode_iei_max_num_ns_vc(ie, bi, org_offset);
646 break;
647 case NSIP_IE_NUM_IP4_ENDPOINTS:
648 decode_iei_num_ip4_endpoints(ie, bi, org_offset);
649 break;
650 case NSIP_IE_NUM_IP6_ENDPOINTS:
651 decode_iei_num_ip6_endpoints(ie, bi, org_offset);
652 break;
653 case NSIP_IE_RESET_FLAG:
654 decode_iei_reset_flag(ie, bi, org_offset);
655 break;
656 case NSIP_IE_IP_ADDRESS:
657 decode_iei_ip_address(ie, bi, org_offset);
658 break;
659 default:
664 static void
665 decode_pdu_general(nsip_ie_t *ies, int num_ies, build_info_t *bi) {
666 int i;
667 for (i = 0; i < num_ies; i++) {
668 decode_ie(&ies[i], bi);
672 static void
673 decode_pdu_ns_unitdata(build_info_t *bi) {
674 tvbuff_t *next_tvb;
676 nsip_ie_t ies[] = {
677 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Control bits */
678 { NSIP_IE_BVCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 2 },
679 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 0 },
680 /* NS SDU, length unknown */
682 int sdu_length;
684 decode_iei_control_bits(ies, bi, bi->offset);
685 decode_pdu_general(&ies[1], 1, bi);
687 next_tvb = tvb_new_subset_remaining(bi->tvb, bi->offset);
688 if (bssgp_handle) {
689 call_dissector(bssgp_handle, next_tvb, bi->pinfo, bi->parent_tree);
691 else {
692 sdu_length = tvb_captured_length_remaining(bi->tvb, bi->offset);
693 proto_tree_add_bytes_format(bi->nsip_tree, hf_nsip_ns_sdu, bi->tvb, bi->offset, sdu_length,
694 NULL, "NS SDU (%u bytes)", sdu_length);
698 static void
699 decode_pdu_ns_reset(build_info_t *bi) {
700 nsip_ie_t ies[] = {
701 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 3 },
702 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
703 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
705 decode_pdu_general(ies, 3, bi);
708 static void
709 decode_pdu_ns_reset_ack(build_info_t *bi) {
710 nsip_ie_t ies[] = {
711 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
712 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
714 decode_pdu_general(ies, 2, bi);
717 static void
718 decode_pdu_ns_block(build_info_t *bi) {
719 nsip_ie_t ies[] = {
720 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 3 },
721 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
723 decode_pdu_general(ies, 2, bi);
726 static void
727 decode_pdu_ns_block_ack(build_info_t *bi) {
728 nsip_ie_t ies[] = { { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV,
729 0, 1 }, };
730 decode_pdu_general(ies, 1, bi);
733 static void
734 decode_pdu_ns_status(build_info_t *bi) {
735 nsip_ie_t ies[] = {
736 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 3 },
737 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
738 { NSIP_IE_NS_PDU, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
739 /* Unknown length */
740 { NSIP_IE_BVCI, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 4 },
741 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
742 /* Unknown length */
743 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
744 /* Unknown length */
746 decode_pdu_general(ies, 6, bi);
749 static void
750 decode_pdu_sns_ack(build_info_t *bi) {
751 nsip_ie_t ies[] = {
752 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
753 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
754 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 3 },
755 { NSIP_IE_IP_ADDRESS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV, 0, 0 },
756 /* Unknown length */
757 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
758 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
760 decode_pdu_general(ies, 1, bi);
761 decode_iei_transaction_id(&ies[1], bi, bi->offset);
762 decode_pdu_general(&ies[2], 4, bi);
765 static void
766 decode_pdu_sns_add(build_info_t *bi) {
767 nsip_ie_t ies[] = {
768 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
769 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
770 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
771 /* Unknown length */
772 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
773 /* Unknown length */
775 decode_pdu_general(ies, 1, bi);
776 decode_iei_transaction_id(&ies[1], bi, bi->offset);
777 decode_pdu_general(&ies[2], 2, bi);
780 static void
781 decode_pdu_sns_changeweight(build_info_t *bi) {
782 nsip_ie_t ies[] = {
783 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
784 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
785 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
786 /* Unknown length */
787 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
788 /* Unknown length */
790 decode_pdu_general(ies, 1, bi);
791 decode_iei_transaction_id(&ies[1], bi, bi->offset);
792 decode_pdu_general(&ies[2], 2, bi);
795 static void
796 decode_pdu_sns_config(build_info_t *bi) {
798 nsip_ie_t ies[] = {
799 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* End flag */
800 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
801 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
802 /* Unknown length */
803 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
804 /* Unknown length */
806 decode_iei_end_flag(ies, bi, bi->offset);
807 decode_pdu_general(&ies[1], 3, bi);
810 static void
811 decode_pdu_sns_config_ack(build_info_t *bi) {
812 nsip_ie_t ies[] = {
813 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
814 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 3 },
816 decode_pdu_general(ies, 2, bi);
819 static void
820 decode_pdu_sns_delete(build_info_t *bi) {
821 nsip_ie_t ies[] = {
822 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4}, /* CR013 */
823 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
824 { NSIP_IE_IP_ADDRESS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV, 0, 0 },
825 /* Unknown length */
826 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
827 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
829 decode_pdu_general(ies, 1, bi);
830 decode_iei_transaction_id(&ies[1], bi, bi->offset);
831 decode_pdu_general(&ies[2], 3, bi);
834 static void
835 decode_pdu_sns_size(build_info_t *bi) {
836 nsip_ie_t ies[] = {
837 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
838 { NSIP_IE_RESET_FLAG, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TV, 0, 2 },
839 { NSIP_IE_MAX_NUM_NS_VC, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TV, 0, 3 },
840 { NSIP_IE_NUM_IP4_ENDPOINTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV,
841 0, 3 },
842 { NSIP_IE_NUM_IP6_ENDPOINTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV,
843 0, 3 },
845 decode_pdu_general(ies, 5, bi);
848 static void
849 decode_pdu_sns_size_ack(build_info_t *bi) {
850 nsip_ie_t ies[] = {
851 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
852 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 3 },
854 decode_pdu_general(ies, 2, bi);
857 static void
858 decode_pdu(uint8_t pdu_type, build_info_t *bi, packet_info *pinfo) {
859 switch (pdu_type) {
860 case NSIP_PDU_NS_UNITDATA:
861 decode_pdu_ns_unitdata(bi);
862 break;
863 case NSIP_PDU_NS_RESET:
864 decode_pdu_ns_reset(bi);
865 break;
866 case NSIP_PDU_NS_RESET_ACK:
867 decode_pdu_ns_reset_ack(bi);
868 break;
869 case NSIP_PDU_NS_BLOCK:
870 decode_pdu_ns_block(bi);
871 break;
872 case NSIP_PDU_NS_BLOCK_ACK:
873 decode_pdu_ns_block_ack(bi);
874 break;
875 case NSIP_PDU_NS_STATUS:
876 pinfo->flags.in_error_pkt = true;
877 decode_pdu_ns_status(bi);
878 break;
879 case NSIP_PDU_SNS_ACK:
880 decode_pdu_sns_ack(bi);
881 break;
882 case NSIP_PDU_SNS_ADD:
883 decode_pdu_sns_add(bi);
884 break;
885 case NSIP_PDU_SNS_CHANGEWEIGHT:
886 decode_pdu_sns_changeweight(bi);
887 break;
888 case NSIP_PDU_SNS_CONFIG:
889 decode_pdu_sns_config(bi);
890 break;
891 case NSIP_PDU_SNS_CONFIG_ACK:
892 decode_pdu_sns_config_ack(bi);
893 break;
894 case NSIP_PDU_SNS_DELETE:
895 decode_pdu_sns_delete(bi);
896 break;
897 case NSIP_PDU_SNS_SIZE:
898 decode_pdu_sns_size(bi);
899 break;
900 case NSIP_PDU_SNS_SIZE_ACK:
901 decode_pdu_sns_size_ack(bi);
902 break;
903 case NSIP_PDU_NS_ALIVE:
904 case NSIP_PDU_NS_ALIVE_ACK:
905 case NSIP_PDU_NS_UNBLOCK:
906 case NSIP_PDU_NS_UNBLOCK_ACK:
907 /* Only contains PDU type, which has already been decoded */
908 default: ;
912 static int
913 dissect_nsip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
914 uint8_t pdu_type;
915 build_info_t bi = { NULL, 0, NULL, NULL, NULL, NULL };
916 proto_tree *nsip_tree;
918 bi.tvb = tvb;
919 bi.pinfo = pinfo;
920 bi.parent_tree = tree;
922 if (!nsip_is_recursive) {
923 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GPRS-NS");
924 col_clear(pinfo->cinfo, COL_INFO);
927 pdu_type = tvb_get_uint8(tvb, 0);
928 bi.offset++;
930 if (tree) {
931 bi.ti = proto_tree_add_item(tree, proto_nsip, tvb, 0, -1,
932 ENC_NA);
933 nsip_tree = proto_item_add_subtree(bi.ti, ett_nsip);
934 proto_tree_add_item(nsip_tree, hf_nsip_pdu_type, tvb, 0, 1, ENC_BIG_ENDIAN);
935 proto_item_append_text(bi.ti, ", PDU type: %s",
936 val_to_str_const(pdu_type, tab_nsip_pdu_types, "Unknown"));
937 bi.nsip_tree = nsip_tree;
940 if (!nsip_is_recursive) {
941 col_set_str(pinfo->cinfo, COL_INFO,
942 val_to_str_const(pdu_type, tab_nsip_pdu_types, "Unknown PDU type"));
943 } else {
944 col_append_sep_str(pinfo->cinfo, COL_INFO, NSIP_SEP,
945 val_to_str_const(pdu_type, tab_nsip_pdu_types, "Unknown PDU type"));
947 decode_pdu(pdu_type, &bi, pinfo);
948 return tvb_captured_length(tvb);
951 void
952 proto_register_nsip(void)
954 static hf_register_info hf[] = {
955 { &hf_nsip_cause,
956 { "Cause", "nsip.cause",
957 FT_UINT8, BASE_HEX, VALS(tab_nsip_cause_values), 0x0,
958 NULL, HFILL }
960 { &hf_nsip_ns_vci,
961 { "NS-VCI", "nsip.ns_vci",
962 FT_UINT16, BASE_HEX, NULL, 0x0,
963 "Network Service Virtual Link Identifier", HFILL }
965 { &hf_nsip_pdu_type,
966 { "PDU type", "nsip.pdu_type",
967 FT_UINT8, BASE_HEX, VALS(tab_nsip_pdu_types), 0x0,
968 "PDU type information element", HFILL }
970 { &hf_nsip_bvci,
971 { "BVCI", "nsip.bvci",
972 FT_UINT16, BASE_DEC, NULL, 0x0,
973 "BSSGP Virtual Connection Identifier", HFILL }
975 { &hf_nsip_nsei,
976 { "NSEI", "nsip.nsei",
977 FT_UINT16, BASE_DEC, NULL, 0x0,
978 "Network Service Entity Identifier", HFILL }
980 #if 0
981 { &hf_nsip_ip4_elements,
982 { "IP4 elements", "nsip.ip4_elements",
983 FT_NONE, BASE_NONE, NULL, 0x0,
984 "List of IP4 elements", HFILL }
986 #endif
987 #if 0
988 { &hf_nsip_ip6_elements,
989 { "IP6 elements", "nsip.ip6_elements",
990 FT_NONE, BASE_NONE, NULL, 0x0,
991 "List of IP6 elements", HFILL }
993 #endif
994 { &hf_nsip_max_num_ns_vc,
995 { "Maximum number of NS-VCs", "nsip.max_num_ns_vc",
996 FT_UINT16, BASE_DEC, NULL, 0x0,
997 NULL, HFILL }
999 { &hf_nsip_num_ip4_endpoints,
1000 { "Number of IP4 endpoints", "nsip.num_ip4_endpoints",
1001 FT_UINT16, BASE_DEC, NULL, 0x0,
1002 NULL, HFILL }
1004 { &hf_nsip_num_ip6_endpoints,
1005 { "Number of IP6 endpoints", "nsip.num_ip6_endpoints",
1006 FT_UINT16, BASE_DEC, NULL, 0x0,
1007 NULL, HFILL }
1009 { &hf_nsip_reset_flag,
1010 { "Reset flag", "nsip.reset_flag",
1011 FT_UINT8, BASE_HEX, NULL, 0,
1012 NULL, HFILL }
1014 { &hf_nsip_reset_flag_bit,
1015 { "Reset flag", "nsip.reset_flag.flag",
1016 FT_BOOLEAN, 8, TFS(&tfs_set_notset), NSIP_MASK_RESET_FLAG,
1017 NULL, HFILL }
1019 { &hf_nsip_reset_flag_spare,
1020 { "Reset flag spare bits", "nsip.reset_flag.spare",
1021 FT_UINT8, BASE_HEX, NULL, NSIP_MASK_RESET_FLAG_SPARE,
1022 NULL, HFILL }
1024 { &hf_nsip_ip_address_type,
1025 { "IP Address Type", "nsip.ip_address_type",
1026 FT_UINT8, BASE_DEC, VALS(ip_address_type_vals), 0x0,
1027 NULL, HFILL }
1029 { &hf_nsip_ip_address_ipv4,
1030 { "IP Address", "nsip.ipv4_address",
1031 FT_IPv4, BASE_NONE, NULL, 0x0,
1032 NULL, HFILL }
1034 { &hf_nsip_ip_address_ipv6,
1035 { "IP Address", "nsip.ipv6_address",
1036 FT_IPv6, BASE_NONE, NULL, 0x0,
1037 NULL, HFILL }
1039 { &hf_nsip_end_flag,
1040 { "End flag", "nsip.end_flag",
1041 FT_UINT8, BASE_HEX, NULL, 0x0,
1042 NULL, HFILL }
1044 { &hf_nsip_end_flag_bit,
1045 { "End flag", "nsip.end_flag.flag",
1046 FT_BOOLEAN, 8, TFS(&tfs_set_notset), NSIP_MASK_END_FLAG,
1047 NULL, HFILL }
1049 { &hf_nsip_end_flag_spare,
1050 { "End flag spare bits", "nsip.end_flag.spare",
1051 FT_UINT8, BASE_HEX, NULL, NSIP_MASK_END_FLAG_SPARE,
1052 NULL, HFILL }
1054 { &hf_nsip_control_bits,
1055 { "NS SDU Control bits", "nsip.control_bits",
1056 FT_UINT8, BASE_HEX, NULL, 0x0,
1057 NULL, HFILL }
1059 { &hf_nsip_control_bits_r,
1060 { "Request change flow", "nsip.control_bits.r",
1061 FT_BOOLEAN, 8, TFS(&tfs_set_notset), NSIP_MASK_CONTROL_BITS_R,
1062 NULL, HFILL }
1064 { &hf_nsip_control_bits_c,
1065 { "Confirm change flow", "nsip.control_bits.c",
1066 FT_BOOLEAN, 8, TFS(&tfs_set_notset), NSIP_MASK_CONTROL_BITS_C,
1067 NULL, HFILL }
1069 { &hf_nsip_control_bits_spare,
1070 { "Spare bits", "nsip.control_bits.spare",
1071 FT_UINT8, BASE_HEX, NULL, NSIP_MASK_CONTROL_BITS_SPARE,
1072 NULL, HFILL }
1074 { &hf_nsip_transaction_id,
1075 { "Transaction ID", "nsip.transaction_id",
1076 FT_UINT8, BASE_DEC, NULL, 0x0,
1077 NULL, HFILL }
1079 #if 0
1080 { &hf_nsip_ip_element_ip_address_ipv4,
1081 { "IP Address", "nsip.ip_element.ipv4_address",
1082 FT_IPv4, BASE_NONE, NULL, 0x0,
1083 NULL, HFILL }
1085 #endif
1086 #if 0
1087 { &hf_nsip_ip_element_ip_address_ipv6,
1088 { "IP Address", "nsip.ip_element.ipv6_address",
1089 FT_IPv6, BASE_NONE, NULL, 0x0,
1090 NULL, HFILL }
1092 #endif
1093 { &hf_nsip_ip_element_udp_port,
1094 { "UDP Port", "nsip.ip_element.udp_port",
1095 FT_UINT16, BASE_DEC, NULL, 0x0,
1096 NULL, HFILL }
1098 { &hf_nsip_ip_element_signalling_weight,
1099 { "Signalling Weight", "nsip.ip_element.signalling_weight",
1100 FT_UINT8, BASE_DEC, NULL, 0x0,
1101 NULL, HFILL }
1103 { &hf_nsip_ip_element_data_weight,
1104 { "Data Weight", "nsip.ip_element.data_weight",
1105 FT_UINT8, BASE_DEC, NULL, 0x0,
1106 NULL, HFILL }
1108 { &hf_nsip_ns_pdu,
1109 { "NS PDU", "nsip.ns_pdu",
1110 FT_BYTES, BASE_NONE, NULL, 0x0,
1111 NULL, HFILL }
1113 { &hf_nsip_ns_sdu,
1114 { "NS SDU", "nsip.ns_sdu",
1115 FT_BYTES, BASE_NONE, NULL, 0x0,
1116 NULL, HFILL }
1120 /* Setup protocol subtree array */
1121 static int *ett[] = {
1122 &ett_nsip,
1123 &ett_nsip_control_bits,
1124 &ett_nsip_reset_flag,
1125 &ett_nsip_end_flag,
1126 &ett_nsip_ip_element,
1127 &ett_nsip_ip_element_list,
1130 module_t *nsip_module;
1132 /* Register the protocol name and description */
1133 proto_nsip = proto_register_protocol("GPRS Network Service", "GPRS-NS", "gprs-ns");
1135 /* Required function calls to register the header fields and
1136 subtrees used */
1137 proto_register_field_array(proto_nsip, hf, array_length(hf));
1138 proto_register_subtree_array(ett, array_length(ett));
1140 register_dissector("gprs_ns", dissect_nsip, proto_nsip);
1142 /* Register configuration options */
1143 nsip_module = prefs_register_protocol(proto_nsip, NULL);
1144 /* For reading older preference files with "nsip." preferences */
1145 prefs_register_module_alias("nsip", nsip_module);
1146 prefs_register_obsolete_preference(nsip_module, "udp.port1");
1147 prefs_register_obsolete_preference(nsip_module, "udp.port2");
1150 void
1151 proto_reg_handoff_nsip(void) {
1153 nsip_handle = find_dissector_add_dependency("gprs_ns", proto_nsip);
1154 bssgp_handle = find_dissector_add_dependency("bssgp", proto_nsip);
1156 dissector_add_uint_range_with_preference("udp.port", DEFAULT_NSIP_PORT_RANGE, nsip_handle);
1157 dissector_add_uint("atm.aal5.type", TRAF_GPRS_NS, nsip_handle);
1162 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1164 * Local variables:
1165 * c-basic-offset: 2
1166 * tab-width: 8
1167 * indent-tabs-mode: nil
1168 * End:
1170 * vi: set shiftwidth=2 tabstop=8 expandtab:
1171 * :indentSize=2:tabSize=8:noTabs=true: