HACK: 2nd try to match RowsetProperties
[wireshark-wip.git] / epan / dissectors / packet-nsip.c
blob22b475bb824321fb4cf320987193a0cbf2d9aaa9
1 /* packet-nsip.c
2 * Routines for Network Service Over IP dissection
3 * Copyright 2000, Susanne Edlund <susanne.edlund@ericsson.com>
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 /* 3GPP TS 48.016 V 5.3.0 (2004-07) Release 6 + CR013 */
28 #include "config.h"
30 #include <epan/packet.h>
32 #include <prefs.h>
34 #define NSIP_DEBUG 0
35 #define NSIP_SEP ", " /* Separator string */
37 static range_t *global_nsip_udp_port_range;
38 #define DEFAULT_NSIP_PORT_RANGE "2157,19999"
40 void proto_reg_handoff_nsip(void);
42 /* Initialize the protocol and registered fields */
43 static int proto_nsip = -1;
45 static int hf_nsip_cause = -1;
46 static int hf_nsip_ns_vci = -1;
47 static int hf_nsip_pdu_type = -1;
48 static int hf_nsip_bvci = -1;
49 static int hf_nsip_nsei = -1;
50 /* static int hf_nsip_ip4_elements = -1; */
51 /* static int hf_nsip_ip6_elements = -1; */
52 static int hf_nsip_max_num_ns_vc = -1;
53 static int hf_nsip_num_ip4_endpoints = -1;
54 static int hf_nsip_num_ip6_endpoints = -1;
55 static int hf_nsip_reset_flag = -1;
56 static int hf_nsip_reset_flag_spare = -1;
57 static int hf_nsip_ip_address_type = -1;
58 static int hf_nsip_ip_address_ipv4 = -1;
59 static int hf_nsip_ip_address_ipv6 = -1;
60 static int hf_nsip_end_flag = -1;
61 static int hf_nsip_end_flag_spare = -1;
62 static int hf_nsip_control_bits_r = -1;
63 static int hf_nsip_control_bits_c = -1;
64 static int hf_nsip_control_bits_spare = -1;
65 static int hf_nsip_transaction_id = -1;
66 /* static int hf_nsip_ip_element_ip_address_ipv4 = -1; */
67 /* static int hf_nsip_ip_element_ip_address_ipv6 = -1; */
68 static int hf_nsip_ip_element_udp_port = -1;
69 static int hf_nsip_ip_element_signalling_weight = -1;
70 static int hf_nsip_ip_element_data_weight = -1;
73 /* Initialize the subtree pointers */
74 static gint ett_nsip = -1;
75 static gint ett_nsip_control_bits = -1;
76 static gint ett_nsip_reset_flag = -1;
77 static gint ett_nsip_end_flag = -1;
78 static gint ett_nsip_ip_element = -1;
79 static gint ett_nsip_ip_element_list = -1;
81 /* PDU type coding, v5.3.0, table 10.3.7.1, p 51 */
82 #define NSIP_PDU_NS_UNITDATA 0x00
83 #define NSIP_PDU_NS_RESET 0x02
84 #define NSIP_PDU_NS_RESET_ACK 0x03
85 #define NSIP_PDU_NS_BLOCK 0x04
86 #define NSIP_PDU_NS_BLOCK_ACK 0x05
87 #define NSIP_PDU_NS_UNBLOCK 0x06
88 #define NSIP_PDU_NS_UNBLOCK_ACK 0x07
89 #define NSIP_PDU_NS_STATUS 0x08
90 #define NSIP_PDU_NS_ALIVE 0x0a
91 #define NSIP_PDU_NS_ALIVE_ACK 0x0b
92 #define NSIP_PDU_SNS_ACK 0x0c
93 #define NSIP_PDU_SNS_ADD 0x0d
94 #define NSIP_PDU_SNS_CHANGEWEIGHT 0x0e
95 #define NSIP_PDU_SNS_CONFIG 0x0f
96 #define NSIP_PDU_SNS_CONFIG_ACK 0x10
97 #define NSIP_PDU_SNS_DELETE 0x11
98 #define NSIP_PDU_SNS_SIZE 0x12
99 #define NSIP_PDU_SNS_SIZE_ACK 0x13
101 static const value_string tab_nsip_pdu_types[] = {
102 { NSIP_PDU_NS_UNITDATA, "NS_UNITDATA" },
103 { NSIP_PDU_NS_RESET, "NS_RESET" },
104 { NSIP_PDU_NS_RESET_ACK, "NS_RESET_ACK" },
105 { NSIP_PDU_NS_BLOCK, "NS_BLOCK" },
106 { NSIP_PDU_NS_BLOCK_ACK, "NS_BLOCK_ACK" },
107 { NSIP_PDU_NS_UNBLOCK, "NS_UNBLOCK" },
108 { NSIP_PDU_NS_UNBLOCK_ACK, "NS_UNBLOCK_ACK" },
109 { NSIP_PDU_NS_STATUS, "NS_STATUS" },
110 { NSIP_PDU_NS_ALIVE, "NS_ALIVE" },
111 { NSIP_PDU_NS_ALIVE_ACK, "NS_ALIVE_ACK" },
112 { NSIP_PDU_SNS_ACK, "SNS_ACK" },
113 { NSIP_PDU_SNS_ADD, "SNS_ADD" },
114 { NSIP_PDU_SNS_CHANGEWEIGHT, "SNS_CHANGEWEIGHT" },
115 { NSIP_PDU_SNS_CONFIG, "SNS_CONFIG" },
116 { NSIP_PDU_SNS_CONFIG_ACK, "SNS_CONFIG_ACK" },
117 { NSIP_PDU_SNS_DELETE, "SNS_DELETE" },
118 { NSIP_PDU_SNS_SIZE, "SNS_SIZE" },
119 { NSIP_PDU_SNS_SIZE_ACK, "SNS_SIZE_ACK" },
120 { 0, NULL },
123 /* Information element coding, v 5.3.0, table 10.3.1, p 46 */
124 #define NSIP_IE_CAUSE 0x00
125 #define NSIP_IE_NS_VCI 0x01
126 #define NSIP_IE_NS_PDU 0x02
127 #define NSIP_IE_BVCI 0x03
128 #define NSIP_IE_NSEI 0x04
129 #define NSIP_IE_IP4_ELEMENTS 0x05
130 #define NSIP_IE_IP6_ELEMENTS 0x06
131 #define NSIP_IE_MAX_NUM_NS_VC 0x07
132 #define NSIP_IE_NUM_IP4_ENDPOINTS 0x08
133 #define NSIP_IE_NUM_IP6_ENDPOINTS 0x09
134 #define NSIP_IE_RESET_FLAG 0x0a
135 #define NSIP_IE_IP_ADDRESS 0x0b
137 #if NSIP_DEBUG
138 static const value_string tab_nsip_ieis[] = {
139 { NSIP_IE_CAUSE, "Cause" },
140 { NSIP_IE_NS_VCI, "NS-VCI" },
141 { NSIP_IE_NS_PDU, "NS PDU" },
142 { NSIP_IE_BVCI, "BVCI" },
143 { NSIP_IE_NSEI, "NSEI" },
144 { NSIP_IE_IP4_ELEMENTS, "List of IP4 Elements" },
145 { NSIP_IE_IP6_ELEMENTS, "List of IP6 Elements" },
146 { NSIP_IE_MAX_NUM_NS_VC, "Maximum Number of NC-VCs" },
147 { NSIP_IE_NUM_IP4_ENDPOINTS, "Number of IP4 Endpoints" },
148 { NSIP_IE_NUM_IP6_ENDPOINTS, "Number of IP6 Endpoints"},
149 { NSIP_IE_RESET_FLAG, "Reset Flag" },
150 { NSIP_IE_IP_ADDRESS, "IP Address" },
151 { 0, NULL },
153 #endif
155 /* Cause values, v 5.3.0, table 10.3.2.1, p 47 */
156 #define NSIP_CAUSE_TRANSIT_NETWORK_FAILURE 0x00
157 #define NSIP_CAUSE_OM_INTERVENTION 0x01
158 #define NSIP_CAUSE_EQUIPMENT_FAILURE 0x02
159 #define NSIP_CAUSE_NS_VC_BLOCKED 0x03
160 #define NSIP_CAUSE_NS_VC_UNKNOWN 0x04
161 #define NSIP_CAUSE_BVCI_UNKNOWN 0x05
162 #define NSIP_CAUSE_SEMANTICALLY_INCORRECT_PDU 0x08
163 #define NSIP_CAUSE_NSIP_PDU_NOT_COMPATIBLE 0x0a
164 #define NSIP_CAUSE_PROTOCOL_ERROR 0x0b
165 #define NSIP_CAUSE_INVALID_ESSENTIAL_IE 0x0c
166 #define NSIP_CAUSE_MISSING_ESSENTIAL_IE 0x0d
167 #define NSIP_CAUSE_INVALID_NUM_IP4_ENDPOINTS 0x0e
168 #define NSIP_CAUSE_INVALID_NUM_IP6_ENDPOINTS 0x0f
169 #define NSIP_CAUSE_INVALID_NUM_NS_VC 0x10
170 #define NSIP_CAUSE_INVALID_WEIGHTS 0x11
171 #define NSIP_CAUSE_UNKNOWN_IP_ENDPOINT 0x12
172 #define NSIP_CAUSE_UNKNOWN_IP_ADDRESS 0x13
173 #define NSIP_CAUSE_IP_TEST_FAILED 0x14
175 static const value_string tab_nsip_cause_values[] = {
176 { NSIP_CAUSE_TRANSIT_NETWORK_FAILURE, "Transit network failure" },
177 { NSIP_CAUSE_OM_INTERVENTION, "O&M intervention" },
178 { NSIP_CAUSE_EQUIPMENT_FAILURE, "Equipment failure" },
179 { NSIP_CAUSE_NS_VC_BLOCKED, "NS-VC blocked" },
180 { NSIP_CAUSE_NS_VC_UNKNOWN, "NS-VC unknown" },
181 { NSIP_CAUSE_BVCI_UNKNOWN, "BVCI unknown on that NSE" },
182 { NSIP_CAUSE_SEMANTICALLY_INCORRECT_PDU, "Semantically incorrect PDU" },
183 { NSIP_CAUSE_NSIP_PDU_NOT_COMPATIBLE, "PDU not compatible with the protocol state" },
184 { NSIP_CAUSE_PROTOCOL_ERROR, "Protocol error - unspecified" },
185 { NSIP_CAUSE_INVALID_ESSENTIAL_IE, "Invalid essential IE" },
186 { NSIP_CAUSE_MISSING_ESSENTIAL_IE, "Missing essential IE" },
187 { NSIP_CAUSE_INVALID_NUM_IP4_ENDPOINTS, "Invalid number of IP4 endpoints" },
188 { NSIP_CAUSE_INVALID_NUM_IP6_ENDPOINTS, "Invalid number of IP6 endpoints" },
189 { NSIP_CAUSE_INVALID_NUM_NS_VC, "Invalid number of NS-VCs" },
190 { NSIP_CAUSE_INVALID_WEIGHTS, "Invalid weights" },
191 { NSIP_CAUSE_UNKNOWN_IP_ENDPOINT, "Unknown IP endpoint" },
192 { NSIP_CAUSE_UNKNOWN_IP_ADDRESS, "Unknown IP address" },
193 { NSIP_CAUSE_IP_TEST_FAILED, "IP test failed" },
194 { 0, NULL },
197 /* Presence requirements of Information Elements
198 v 5.3.0, chapter 8.1.1, p. 35 */
199 #define NSIP_IE_PRESENCE_M 1 /* Mandatory */
200 #define NSIP_IE_PRESENCE_O 2 /* Conditional */
201 #define NSIP_IE_PRESENCE_C 3 /* Optional */
203 /* Format options */
204 #define NSIP_IE_FORMAT_V 1
205 #define NSIP_IE_FORMAT_TV 2
206 #define NSIP_IE_FORMAT_TLV 3
208 /* IP address types, v 5.3.0, chapter 10.3.2b, p. 48 */
209 #define NSIP_IP_ADDRESS_TYPE_IPV4 1
210 #define NSIP_IP_ADDRESS_TYPE_IPV6 2
211 #define NSIP_IP_VERSION_4 4
212 #define NSIP_IP_VERSION_6 6
214 static const value_string ip_address_type_vals[] = {
215 { 0, "Reserved" },
216 { NSIP_IP_ADDRESS_TYPE_IPV4, "IPv4 Address" },
217 { NSIP_IP_ADDRESS_TYPE_IPV6, "IPv6 Address" },
218 { 0, NULL },
222 #define NSIP_MASK_CONTROL_BITS_R 0x01
223 #define NSIP_MASK_CONTROL_BITS_C 0x02
224 #define NSIP_MASK_CONTROL_BITS_SPARE 0xFC
225 #define NSIP_MASK_END_FLAG 0x01
226 #define NSIP_MASK_END_FLAG_SPARE 0xFE
227 #define NSIP_MASK_RESET_FLAG 0x01
228 #define NSIP_MASK_RESET_FLAG_SPARE 0xFE
230 static dissector_handle_t bssgp_handle;
231 static dissector_handle_t nsip_handle;
233 static gboolean nsip_is_recursive = FALSE;
235 typedef struct {
236 guint8 iei;
237 guint8 presence_req;
238 int format;
239 guint16 value_length; /* in bytes */
240 guint16 total_length; /* as specified, or 0 if unspecified */
241 } nsip_ie_t;
243 typedef struct {
244 tvbuff_t *tvb;
245 int offset;
246 packet_info *pinfo;
247 proto_tree *nsip_tree;
248 proto_tree *parent_tree;
249 proto_item *ti;
250 } build_info_t;
252 typedef struct {
253 int version;
254 int address_length;
255 int total_length;
256 } nsip_ip_element_info_t;
258 static nsip_ip_element_info_t ipv4_element = { NSIP_IP_VERSION_4, 4, 8 };
259 static nsip_ip_element_info_t ipv6_element = { NSIP_IP_VERSION_6, 16, 20 };
261 static void
262 get_value_length(nsip_ie_t *ie, build_info_t *bi) {
263 /* length indicator in bit 8, 0 => two bytes, 1 => one byte */
264 const guint8 MASK_LENGTH_INDICATOR = 0x80;
265 const guint8 MASK_ONE_BYTE_LENGTH = 0x7f;
266 guint8 length_len;
267 guint16 length;
269 length = tvb_get_guint8(bi->tvb, bi->offset);
270 length_len = 1;
272 if (length & MASK_LENGTH_INDICATOR) {
273 length &= MASK_ONE_BYTE_LENGTH;
275 else {
276 length_len++;
277 length <<= 8;
278 length |= tvb_get_guint8(bi->tvb, bi->offset+1);
280 ie->value_length = length;
281 ie->total_length += length_len + length;
282 bi->offset += length_len;
285 static int
286 check_correct_iei(nsip_ie_t *ie, build_info_t *bi) {
287 guint8 fetched_iei = tvb_get_guint8(bi->tvb, bi->offset);
289 #if NSIP_DEBUG
290 if (fetched_iei != ie->iei) {
291 proto_tree_add_text(bi->nsip_tree, bi->tvb, bi->offset, 1,
292 "Tried IEI %s (%#02x), found IEI %s (%#02x)",
293 val_to_str_const(ie->iei, tab_nsip_ieis, "Unknown"),
294 ie->iei,
295 val_to_str_const(fetched_iei, tab_nsip_ieis, "Unknown"),
296 fetched_iei);
298 #endif
299 return (fetched_iei == ie->iei);
302 static void
303 decode_iei_cause(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
304 guint8 cause;
306 cause = tvb_get_guint8(bi->tvb, bi->offset);
307 proto_tree_add_uint(bi->nsip_tree, hf_nsip_cause,
308 bi->tvb, ie_start_offset, ie->total_length,
309 cause);
310 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
311 "Cause: %s",
312 val_to_str(cause, tab_nsip_cause_values, "Unknown (0x%02x)"));
314 proto_item_append_text(bi->ti, ", Cause: %s",
315 val_to_str(cause, tab_nsip_cause_values, "Unknown (0x%02x)"));
317 bi->offset += ie->value_length;
320 static void
321 decode_iei_ns_vci(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
322 guint16 ns_vci;
324 ns_vci = tvb_get_ntohs(bi->tvb, bi->offset);
326 proto_tree_add_uint(bi->nsip_tree, hf_nsip_ns_vci,
327 bi->tvb, ie_start_offset, ie->total_length,
328 ns_vci);
329 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
330 "NS VCI: %#04x", ns_vci);
331 proto_item_append_text(bi->ti, ", NS VCI: %#04x", ns_vci);
333 bi->offset += ie->value_length;
336 static void
337 decode_iei_ns_pdu(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
338 tvbuff_t * next_tvb;
340 proto_tree_add_text(bi->nsip_tree, bi->tvb, ie_start_offset,
341 ie->total_length,
342 "NS PDU (%u bytes)", ie->value_length);
343 next_tvb = tvb_new_subset(bi->tvb, bi->offset, ie->value_length, -1);
344 if (nsip_handle) {
345 gboolean was_recursive;
346 was_recursive = nsip_is_recursive;
347 nsip_is_recursive = TRUE;
348 call_dissector(nsip_handle, next_tvb, bi->pinfo, bi->nsip_tree);
349 nsip_is_recursive = was_recursive;
351 bi->offset += ie->value_length;
354 static void
355 decode_iei_nsei(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
356 guint16 nsei = tvb_get_ntohs(bi->tvb, bi->offset);
358 proto_tree_add_uint(bi->nsip_tree, hf_nsip_nsei, bi->tvb,
359 ie_start_offset, ie->total_length, nsei);
360 bi->offset += ie->value_length;
362 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
363 "NSEI %u", nsei);
365 proto_item_append_text(bi->ti, ", NSEI %u", nsei);
368 static void
369 decode_iei_bvci(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
370 guint16 bvci = tvb_get_ntohs(bi->tvb, bi->offset);
372 proto_tree_add_uint(bi->nsip_tree, hf_nsip_bvci, bi->tvb,
373 ie_start_offset, ie->total_length, bvci);
374 bi->offset += ie->value_length;
376 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
377 "BVCI %u", bvci);
378 proto_item_append_text(bi->ti, ", BVCI %u", bvci);
381 static proto_item *
382 decode_ip_element(nsip_ip_element_info_t *element, build_info_t *bi, proto_tree * element_tree) {
383 guint16 udp_port;
384 guint32 ip4_addr;
385 struct e_in6_addr ip6_addr;
386 proto_item *tf = NULL;
387 proto_tree *field_tree = NULL;
389 if (bi->nsip_tree) {
390 tf = proto_tree_add_text(element_tree, bi->tvb, bi->offset,
391 element->total_length, "IP Element");
392 field_tree = proto_item_add_subtree(tf, ett_nsip_ip_element);
394 /* IP address */
395 switch (element->version) {
396 case NSIP_IP_VERSION_4:
397 ip4_addr = tvb_get_ipv4(bi->tvb, bi->offset);
398 proto_tree_add_item(field_tree, hf_nsip_ip_address_ipv4,
399 bi->tvb, bi->offset, element->address_length,
400 ENC_BIG_ENDIAN);
401 proto_item_append_text(tf, ": IP address: %s",
402 ip_to_str((guint8 *)&ip4_addr));
404 break;
405 case NSIP_IP_VERSION_6:
406 tvb_get_ipv6(bi->tvb, bi->offset, &ip6_addr);
407 proto_tree_add_item(field_tree, hf_nsip_ip_address_ipv6, bi->tvb,
408 bi->offset, element->address_length,
409 ENC_NA);
410 proto_item_append_text(tf, ": IP address: %s",
411 ip6_to_str((struct e_in6_addr *)&ip6_addr));
412 break;
413 default:
417 bi->offset += element->address_length;
419 if (bi->nsip_tree) {
420 /* UDP port value */
421 udp_port = tvb_get_ntohs(bi->tvb, bi->offset);
422 proto_tree_add_item(field_tree, hf_nsip_ip_element_udp_port,
423 bi->tvb, bi->offset, 2, ENC_BIG_ENDIAN);
424 proto_item_append_text(tf, ", UDP Port: %u", udp_port);
426 bi->offset += 2;
428 if (bi->nsip_tree) {
429 /* Signalling weight */
430 proto_tree_add_item(field_tree, hf_nsip_ip_element_signalling_weight,
431 bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN);
433 bi->offset++;
435 if (bi->nsip_tree) {
436 /* Data weight */
437 proto_tree_add_item(field_tree, hf_nsip_ip_element_data_weight,
438 bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN);
440 bi->offset++;
441 return tf;
444 static proto_item *
445 decode_ip_elements(nsip_ip_element_info_t *element, nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
446 int i;
447 int num_elements = ie->value_length / element->total_length;
448 proto_item *tf;
449 proto_tree *field_tree;
451 tf = proto_tree_add_text(bi->nsip_tree, bi->tvb, ie_start_offset,
452 ie->total_length,
453 "List of IP%u Elements (%u Elements)",
454 element->version, num_elements);
455 field_tree = proto_item_add_subtree(tf, ett_nsip_ip_element_list);
457 for (i = 0; i < num_elements; i++) {
458 decode_ip_element(element, bi, field_tree);
460 return tf;
463 static void
464 decode_iei_max_num_ns_vc(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
465 guint16 num_ns_vc;
467 if (bi->nsip_tree) {
468 num_ns_vc = tvb_get_ntohs(bi->tvb, bi->offset);
470 proto_tree_add_uint(bi->nsip_tree, hf_nsip_max_num_ns_vc,
471 bi->tvb, ie_start_offset, ie->total_length,
472 num_ns_vc);
474 bi->offset += 2;
477 static void
478 decode_iei_num_ip4_endpoints(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
479 guint16 num_endpoints;
481 if (bi->nsip_tree) {
482 num_endpoints = tvb_get_ntohs(bi->tvb, bi->offset);
484 proto_tree_add_uint(bi->nsip_tree, hf_nsip_num_ip4_endpoints,
485 bi->tvb, ie_start_offset, ie->total_length,
486 num_endpoints);
488 bi->offset += 2;
491 static void
492 decode_iei_num_ip6_endpoints(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
493 guint16 num_endpoints;
495 if (bi->nsip_tree) {
496 num_endpoints = tvb_get_ntohs(bi->tvb, bi->offset);
498 proto_tree_add_uint(bi->nsip_tree, hf_nsip_num_ip6_endpoints,
499 bi->tvb, ie_start_offset, ie->total_length,
500 num_endpoints);
502 bi->offset += 2;
505 static void
506 decode_iei_reset_flag(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
507 guint8 flag;
508 proto_item *tf;
509 proto_tree *field_tree;
511 flag = tvb_get_guint8(bi->tvb, bi->offset);
512 if (bi->nsip_tree) {
514 tf = proto_tree_add_text(bi->nsip_tree, bi->tvb, ie_start_offset,
515 ie->total_length,
516 "Reset Flag: %#02x", flag);
518 field_tree = proto_item_add_subtree(tf, ett_nsip_reset_flag);
519 proto_tree_add_boolean(field_tree, hf_nsip_reset_flag, bi->tvb,
520 bi->offset, 1,
521 flag & NSIP_MASK_RESET_FLAG);
522 if (flag & NSIP_MASK_RESET_FLAG) {
523 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
524 "Reset");
525 proto_item_append_text(bi->ti, ", Reset");
527 proto_tree_add_uint(field_tree, hf_nsip_reset_flag_spare,
528 bi->tvb, bi->offset, 1,
529 flag & NSIP_MASK_RESET_FLAG_SPARE);
531 bi->offset += 1;
534 static void
535 decode_iei_ip_address(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
536 guint8 addr_type;
537 guint32 ip4_addr;
538 struct e_in6_addr ip6_addr;
540 addr_type = tvb_get_guint8(bi->tvb, bi->offset);
541 proto_tree_add_item(bi->nsip_tree, hf_nsip_ip_address_type,
542 bi->tvb, bi->offset, 1, ENC_BIG_ENDIAN);
543 switch (addr_type) {
544 case NSIP_IP_ADDRESS_TYPE_IPV4:
545 ie->total_length = 2 + ipv4_element.address_length;
546 ip4_addr = tvb_get_ipv4(bi->tvb, bi->offset+1);
547 proto_tree_add_ipv4(bi->nsip_tree, hf_nsip_ip_address_ipv4,
548 bi->tvb, ie_start_offset, ie->total_length,
549 ip4_addr);
550 break;
551 case NSIP_IP_ADDRESS_TYPE_IPV6:
552 ie->total_length = 2 + ipv6_element.address_length;
553 tvb_get_ipv6(bi->tvb, bi->offset+1, &ip6_addr);
554 proto_tree_add_ipv6(bi->nsip_tree, hf_nsip_ip_address_ipv4,
555 bi->tvb, ie_start_offset, ie->total_length,
556 (guint8 *)&ip6_addr);
557 break;
558 default:
559 return; /* error */
561 bi->offset += ie->value_length;
564 static void
565 decode_iei_transaction_id(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
566 guint8 id;
567 id = tvb_get_guint8(bi->tvb, bi->offset);
568 proto_tree_add_uint(bi->nsip_tree, hf_nsip_transaction_id,
569 bi->tvb, ie_start_offset, ie->total_length, id);
570 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
571 "Transaction Id: %d", id);
572 bi->offset += 1;
575 static void
576 decode_iei_end_flag(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
577 guint8 flag;
578 proto_item *tf;
579 proto_tree *field_tree;
581 if (bi->nsip_tree) {
582 flag = tvb_get_guint8(bi->tvb, bi->offset);
584 tf = proto_tree_add_text(bi->nsip_tree, bi->tvb, ie_start_offset,
585 ie->total_length,
586 "End Flag: %#02x", flag);
588 field_tree = proto_item_add_subtree(tf, ett_nsip_end_flag);
589 proto_tree_add_boolean(field_tree, hf_nsip_end_flag, bi->tvb,
590 bi->offset, 1,
591 flag & NSIP_MASK_END_FLAG);
592 if (flag & NSIP_MASK_END_FLAG) {
593 proto_item_append_text(bi->ti, ", End");
595 proto_tree_add_uint(field_tree, hf_nsip_end_flag_spare,
596 bi->tvb, bi->offset, 1,
597 flag & NSIP_MASK_END_FLAG_SPARE);
599 bi->offset += 1;
602 static void
603 decode_iei_control_bits(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
604 guint8 control_bits;
605 proto_item *tf;
606 proto_tree *field_tree;
608 control_bits = tvb_get_guint8(bi->tvb, bi->offset);
610 if (bi->nsip_tree) {
611 tf = proto_tree_add_text(bi->nsip_tree, bi->tvb, ie_start_offset,
612 ie->total_length,
613 "NS SDU Control bits: %#02x", control_bits);
615 field_tree = proto_item_add_subtree(tf, ett_nsip_control_bits);
616 proto_tree_add_boolean(field_tree, hf_nsip_control_bits_r, bi->tvb,
617 bi->offset, 1,
618 control_bits & NSIP_MASK_CONTROL_BITS_R);
619 proto_tree_add_boolean(field_tree, hf_nsip_control_bits_c, bi->tvb,
620 bi->offset, 1,
621 control_bits & NSIP_MASK_CONTROL_BITS_C);
622 proto_tree_add_uint(field_tree, hf_nsip_control_bits_spare,
623 bi->tvb, bi->offset, 1,
624 control_bits & NSIP_MASK_CONTROL_BITS_SPARE);
626 bi->offset++;
628 if (control_bits & NSIP_MASK_CONTROL_BITS_R) {
629 col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Req CF");
630 proto_item_append_text(bi->ti, ", Request Change Flow");
633 if (control_bits & NSIP_MASK_CONTROL_BITS_C) {
634 col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Conf CF");
635 proto_item_append_text(bi->ti, ", Confirm Change Flow");
640 static void
641 decode_ie(nsip_ie_t *ie, build_info_t *bi) {
643 int org_offset = bi->offset;
645 if (tvb_length_remaining(bi->tvb, bi->offset) < 1) {
646 return;
648 switch (ie->format) {
649 case NSIP_IE_FORMAT_TLV:
650 if (!check_correct_iei(ie, bi)) {
651 return;
653 bi->offset++; /* Account for type */
654 ie->total_length = 1;
655 get_value_length(ie, bi);
656 break;
657 case NSIP_IE_FORMAT_TV:
658 if (!check_correct_iei(ie, bi)) {
659 return;
661 bi->offset++; /* Account for type */
662 ie->value_length = ie->total_length - 1;
663 break;
664 case NSIP_IE_FORMAT_V:
665 ie->value_length = ie->total_length;
666 default:
669 switch (ie->iei) {
670 case NSIP_IE_CAUSE:
671 decode_iei_cause(ie, bi, org_offset);
672 break;
673 case NSIP_IE_NS_VCI:
674 decode_iei_ns_vci(ie, bi, org_offset);
675 break;
676 case NSIP_IE_NS_PDU:
677 decode_iei_ns_pdu(ie, bi, org_offset);
678 break;
679 case NSIP_IE_NSEI:
680 decode_iei_nsei(ie, bi, org_offset);
681 break;
682 case NSIP_IE_BVCI:
683 decode_iei_bvci(ie, bi, org_offset);
684 break;
685 case NSIP_IE_IP4_ELEMENTS:
686 decode_ip_elements(&ipv4_element, ie, bi, org_offset);
687 break;
688 case NSIP_IE_IP6_ELEMENTS:
689 decode_ip_elements(&ipv6_element, ie, bi, org_offset);
690 break;
691 case NSIP_IE_MAX_NUM_NS_VC:
692 decode_iei_max_num_ns_vc(ie, bi, org_offset);
693 break;
694 case NSIP_IE_NUM_IP4_ENDPOINTS:
695 decode_iei_num_ip4_endpoints(ie, bi, org_offset);
696 break;
697 case NSIP_IE_NUM_IP6_ENDPOINTS:
698 decode_iei_num_ip6_endpoints(ie, bi, org_offset);
699 break;
700 case NSIP_IE_RESET_FLAG:
701 decode_iei_reset_flag(ie, bi, org_offset);
702 break;
703 case NSIP_IE_IP_ADDRESS:
704 decode_iei_ip_address(ie, bi, org_offset);
705 break;
706 default:
711 static void
712 decode_pdu_general(nsip_ie_t *ies, int num_ies, build_info_t *bi) {
713 int i;
714 for (i = 0; i < num_ies; i++) {
715 decode_ie(&ies[i], bi);
719 static void
720 decode_pdu_ns_unitdata(build_info_t *bi) {
721 tvbuff_t *next_tvb;
723 nsip_ie_t ies[] = {
724 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Control bits */
725 { NSIP_IE_BVCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 2 },
726 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 0 },
727 /* NS SDU, length unknown */
729 gint sdu_length;
731 decode_iei_control_bits(ies, bi, bi->offset);
732 decode_pdu_general(&ies[1], 1, bi);
734 next_tvb = tvb_new_subset_remaining(bi->tvb, bi->offset);
735 if (bssgp_handle) {
736 call_dissector(bssgp_handle, next_tvb, bi->pinfo, bi->parent_tree);
738 else {
739 sdu_length = tvb_length_remaining(bi->tvb, bi->offset);
740 proto_tree_add_text(bi->nsip_tree, bi->tvb, bi->offset, sdu_length,
741 "NS SDU (%u bytes)", sdu_length);
745 static void
746 decode_pdu_ns_reset(build_info_t *bi) {
747 nsip_ie_t ies[] = {
748 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 3 },
749 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
750 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
752 decode_pdu_general(ies, 3, bi);
755 static void
756 decode_pdu_ns_reset_ack(build_info_t *bi) {
757 nsip_ie_t ies[] = {
758 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
759 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
761 decode_pdu_general(ies, 2, bi);
764 static void
765 decode_pdu_ns_block(build_info_t *bi) {
766 nsip_ie_t ies[] = {
767 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 3 },
768 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
770 decode_pdu_general(ies, 2, bi);
773 static void
774 decode_pdu_ns_block_ack(build_info_t *bi) {
775 nsip_ie_t ies[] = { { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV,
776 0, 1 }, };
777 decode_pdu_general(ies, 1, bi);
780 static void
781 decode_pdu_ns_status(build_info_t *bi) {
782 nsip_ie_t ies[] = {
783 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 3 },
784 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
785 { NSIP_IE_NS_PDU, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
786 /* Unknown length */
787 { NSIP_IE_BVCI, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 4 },
788 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
789 /* Unknown length */
790 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
791 /* Unknown length */
793 decode_pdu_general(ies, 6, bi);
796 static void
797 decode_pdu_sns_ack(build_info_t *bi) {
798 nsip_ie_t ies[] = {
799 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
800 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
801 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 3 },
802 { NSIP_IE_IP_ADDRESS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV, 0, 0 },
803 /* Unknown length */
804 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
805 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
807 decode_pdu_general(ies, 1, bi);
808 decode_iei_transaction_id(&ies[1], bi, bi->offset);
809 decode_pdu_general(&ies[2], 4, bi);
812 static void
813 decode_pdu_sns_add(build_info_t *bi) {
814 nsip_ie_t ies[] = {
815 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
816 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
817 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
818 /* Unknown length */
819 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
820 /* Unknown length */
822 decode_pdu_general(ies, 1, bi);
823 decode_iei_transaction_id(&ies[1], bi, bi->offset);
824 decode_pdu_general(&ies[2], 2, bi);
827 static void
828 decode_pdu_sns_changeweight(build_info_t *bi) {
829 nsip_ie_t ies[] = {
830 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
831 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
832 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
833 /* Unknown length */
834 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
835 /* Unknown length */
837 decode_pdu_general(ies, 1, bi);
838 decode_iei_transaction_id(&ies[1], bi, bi->offset);
839 decode_pdu_general(&ies[2], 2, bi);
842 static void
843 decode_pdu_sns_config(build_info_t *bi) {
845 nsip_ie_t ies[] = {
846 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* End flag */
847 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
848 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
849 /* Unknown length */
850 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
851 /* Unknown length */
853 decode_iei_end_flag(ies, bi, bi->offset);
854 decode_pdu_general(&ies[1], 3, bi);
857 static void
858 decode_pdu_sns_config_ack(build_info_t *bi) {
859 nsip_ie_t ies[] = {
860 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
861 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 3 },
863 decode_pdu_general(ies, 2, bi);
866 static void
867 decode_pdu_sns_delete(build_info_t *bi) {
868 nsip_ie_t ies[] = {
869 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4}, /* CR013 */
870 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
871 { NSIP_IE_IP_ADDRESS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV, 0, 0 },
872 /* Unknown length */
873 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
874 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
876 decode_pdu_general(ies, 1, bi);
877 decode_iei_transaction_id(&ies[1], bi, bi->offset);
878 decode_pdu_general(&ies[2], 3, bi);
881 static void
882 decode_pdu_sns_size(build_info_t *bi) {
883 nsip_ie_t ies[] = {
884 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
885 { NSIP_IE_RESET_FLAG, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TV, 0, 2 },
886 { NSIP_IE_MAX_NUM_NS_VC, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TV, 0, 3 },
887 { NSIP_IE_NUM_IP4_ENDPOINTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV,
888 0, 3 },
889 { NSIP_IE_NUM_IP6_ENDPOINTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV,
890 0, 3 },
892 decode_pdu_general(ies, 5, bi);
895 static void
896 decode_pdu_sns_size_ack(build_info_t *bi) {
897 nsip_ie_t ies[] = {
898 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
899 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 3 },
901 decode_pdu_general(ies, 2, bi);
904 static void
905 decode_pdu(guint8 pdu_type, build_info_t *bi) {
906 switch (pdu_type) {
907 case NSIP_PDU_NS_UNITDATA:
908 decode_pdu_ns_unitdata(bi);
909 break;
910 case NSIP_PDU_NS_RESET:
911 decode_pdu_ns_reset(bi);
912 break;
913 case NSIP_PDU_NS_RESET_ACK:
914 decode_pdu_ns_reset_ack(bi);
915 break;
916 case NSIP_PDU_NS_BLOCK:
917 decode_pdu_ns_block(bi);
918 break;
919 case NSIP_PDU_NS_BLOCK_ACK:
920 decode_pdu_ns_block_ack(bi);
921 break;
922 case NSIP_PDU_NS_STATUS:
923 decode_pdu_ns_status(bi);
924 break;
925 case NSIP_PDU_SNS_ACK:
926 decode_pdu_sns_ack(bi);
927 break;
928 case NSIP_PDU_SNS_ADD:
929 decode_pdu_sns_add(bi);
930 break;
931 case NSIP_PDU_SNS_CHANGEWEIGHT:
932 decode_pdu_sns_changeweight(bi);
933 break;
934 case NSIP_PDU_SNS_CONFIG:
935 decode_pdu_sns_config(bi);
936 break;
937 case NSIP_PDU_SNS_CONFIG_ACK:
938 decode_pdu_sns_config_ack(bi);
939 break;
940 case NSIP_PDU_SNS_DELETE:
941 decode_pdu_sns_delete(bi);
942 break;
943 case NSIP_PDU_SNS_SIZE:
944 decode_pdu_sns_size(bi);
945 break;
946 case NSIP_PDU_SNS_SIZE_ACK:
947 decode_pdu_sns_size_ack(bi);
948 break;
949 case NSIP_PDU_NS_ALIVE:
950 case NSIP_PDU_NS_ALIVE_ACK:
951 case NSIP_PDU_NS_UNBLOCK:
952 case NSIP_PDU_NS_UNBLOCK_ACK:
953 /* Only contains PDU type, which has already been decoded */
954 default: ;
958 static void
959 dissect_nsip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
960 guint8 pdu_type;
961 build_info_t bi = { NULL, 0, NULL, NULL, NULL, NULL };
962 proto_tree *nsip_tree;
964 bi.tvb = tvb;
965 bi.pinfo = pinfo;
966 bi.parent_tree = tree;
968 pinfo->current_proto = "GPRS-NS";
970 if (!nsip_is_recursive) {
971 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GPRS-NS");
972 col_clear(pinfo->cinfo, COL_INFO);
975 pdu_type = tvb_get_guint8(tvb, 0);
976 bi.offset++;
978 if (tree) {
979 bi.ti = proto_tree_add_item(tree, proto_nsip, tvb, 0, -1,
980 ENC_NA);
981 nsip_tree = proto_item_add_subtree(bi.ti, ett_nsip);
982 proto_tree_add_item(nsip_tree, hf_nsip_pdu_type, tvb, 0, 1, ENC_NA);
983 proto_item_append_text(bi.ti, ", PDU type: %s",
984 val_to_str_const(pdu_type, tab_nsip_pdu_types, "Unknown"));
985 bi.nsip_tree = nsip_tree;
988 if (!nsip_is_recursive) {
989 col_set_str(pinfo->cinfo, COL_INFO,
990 val_to_str_const(pdu_type, tab_nsip_pdu_types, "Unknown PDU type"));
991 } else {
992 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NSIP_SEP, "%s",
993 val_to_str_const(pdu_type, tab_nsip_pdu_types, "Unknown PDU type"));
995 decode_pdu(pdu_type, &bi);
998 void
999 proto_register_nsip(void)
1001 static hf_register_info hf[] = {
1002 { &hf_nsip_cause,
1003 { "Cause", "nsip.cause",
1004 FT_UINT8, BASE_OCT, VALS(tab_nsip_cause_values), 0x0,
1005 NULL, HFILL }
1007 { &hf_nsip_ns_vci,
1008 { "NS-VCI", "nsip.ns_vci",
1009 FT_UINT16, BASE_HEX, NULL, 0x0,
1010 "Network Service Virtual Link Identifier", HFILL }
1012 { &hf_nsip_pdu_type,
1013 { "PDU type", "nsip.pdu_type",
1014 FT_UINT8, BASE_OCT, VALS(tab_nsip_pdu_types), 0x0,
1015 "PDU type information element", HFILL }
1017 { &hf_nsip_bvci,
1018 { "BVCI", "nsip.bvci",
1019 FT_UINT16, BASE_DEC, NULL, 0x0,
1020 "BSSGP Virtual Connection Identifier", HFILL }
1022 { &hf_nsip_nsei,
1023 { "NSEI", "nsip.nsei",
1024 FT_UINT16, BASE_DEC, NULL, 0x0,
1025 "Network Service Entity Identifier", HFILL }
1027 #if 0
1028 { &hf_nsip_ip4_elements,
1029 { "IP4 elements", "nsip.ip4_elements",
1030 FT_NONE, BASE_NONE, NULL, 0x0,
1031 "List of IP4 elements", HFILL }
1033 #endif
1034 #if 0
1035 { &hf_nsip_ip6_elements,
1036 { "IP6 elements", "nsip.ip6_elements",
1037 FT_NONE, BASE_NONE, NULL, 0x0,
1038 "List of IP6 elements", HFILL }
1040 #endif
1041 { &hf_nsip_max_num_ns_vc,
1042 { "Maximum number of NS-VCs", "nsip.max_num_ns_vc",
1043 FT_UINT16, BASE_DEC, NULL, 0x0,
1044 NULL, HFILL }
1046 { &hf_nsip_num_ip4_endpoints,
1047 { "Number of IP4 endpoints", "nsip.num_ip4_endpoints",
1048 FT_UINT16, BASE_DEC, NULL, 0x0,
1049 NULL, HFILL }
1051 { &hf_nsip_num_ip6_endpoints,
1052 { "Number of IP6 endpoints", "nsip.num_ip6_endpoints",
1053 FT_UINT16, BASE_DEC, NULL, 0x0,
1054 NULL, HFILL }
1056 { &hf_nsip_reset_flag,
1057 { "Reset flag", "nsip.reset_flag.flag",
1058 FT_BOOLEAN, 8, TFS(&tfs_set_notset), NSIP_MASK_RESET_FLAG,
1059 NULL, HFILL }
1061 { &hf_nsip_reset_flag_spare,
1062 { "Reset flag spare bits", "nsip.reset_flag.spare",
1063 FT_UINT8, BASE_HEX, NULL, NSIP_MASK_RESET_FLAG_SPARE,
1064 NULL, HFILL }
1066 { &hf_nsip_ip_address_type,
1067 { "IP Address Type", "nsip.ip_address_type",
1068 FT_UINT8, BASE_DEC, VALS(ip_address_type_vals), 0x0,
1069 NULL, HFILL }
1071 { &hf_nsip_ip_address_ipv4,
1072 { "IP Address", "nsip.ipv4_address",
1073 FT_IPv4, BASE_NONE, NULL, 0x0,
1074 NULL, HFILL }
1076 { &hf_nsip_ip_address_ipv6,
1077 { "IP Address", "nsip.ipv6_address",
1078 FT_IPv6, BASE_NONE, NULL, 0x0,
1079 NULL, HFILL }
1081 { &hf_nsip_end_flag,
1082 { "End flag", "nsip.end_flag.flag",
1083 FT_BOOLEAN, 8, TFS(&tfs_set_notset), NSIP_MASK_END_FLAG,
1084 NULL, HFILL }
1086 { &hf_nsip_end_flag_spare,
1087 { "End flag spare bits", "nsip.end_flag.spare",
1088 FT_UINT8, BASE_HEX, NULL, NSIP_MASK_END_FLAG_SPARE,
1089 NULL, HFILL }
1091 { &hf_nsip_control_bits_r,
1092 { "Request change flow", "nsip.control_bits.r",
1093 FT_BOOLEAN, 8, TFS(&tfs_set_notset), NSIP_MASK_CONTROL_BITS_R,
1094 NULL, HFILL }
1096 { &hf_nsip_control_bits_c,
1097 { "Confirm change flow", "nsip.control_bits.c",
1098 FT_BOOLEAN, 8, TFS(&tfs_set_notset), NSIP_MASK_CONTROL_BITS_C,
1099 NULL, HFILL }
1101 { &hf_nsip_control_bits_spare,
1102 { "Spare bits", "nsip.control_bits.spare",
1103 FT_UINT8, BASE_HEX, NULL, NSIP_MASK_CONTROL_BITS_SPARE,
1104 NULL, HFILL }
1106 { &hf_nsip_transaction_id,
1107 { "Transaction ID", "nsip.transaction_id",
1108 FT_UINT8, BASE_DEC, NULL, 0x0,
1109 NULL, HFILL }
1111 #if 0
1112 { &hf_nsip_ip_element_ip_address_ipv4,
1113 { "IP Address", "nsip.ip_element.ipv4_address",
1114 FT_IPv4, BASE_NONE, NULL, 0x0,
1115 NULL, HFILL }
1117 #endif
1118 #if 0
1119 { &hf_nsip_ip_element_ip_address_ipv6,
1120 { "IP Address", "nsip.ip_element.ipv6_address",
1121 FT_IPv6, BASE_NONE, NULL, 0x0,
1122 NULL, HFILL }
1124 #endif
1125 { &hf_nsip_ip_element_udp_port,
1126 { "UDP Port", "nsip.ip_element.udp_port",
1127 FT_UINT16, BASE_DEC, NULL, 0x0,
1128 NULL, HFILL }
1130 { &hf_nsip_ip_element_signalling_weight,
1131 { "Signalling Weight", "nsip.ip_element.signalling_weight",
1132 FT_UINT8, BASE_DEC, NULL, 0x0,
1133 NULL, HFILL }
1135 { &hf_nsip_ip_element_data_weight,
1136 { "Data Weight", "nsip.ip_element.data_weight",
1137 FT_UINT8, BASE_DEC, NULL, 0x0,
1138 NULL, HFILL }
1142 /* Setup protocol subtree array */
1143 static gint *ett[] = {
1144 &ett_nsip,
1145 &ett_nsip_control_bits,
1146 &ett_nsip_reset_flag,
1147 &ett_nsip_end_flag,
1148 &ett_nsip_ip_element,
1149 &ett_nsip_ip_element_list,
1152 module_t *nsip_module;
1154 /* Register the protocol name and description */
1155 proto_nsip = proto_register_protocol("GPRS Network Service",
1156 "GPRS-NS", "gprs-ns");
1158 /* Required function calls to register the header fields and
1159 subtrees used */
1160 proto_register_field_array(proto_nsip, hf, array_length(hf));
1161 proto_register_subtree_array(ett, array_length(ett));
1163 register_dissector("gprs_ns", dissect_nsip, proto_nsip);
1165 /* Set default UDP ports */
1166 range_convert_str(&global_nsip_udp_port_range, DEFAULT_NSIP_PORT_RANGE, MAX_UDP_PORT);
1168 /* Register configuration options */
1169 nsip_module = prefs_register_protocol(proto_nsip, proto_reg_handoff_nsip);
1170 prefs_register_obsolete_preference(nsip_module, "udp.port1");
1171 prefs_register_obsolete_preference(nsip_module, "udp.port2");
1172 prefs_register_range_preference(nsip_module, "udp.ports", "GPRS-NS UDP ports",
1173 "UDP ports to be decoded as GPRS-NS (default: "
1174 DEFAULT_NSIP_PORT_RANGE ")",
1175 &global_nsip_udp_port_range, MAX_UDP_PORT);
1178 void
1179 proto_reg_handoff_nsip(void) {
1180 static gboolean nsip_prefs_initialized = FALSE;
1181 static range_t *nsip_udp_port_range;
1183 if (!nsip_prefs_initialized) {
1184 nsip_handle = find_dissector("gprs_ns");
1185 bssgp_handle = find_dissector("bssgp");
1186 nsip_prefs_initialized = TRUE;
1187 } else {
1188 dissector_delete_uint_range("udp.port", nsip_udp_port_range, nsip_handle);
1189 g_free(nsip_udp_port_range);
1192 nsip_udp_port_range = range_copy(global_nsip_udp_port_range);
1194 dissector_add_uint_range("udp.port", nsip_udp_port_range, nsip_handle);
1199 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1201 * Local variables:
1202 * c-basic-offset: 2
1203 * tab-width: 4
1204 * indent-tabs-mode: nil
1205 * End:
1207 * vi: set shiftwidth=2 tabstop=4 expandtab:
1208 * :indentSize=2:tabSize=4:noTabs=true: