2 * Routines for Network Service Over IP dissection
3 * Copyright 2000, Susanne Edlund <susanne.edlund@ericsson.com>
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 /* 3GPP TS 48.016 V 5.3.0 (2004-07) Release 6 + CR013 */
38 #include <epan/packet.h>
39 #include <epan/ipv6-utils.h>
43 #define DECODE_AS_NSIP 1
44 #define NSIP_UDP_PORT1 2157
45 #define NSIP_UDP_PORT2 19999
46 #define NSIP_SEP ", " /* Separator string */
47 #define NSIP_LITTLE_ENDIAN 0
49 static int nsip_udp_port1 = NSIP_UDP_PORT1;
50 static int nsip_udp_port2 = NSIP_UDP_PORT2;
51 static int global_nsip_udp_port1 = NSIP_UDP_PORT1;
52 static int global_nsip_udp_port2 = NSIP_UDP_PORT2;
54 void proto_reg_handoff_nsip(void);
56 /* Initialize the protocol and registered fields */
57 static int proto_nsip = -1;
59 static int hf_nsip_cause = -1;
60 static int hf_nsip_ns_vci = -1;
61 static int hf_nsip_pdu_type = -1;
62 static int hf_nsip_bvci = -1;
63 static int hf_nsip_nsei = -1;
64 static int hf_nsip_ip4_elements = -1;
65 static int hf_nsip_ip6_elements = -1;
66 static int hf_nsip_max_num_ns_vc = -1;
67 static int hf_nsip_num_ip4_endpoints = -1;
68 static int hf_nsip_num_ip6_endpoints = -1;
69 static int hf_nsip_reset_flag = -1;
70 static int hf_nsip_ip_address_ipv4 = -1;
71 static int hf_nsip_ip_address_ipv6 = -1;
72 static int hf_nsip_end_flag = -1;
73 static int hf_nsip_control_bits_r = -1;
74 static int hf_nsip_control_bits_c = -1;
75 static int hf_nsip_transaction_id = -1;
76 static int hf_nsip_ip_element_ip_address_ipv4 = -1;
77 static int hf_nsip_ip_element_ip_address_ipv6 = -1;
78 static int hf_nsip_ip_element_udp_port = -1;
79 static int hf_nsip_ip_element_signalling_weight = -1;
80 static int hf_nsip_ip_element_data_weight = -1;
83 /* Initialize the subtree pointers */
84 static gint ett_nsip = -1;
85 static gint ett_nsip_control_bits = -1;
86 static gint ett_nsip_ip_element = -1;
87 static gint ett_nsip_ip_element_list = -1;
89 /* PDU type coding, v5.3.0, table 10.3.7.1, p 51 */
90 #define NSIP_PDU_NS_UNITDATA 0x00
91 #define NSIP_PDU_NS_RESET 0x02
92 #define NSIP_PDU_NS_RESET_ACK 0x03
93 #define NSIP_PDU_NS_BLOCK 0x04
94 #define NSIP_PDU_NS_BLOCK_ACK 0x05
95 #define NSIP_PDU_NS_UNBLOCK 0x06
96 #define NSIP_PDU_NS_UNBLOCK_ACK 0x07
97 #define NSIP_PDU_NS_STATUS 0x08
98 #define NSIP_PDU_NS_ALIVE 0x0a
99 #define NSIP_PDU_NS_ALIVE_ACK 0x0b
100 #define NSIP_PDU_SNS_ACK 0x0c
101 #define NSIP_PDU_SNS_ADD 0x0d
102 #define NSIP_PDU_SNS_CHANGEWEIGHT 0x0e
103 #define NSIP_PDU_SNS_CONFIG 0x0f
104 #define NSIP_PDU_SNS_CONFIG_ACK 0x10
105 #define NSIP_PDU_SNS_DELETE 0x11
106 #define NSIP_PDU_SNS_SIZE 0x12
107 #define NSIP_PDU_SNS_SIZE_ACK 0x13
109 static const value_string tab_nsip_pdu_types[] = {
110 { NSIP_PDU_NS_UNITDATA, "NS_UNITDATA" },
111 { NSIP_PDU_NS_RESET, "NS_RESET" },
112 { NSIP_PDU_NS_RESET_ACK, "NS_RESET_ACK" },
113 { NSIP_PDU_NS_BLOCK, "NS_BLOCK" },
114 { NSIP_PDU_NS_BLOCK_ACK, "NS_BLOCK_ACK" },
115 { NSIP_PDU_NS_UNBLOCK, "NS_UNBLOCK" },
116 { NSIP_PDU_NS_UNBLOCK_ACK, "NS_UNBLOCK_ACK" },
117 { NSIP_PDU_NS_STATUS, "NS_STATUS" },
118 { NSIP_PDU_NS_ALIVE, "NS_ALIVE" },
119 { NSIP_PDU_NS_ALIVE_ACK, "NS_ALIVE_ACK" },
120 { NSIP_PDU_SNS_ACK, "SNS_ACK" },
121 { NSIP_PDU_SNS_ADD, "SNS_ADD" },
122 { NSIP_PDU_SNS_CHANGEWEIGHT, "SNS_CHANGEWEIGHT" },
123 { NSIP_PDU_SNS_CONFIG, "SNS_CONFIG" },
124 { NSIP_PDU_SNS_CONFIG_ACK, "SNS_CONFIG_ACK" },
125 { NSIP_PDU_SNS_DELETE, "SNS_DELETE" },
126 { NSIP_PDU_SNS_SIZE, "SNS_SIZE" },
127 { NSIP_PDU_SNS_SIZE_ACK, "SNS_SIZE_ACK" },
131 /* Information element coding, v 5.3.0, table 10.3.1, p 46 */
132 #define NSIP_IE_CAUSE 0x00
133 #define NSIP_IE_NS_VCI 0x01
134 #define NSIP_IE_NS_PDU 0x02
135 #define NSIP_IE_BVCI 0x03
136 #define NSIP_IE_NSEI 0x04
137 #define NSIP_IE_IP4_ELEMENTS 0x05
138 #define NSIP_IE_IP6_ELEMENTS 0x06
139 #define NSIP_IE_MAX_NUM_NS_VC 0x07
140 #define NSIP_IE_NUM_IP4_ENDPOINTS 0x08
141 #define NSIP_IE_NUM_IP6_ENDPOINTS 0x09
142 #define NSIP_IE_RESET_FLAG 0x0a
143 #define NSIP_IE_IP_ADDRESS 0x0b
145 static const value_string tab_nsip_ieis[] = {
146 { NSIP_IE_CAUSE, "Cause" },
147 { NSIP_IE_NS_VCI, "NS-VCI" },
148 { NSIP_IE_NS_PDU, "NS PDU" },
149 { NSIP_IE_BVCI, "BVCI" },
150 { NSIP_IE_NSEI, "NSEI" },
151 { NSIP_IE_IP4_ELEMENTS, "List of IP4 Elements" },
152 { NSIP_IE_IP6_ELEMENTS, "List of IP6 Elements" },
153 { NSIP_IE_MAX_NUM_NS_VC, "Maximum Number of NC-VCs" },
154 { NSIP_IE_NUM_IP4_ENDPOINTS, "Number of IP4 Endpoints" },
155 { NSIP_IE_NUM_IP6_ENDPOINTS, "Number of IP6 Endpoints"},
156 { NSIP_IE_RESET_FLAG, "Reset Flag" },
157 { NSIP_IE_IP_ADDRESS, "IP Address" },
161 /* Cause values, v 5.3.0, table 10.3.2.1, p 47 */
162 #define NSIP_CAUSE_TRANSIT_NETWORK_FAILURE 0x00
163 #define NSIP_CAUSE_OM_INTERVENTION 0x01
164 #define NSIP_CAUSE_EQUIPMENT_FAILURE 0x02
165 #define NSIP_CAUSE_NS_VC_BLOCKED 0x03
166 #define NSIP_CAUSE_NS_VC_UNKNOWN 0x04
167 #define NSIP_CAUSE_BVCI_UNKNOWN 0x05
168 #define NSIP_CAUSE_SEMANTICALLY_INCORRECT_PDU 0x08
169 #define NSIP_CAUSE_NSIP_PDU_NOT_COMPATIBLE 0x0a
170 #define NSIP_CAUSE_PROTOCOL_ERROR 0x0b
171 #define NSIP_CAUSE_INVALID_ESSENTIAL_IE 0x0c
172 #define NSIP_CAUSE_MISSING_ESSENTIAL_IE 0x0d
173 #define NSIP_CAUSE_INVALID_NUM_IP4_ENDPOINTS 0x0e
174 #define NSIP_CAUSE_INVALID_NUM_IP6_ENDPOINTS 0x0f
175 #define NSIP_CAUSE_INVALID_NUM_NS_VC 0x10
176 #define NSIP_CAUSE_INVALID_WEIGHTS 0x11
177 #define NSIP_CAUSE_UNKNOWN_IP_ENDPOINT 0x12
178 #define NSIP_CAUSE_UNKNOWN_IP_ADDRESS 0x13
179 #define NSIP_CAUSE_IP_TEST_FAILED 0x14
181 static const value_string tab_nsip_cause_values[] = {
182 { NSIP_CAUSE_TRANSIT_NETWORK_FAILURE, "Transit network failure" },
183 { NSIP_CAUSE_OM_INTERVENTION, "O&M intervention" },
184 { NSIP_CAUSE_EQUIPMENT_FAILURE, "Equipment failure" },
185 { NSIP_CAUSE_NS_VC_BLOCKED, "NS-VC blocked" },
186 { NSIP_CAUSE_NS_VC_UNKNOWN, "NS-VC unknown" },
187 { NSIP_CAUSE_BVCI_UNKNOWN, "BVCI unknown on that NSE" },
188 { NSIP_CAUSE_SEMANTICALLY_INCORRECT_PDU, "Semantically incorrect PDU" },
189 { NSIP_CAUSE_NSIP_PDU_NOT_COMPATIBLE, "PDU not compatible with the protocol state" },
190 { NSIP_CAUSE_PROTOCOL_ERROR, "Protocol error - unspecified" },
191 { NSIP_CAUSE_INVALID_ESSENTIAL_IE, "Invalid essential IE" },
192 { NSIP_CAUSE_MISSING_ESSENTIAL_IE, "Missing essential IE" },
193 { NSIP_CAUSE_INVALID_NUM_IP4_ENDPOINTS, "Invalid number of IP4 endpoints" },
194 { NSIP_CAUSE_INVALID_NUM_IP6_ENDPOINTS, "Invalid number of IP6 endpoints" },
195 { NSIP_CAUSE_INVALID_NUM_NS_VC, "Invalid number of NS-VCs" },
196 { NSIP_CAUSE_INVALID_WEIGHTS, "Invalid weights" },
197 { NSIP_CAUSE_UNKNOWN_IP_ENDPOINT, "Unknown IP endpoint" },
198 { NSIP_CAUSE_UNKNOWN_IP_ADDRESS, "Unknown IP address" },
199 { NSIP_CAUSE_IP_TEST_FAILED, "IP test failed" },
203 /* Presence requirements of Information Elements
204 v 5.3.0, chapter 8.1.1, p. 35 */
205 #define NSIP_IE_PRESENCE_M 1 /* Mandatory */
206 #define NSIP_IE_PRESENCE_O 2 /* Conditional */
207 #define NSIP_IE_PRESENCE_C 3 /* Optional */
210 #define NSIP_IE_FORMAT_V 1
211 #define NSIP_IE_FORMAT_TV 2
212 #define NSIP_IE_FORMAT_TLV 3
214 /* IP adress types, v 5.3.0, chapter 10.3.2b, p. 48 */
215 #define NSIP_IP_ADDRESS_TYPE_IPV4 1
216 #define NSIP_IP_ADDRESS_TYPE_IPV6 2
217 #define NSIP_IP_VERSION_4 4
218 #define NSIP_IP_VERSION_6 6
220 #define NSIP_MASK_CONTROL_BITS_R 0x01
221 #define NSIP_MASK_CONTROL_BITS_C 0x02
222 #define NSIP_MASK_END_FLAG 0x01
223 #define NSIP_MASK_RESET_FLAG 0x01
225 static dissector_handle_t bssgp_handle;
226 static dissector_handle_t nsip_handle;
232 guint16 value_length; /* in bytes */
233 guint16 total_length; /* as specified, or 0 if unspecified */
240 proto_tree *nsip_tree;
241 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 };
253 static true_false_string set_unset = {
259 get_value_length(nsip_ie_t *ie, build_info_t *bi) {
260 /* length indicator in bit 8, 0 => two bytes, 1 => one byte */
261 const guint8 MASK_LENGTH_INDICATOR = 0x80;
262 const guint8 MASK_ONE_BYTE_LENGTH = 0x7f;
266 length = tvb_get_guint8(bi->tvb, bi->offset);
269 if (length & MASK_LENGTH_INDICATOR) {
270 length &= MASK_ONE_BYTE_LENGTH;
275 length |= tvb_get_guint8(bi->tvb, bi->offset);
277 ie->value_length = length;
278 ie->total_length += length_len + length;
279 bi->offset += length_len;
283 check_correct_iei(nsip_ie_t *ie, build_info_t *bi) {
284 guint8 fetched_iei = tvb_get_guint8(bi->tvb, bi->offset);
287 if (fetched_iei != ie->iei) {
288 proto_tree_add_text(bi->nsip_tree, bi->tvb, bi->offset, 1,
289 "Tried IEI %s (%#02x), found IEI %s (%#02x)",
290 val_to_str(ie->iei, tab_nsip_ieis, "Unknown"),
292 val_to_str(fetched_iei, tab_nsip_ieis, "Unknown"),
296 return (fetched_iei == ie->iei);
300 decode_iei_cause(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
304 cause = tvb_get_guint8(bi->tvb, bi->offset);
305 proto_tree_add_uint_format(bi->nsip_tree, hf_nsip_cause,
306 bi->tvb, ie_start_offset, ie->total_length,
309 val_to_str(cause, tab_nsip_cause_values,
312 bi->offset += ie->value_length;
316 decode_iei_ns_vci(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
320 ns_vci = tvb_get_ntohs(bi->tvb, bi->offset);
322 proto_tree_add_uint_format(bi->nsip_tree, hf_nsip_ns_vci,
323 bi->tvb, ie_start_offset, ie->total_length,
325 "NS VCI: %#04x", ns_vci);
327 bi->offset += ie->value_length;
331 decode_iei_ns_pdu(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
335 proto_tree_add_text(bi->nsip_tree, bi->tvb, ie_start_offset,
337 "NS PDU (%u bytes)", ie->value_length);
339 next_tvb = tvb_new_subset(bi->tvb, bi->offset, ie->value_length, -1);
341 call_dissector(nsip_handle, next_tvb, bi->pinfo, bi->nsip_tree);
344 bi->offset += ie->value_length;
349 decode_iei_nsei(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
350 guint16 nsei = tvb_get_ntohs(bi->tvb, bi->offset);
353 proto_tree_add_uint(bi->nsip_tree, hf_nsip_nsei, bi->tvb,
354 ie_start_offset, ie->total_length, nsei);
356 bi->offset += ie->value_length;
358 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
359 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
365 decode_iei_bvci(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
366 guint16 bvci = tvb_get_ntohs(bi->tvb, bi->offset);
369 proto_tree_add_uint(bi->nsip_tree, hf_nsip_bvci, bi->tvb,
370 ie_start_offset, ie->total_length, bvci);
372 bi->offset += ie->value_length;
374 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
375 col_append_sep_fstr(bi->pinfo->cinfo, COL_INFO, NSIP_SEP,
381 decode_ip_element(nsip_ip_element_info_t *element, build_info_t *bi, proto_tree * element_tree) {
384 struct e_in6_addr ip6_addr;
385 proto_item *tf = NULL;
386 proto_tree *field_tree = NULL;
389 tf = proto_tree_add_text(element_tree, bi->tvb, bi->offset,
390 element->total_length, "IP Element");
391 field_tree = proto_item_add_subtree(tf, ett_nsip_ip_element);
394 switch (element->version) {
395 case NSIP_IP_VERSION_4:
396 tvb_memcpy(bi->tvb, (guint8 *)&ip4_addr, bi->offset,
397 element->address_length);
398 proto_tree_add_item(field_tree, hf_nsip_ip_address_ipv4,
399 bi->tvb, bi->offset, element->address_length,
401 proto_item_append_text(tf, ": IP address: %s",
402 ip_to_str((guint8 *)&ip4_addr));
405 case NSIP_IP_VERSION_6:
406 tvb_memcpy(bi->tvb, (guint8 *)&ip6_addr, bi->offset,
407 sizeof(struct e_in6_addr));
408 proto_tree_add_item(field_tree, hf_nsip_ip_address_ipv6, bi->tvb,
409 bi->offset, element->address_length,
411 proto_item_append_text(tf, ": IP address: %s",
412 ip6_to_str((struct e_in6_addr *)&ip6_addr));
418 bi->offset += element->address_length;
422 udp_port = tvb_get_ntohs(bi->tvb, bi->offset);
423 proto_tree_add_uint_format(field_tree, hf_nsip_ip_element_udp_port,
424 bi->tvb, bi->offset, 2, udp_port,
425 "UDP Port: %u", udp_port);
426 proto_item_append_text(tf, ", UDP Port: %u", udp_port);
431 /* Signalling weight */
432 proto_tree_add_item(field_tree, hf_nsip_ip_element_signalling_weight,
433 bi->tvb, bi->offset, 1, NSIP_LITTLE_ENDIAN);
439 proto_tree_add_item(field_tree, hf_nsip_ip_element_data_weight,
440 bi->tvb, bi->offset, 1, NSIP_LITTLE_ENDIAN);
447 decode_ip_elements(nsip_ip_element_info_t *element, nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
449 int num_elements = ie->value_length / element->total_length;
450 proto_item *tf, *ti = NULL;
451 proto_tree *field_tree;
453 tf = proto_tree_add_text(bi->nsip_tree, bi->tvb, ie_start_offset,
455 "List of IP%u Elements (%u Elements)",
456 element->version, num_elements);
457 field_tree = proto_item_add_subtree(tf, ett_nsip_ip_element_list);
459 for (i = 0; i < num_elements; i++) {
460 ti = decode_ip_element(element, bi, field_tree);
466 decode_iei_max_num_ns_vc(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
470 num_ns_vc = tvb_get_ntohs(bi->tvb, bi->offset);
472 proto_tree_add_uint_format(bi->nsip_tree, hf_nsip_max_num_ns_vc,
473 bi->tvb, ie_start_offset, ie->total_length,
475 "Maximum Number of NS-VCs: %u", num_ns_vc);
481 decode_iei_num_ip4_endpoints(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
482 guint16 num_endpoints;
485 num_endpoints = tvb_get_ntohs(bi->tvb, bi->offset);
487 proto_tree_add_uint_format(bi->nsip_tree, hf_nsip_num_ip4_endpoints,
488 bi->tvb, ie_start_offset, ie->total_length,
490 "Number of IP4 Endpoints: %u", num_endpoints);
496 decode_iei_num_ip6_endpoints(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
497 guint16 num_endpoints;
500 num_endpoints = tvb_get_ntohs(bi->tvb, bi->offset);
502 proto_tree_add_uint_format(bi->nsip_tree, hf_nsip_num_ip6_endpoints,
503 bi->tvb, ie_start_offset, ie->total_length,
505 "Number of IP6 Endpoints: %u", num_endpoints);
511 decode_iei_reset_flag(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
513 flag = tvb_get_guint8(bi->tvb, bi->offset);
516 proto_tree_add_boolean(bi->nsip_tree, hf_nsip_reset_flag, bi->tvb,
517 ie_start_offset, ie->total_length,
518 flag & NSIP_MASK_RESET_FLAG);
524 decode_iei_ip_address(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
527 struct e_in6_addr ip6_addr;
529 address_type = tvb_get_guint8(bi->tvb, bi->offset);
530 switch (address_type) {
531 case NSIP_IP_ADDRESS_TYPE_IPV4:
532 ie->total_length = 2 + ipv4_element.address_length;
533 tvb_memcpy(bi->tvb, (guint8 *)&ip4_addr, bi->offset,
534 ipv4_element.address_length);
536 proto_tree_add_ipv4(bi->nsip_tree, hf_nsip_ip_address_ipv4,
537 bi->tvb, ie_start_offset, ie->total_length,
541 case NSIP_IP_ADDRESS_TYPE_IPV6:
542 ie->total_length = 2 + ipv6_element.address_length;
543 tvb_memcpy(bi->tvb, (guint8 *)&ip6_addr, bi->offset,
544 sizeof(struct e_in6_addr));
546 proto_tree_add_ipv6(bi->nsip_tree, hf_nsip_ip_address_ipv4,
547 bi->tvb, ie_start_offset, ie->total_length,
548 (guint8 *)&ip6_addr);
554 bi->offset += ie->value_length;
558 decode_iei_transaction_id(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
561 id = tvb_get_guint8(bi->tvb, bi->offset);
562 proto_tree_add_uint(bi->nsip_tree, hf_nsip_transaction_id,
563 bi->tvb, ie_start_offset, ie->total_length, id);
569 decode_iei_end_flag(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
572 flag = tvb_get_guint8(bi->tvb, bi->offset);
573 proto_tree_add_boolean(bi->nsip_tree, hf_nsip_end_flag, bi->tvb,
574 ie_start_offset, ie->total_length,
575 flag & NSIP_MASK_END_FLAG);
581 decode_iei_control_bits(nsip_ie_t *ie, build_info_t *bi, int ie_start_offset) {
584 proto_tree *field_tree;
586 control_bits = tvb_get_guint8(bi->tvb, bi->offset);
589 tf = proto_tree_add_text(bi->nsip_tree, bi->tvb, ie_start_offset,
591 "NS SDU Control bits: %#02x", control_bits);
593 field_tree = proto_item_add_subtree(tf, ett_nsip_control_bits);
594 proto_tree_add_boolean(field_tree, hf_nsip_control_bits_r, bi->tvb,
596 control_bits & NSIP_MASK_CONTROL_BITS_R);
597 proto_tree_add_boolean(field_tree, hf_nsip_control_bits_c, bi->tvb,
599 control_bits & NSIP_MASK_CONTROL_BITS_C);
603 if (check_col(bi->pinfo->cinfo, COL_INFO)) {
604 if (control_bits & NSIP_MASK_CONTROL_BITS_R) {
605 col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Req CF");
608 if (control_bits & NSIP_MASK_CONTROL_BITS_C) {
609 col_append_sep_str(bi->pinfo->cinfo, COL_INFO, NSIP_SEP, "Conf CF");
616 decode_ie(nsip_ie_t *ie, build_info_t *bi) {
618 int org_offset = bi->offset;
620 if (tvb_length_remaining(bi->tvb, bi->offset) < 1) {
623 switch (ie->format) {
624 case NSIP_IE_FORMAT_TLV:
625 if (!check_correct_iei(ie, bi)) {
628 bi->offset++; /* Account for type */
629 ie->total_length = 1;
630 get_value_length(ie, bi);
632 case NSIP_IE_FORMAT_TV:
633 if (!check_correct_iei(ie, bi)) {
636 bi->offset++; /* Account for type */
637 ie->value_length = ie->total_length - 1;
639 case NSIP_IE_FORMAT_V:
640 ie->value_length = ie->total_length;
646 decode_iei_cause(ie, bi, org_offset);
649 decode_iei_ns_vci(ie, bi, org_offset);
652 decode_iei_ns_pdu(ie, bi, org_offset);
655 decode_iei_nsei(ie, bi, org_offset);
658 decode_iei_bvci(ie, bi, org_offset);
660 case NSIP_IE_IP4_ELEMENTS:
661 decode_ip_elements(&ipv4_element, ie, bi, org_offset);
663 case NSIP_IE_IP6_ELEMENTS:
664 decode_ip_elements(&ipv6_element, ie, bi, org_offset);
666 case NSIP_IE_MAX_NUM_NS_VC:
667 decode_iei_max_num_ns_vc(ie, bi, org_offset);
669 case NSIP_IE_NUM_IP4_ENDPOINTS:
670 decode_iei_num_ip4_endpoints(ie, bi, org_offset);
672 case NSIP_IE_NUM_IP6_ENDPOINTS:
673 decode_iei_num_ip6_endpoints(ie, bi, org_offset);
675 case NSIP_IE_RESET_FLAG:
676 decode_iei_reset_flag(ie, bi, org_offset);
678 case NSIP_IE_IP_ADDRESS:
679 decode_iei_ip_address(ie, bi, org_offset);
687 decode_pdu_general(nsip_ie_t *ies, int num_ies, build_info_t *bi) {
689 for (i = 0; i < num_ies; i++) {
690 decode_ie(&ies[i], bi);
695 decode_pdu_ns_unitdata(build_info_t *bi) {
699 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Control bits */
700 { NSIP_IE_BVCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 2 },
701 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 0 },
702 /* NS SDU, length unknown */
706 decode_iei_control_bits(ies, bi, bi->offset);
707 decode_pdu_general(&ies[1], 1, bi);
709 next_tvb = tvb_new_subset(bi->tvb, bi->offset, -1, -1);
711 call_dissector(bssgp_handle, next_tvb, bi->pinfo, bi->parent_tree);
714 sdu_length = tvb_length_remaining(bi->tvb, bi->offset);
715 proto_tree_add_text(bi->nsip_tree, bi->tvb, bi->offset, sdu_length,
716 "NS SDU (%u bytes)", sdu_length);
721 decode_pdu_ns_reset(build_info_t *bi) {
723 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 3 },
724 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
725 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
727 decode_pdu_general(ies, 3, bi);
731 decode_pdu_ns_reset_ack(build_info_t *bi) {
733 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
734 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
736 decode_pdu_general(ies, 2, bi);
740 decode_pdu_ns_block(build_info_t *bi) {
742 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 3 },
743 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
745 decode_pdu_general(ies, 2, bi);
749 decode_pdu_ns_block_ack(build_info_t *bi) {
750 nsip_ie_t ies[] = { { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V,
752 decode_pdu_general(ies, 1, bi);
756 decode_pdu_ns_status(build_info_t *bi) {
758 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 3 },
759 { NSIP_IE_NS_VCI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
760 { NSIP_IE_NS_PDU, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
762 { NSIP_IE_BVCI, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 4 },
763 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
765 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
768 decode_pdu_general(ies, 6, bi);
772 decode_pdu_sns_ack(build_info_t *bi) {
774 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
775 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
776 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 3 },
777 { NSIP_IE_IP_ADDRESS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV, 0, 0 },
779 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
780 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
782 decode_pdu_general(ies, 1, bi);
783 decode_iei_transaction_id(&ies[1], bi, bi->offset);
784 decode_pdu_general(&ies[2], 4, bi);
788 decode_pdu_sns_add(build_info_t *bi) {
790 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
791 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
792 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
794 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
797 decode_pdu_general(ies, 1, bi);
798 decode_iei_transaction_id(&ies[1], bi, bi->offset);
799 decode_pdu_general(&ies[2], 2, bi);
803 decode_pdu_sns_changeweight(build_info_t *bi) {
805 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
806 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
807 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
809 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
812 decode_pdu_general(ies, 1, bi);
813 decode_iei_transaction_id(&ies[1], bi, bi->offset);
814 decode_pdu_general(&ies[2], 2, bi);
818 decode_pdu_sns_config(build_info_t *bi) {
822 /* According to v. 5.2.0 */
824 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* End flag */
825 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
826 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
828 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
831 decode_iei_end_flag(ies, bi, bi->offset);
832 decode_pdu_general(&ies[1], 3, bi);
834 else { /* According to v. 5.3.0 */
836 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
837 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* End flag */
838 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
839 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
841 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
844 decode_pdu_general(ies, 1, bi);
845 decode_iei_end_flag(&ies[1], bi, bi->offset);
846 decode_pdu_general(&ies[2], 3, bi);
851 decode_pdu_sns_config_ack(build_info_t *bi) {
853 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
854 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 3 },
856 decode_pdu_general(ies, 2, bi);
860 decode_pdu_sns_delete(build_info_t *bi) {
862 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4}, /* CR013 */
863 { 0, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_V, 0, 1 }, /* Transaction id */
864 { NSIP_IE_IP_ADDRESS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV, 0, 0 },
866 { NSIP_IE_IP4_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
867 { NSIP_IE_IP6_ELEMENTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 0 },
869 decode_pdu_general(ies, 1, bi);
870 decode_iei_transaction_id(&ies[1], bi, bi->offset);
871 decode_pdu_general(&ies[2], 3, bi);
875 decode_pdu_sns_size(build_info_t *bi) {
877 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
878 { NSIP_IE_RESET_FLAG, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TV, 0, 2 },
879 { NSIP_IE_MAX_NUM_NS_VC, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TV, 0, 3 },
880 { NSIP_IE_NUM_IP4_ENDPOINTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV,
882 { NSIP_IE_NUM_IP6_ENDPOINTS, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TV,
885 decode_pdu_general(ies, 5, bi);
889 decode_pdu_sns_size_ack(build_info_t *bi) {
891 { NSIP_IE_NSEI, NSIP_IE_PRESENCE_M, NSIP_IE_FORMAT_TLV, 0, 4 },
892 { NSIP_IE_CAUSE, NSIP_IE_PRESENCE_C, NSIP_IE_FORMAT_TLV, 0, 3 },
894 decode_pdu_general(ies, 2, bi);
898 decode_pdu(guint8 pdu_type, build_info_t *bi) {
900 case NSIP_PDU_NS_UNITDATA:
901 decode_pdu_ns_unitdata(bi);
903 case NSIP_PDU_NS_RESET:
904 decode_pdu_ns_reset(bi);
906 case NSIP_PDU_NS_RESET_ACK:
907 decode_pdu_ns_reset_ack(bi);
909 case NSIP_PDU_NS_BLOCK:
910 decode_pdu_ns_block(bi);
912 case NSIP_PDU_NS_BLOCK_ACK:
913 decode_pdu_ns_block_ack(bi);
915 case NSIP_PDU_NS_STATUS:
916 decode_pdu_ns_status(bi);
918 case NSIP_PDU_SNS_ACK:
919 decode_pdu_sns_ack(bi);
921 case NSIP_PDU_SNS_ADD:
922 decode_pdu_sns_add(bi);
924 case NSIP_PDU_SNS_CHANGEWEIGHT:
925 decode_pdu_sns_changeweight(bi);
927 case NSIP_PDU_SNS_CONFIG:
928 decode_pdu_sns_config(bi);
930 case NSIP_PDU_SNS_CONFIG_ACK:
931 decode_pdu_sns_config_ack(bi);
933 case NSIP_PDU_SNS_DELETE:
934 decode_pdu_sns_delete(bi);
936 case NSIP_PDU_SNS_SIZE:
937 decode_pdu_sns_size(bi);
939 case NSIP_PDU_SNS_SIZE_ACK:
940 decode_pdu_sns_size_ack(bi);
942 case NSIP_PDU_NS_ALIVE:
943 case NSIP_PDU_NS_ALIVE_ACK:
944 case NSIP_PDU_NS_UNBLOCK:
945 case NSIP_PDU_NS_UNBLOCK_ACK:
946 /* Only contains PDU type, which has already been decoded */
952 dissect_nsip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
954 build_info_t bi = { NULL, 0, NULL, NULL, NULL };
956 proto_tree *nsip_tree;
960 bi.parent_tree = tree;
962 pinfo->current_proto = "NSIP";
964 if (check_col(pinfo->cinfo, COL_PROTOCOL))
965 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NSIP");
967 if (check_col(pinfo->cinfo, COL_INFO))
968 col_clear(pinfo->cinfo, COL_INFO);
970 pdu_type = tvb_get_guint8(tvb, 0);
974 ti = proto_tree_add_item(tree, proto_nsip, tvb, 0, -1,
976 nsip_tree = proto_item_add_subtree(ti, ett_nsip);
977 proto_tree_add_uint_format(nsip_tree, hf_nsip_pdu_type, tvb, 0, 1,
979 "PDU type: %s (%#02x)",
980 val_to_str(pdu_type, tab_nsip_pdu_types,
981 "Unknown"), pdu_type);
982 bi.nsip_tree = nsip_tree;
985 if (check_col(pinfo->cinfo, COL_INFO)) {
986 col_add_str(pinfo->cinfo, COL_INFO,
987 val_to_str(pdu_type, tab_nsip_pdu_types, "Unknown PDU type"));
989 decode_pdu(pdu_type, &bi);
993 proto_register_nsip(void)
995 static hf_register_info hf[] = {
997 { "Cause", "nsip.cause",
998 FT_UINT8, BASE_OCT, VALS(tab_nsip_cause_values), 0x0,
1002 { "NS-VCI", "nsip.ns_vci",
1003 FT_UINT16, BASE_DEC, NULL, 0x0,
1004 "Network Service Virtual Link Identifier", HFILL }
1006 { &hf_nsip_pdu_type,
1007 { "PDU type", "nsip.pdu_type",
1008 FT_UINT8, BASE_OCT, VALS(tab_nsip_pdu_types), 0x0,
1009 "PDU type information element", HFILL }
1012 { "BVCI", "nsip.bvci",
1013 FT_UINT16, BASE_DEC, NULL, 0x0,
1014 "BSSGP Virtual Connection Identifier", HFILL }
1017 { "NSEI", "nsip.nsei",
1018 FT_UINT16, BASE_DEC, NULL, 0x0,
1019 "Network Service Entity Identifier", HFILL }
1021 { &hf_nsip_ip4_elements,
1022 { "IP4 elements", "nsip.ip4_elements",
1023 FT_NONE, BASE_NONE, NULL, 0x0,
1024 "List of IP4 elements", HFILL }
1026 { &hf_nsip_ip6_elements,
1027 { "IP6 elements", "nsip.ip6_elements",
1028 FT_NONE, BASE_NONE, NULL, 0x0,
1029 "List of IP6 elements", HFILL }
1031 { &hf_nsip_max_num_ns_vc,
1032 { "Maximum number of NS-VCs", "nsip.max_num_ns_vc",
1033 FT_UINT16, BASE_DEC, NULL, 0x0,
1036 { &hf_nsip_num_ip4_endpoints,
1037 { "Number of IP4 endpoints", "nsip.num_ip4_endpoints",
1038 FT_UINT16, BASE_DEC, NULL, 0x0,
1041 { &hf_nsip_num_ip6_endpoints,
1042 { "Number of IP6 endpoints", "nsip.num_ip6_endpoints",
1043 FT_UINT16, BASE_DEC, NULL, 0x0,
1046 { &hf_nsip_reset_flag,
1047 { "Reset flag", "nsip.reset_flag",
1048 FT_BOOLEAN, 8, TFS(&set_unset), NSIP_MASK_RESET_FLAG,
1051 { &hf_nsip_ip_address_ipv4,
1052 { "IP Address", "nsip.ip_address",
1053 FT_IPv4, BASE_NONE, NULL, 0x0,
1056 { &hf_nsip_ip_address_ipv6,
1057 { "IP Address", "nsip.ip_address",
1058 FT_IPv6, BASE_NONE, NULL, 0x0,
1061 { &hf_nsip_end_flag,
1062 { "End flag", "nsip.end_flag",
1063 FT_BOOLEAN, 8, TFS(&set_unset), NSIP_MASK_END_FLAG,
1066 { &hf_nsip_control_bits_r,
1067 { "Request change flow", "nsip.control_bits.r",
1068 FT_BOOLEAN, 8, TFS(&set_unset), NSIP_MASK_CONTROL_BITS_R,
1071 { &hf_nsip_control_bits_c,
1072 { "Confirm change flow", "nsip.control_bits.c",
1073 FT_BOOLEAN, 8, TFS(&set_unset), NSIP_MASK_CONTROL_BITS_C,
1076 { &hf_nsip_transaction_id,
1077 { "Transaction ID", "nsip.transaction_id",
1078 FT_UINT8, BASE_DEC, NULL, 0x0,
1081 { &hf_nsip_ip_element_ip_address_ipv4,
1082 { "IP Address", "nsip.ip_element.ip_address",
1083 FT_IPv4, BASE_NONE, NULL, 0x0,
1086 { &hf_nsip_ip_element_ip_address_ipv6,
1087 { "IP Address", "nsip.ip_element.ip_address",
1088 FT_IPv6, BASE_NONE, NULL, 0x0,
1091 { &hf_nsip_ip_element_udp_port,
1092 { "UDP Port", "nsip.ip_element.udp_port",
1093 FT_UINT16, BASE_DEC, NULL, 0x0,
1096 { &hf_nsip_ip_element_signalling_weight,
1097 { "Signalling Weight", "nsip.ip_element.signalling_weight",
1098 FT_UINT8, BASE_DEC, NULL, 0x0,
1101 { &hf_nsip_ip_element_data_weight,
1102 { "Data Weight", "nsip.ip_element.data_weight",
1103 FT_UINT8, BASE_DEC, NULL, 0x0,
1108 /* Setup protocol subtree array */
1109 static gint *ett[] = {
1111 &ett_nsip_control_bits,
1112 &ett_nsip_ip_element,
1113 &ett_nsip_ip_element_list,
1116 module_t *nsip_module;
1118 /* Register the protocol name and description */
1119 proto_nsip = proto_register_protocol("Network Service Over IP",
1122 /* Required function calls to register the header fields and
1124 proto_register_field_array(proto_nsip, hf, array_length(hf));
1125 proto_register_subtree_array(ett, array_length(ett));
1127 register_dissector("nsip", dissect_nsip, proto_nsip);
1129 /* Register configuration options */
1130 nsip_module = prefs_register_protocol(proto_nsip, proto_reg_handoff_nsip);
1131 prefs_register_uint_preference(nsip_module, "udp.port1", "NSIP UDP Port 1",
1132 "Set the first UDP port",
1133 10, &nsip_udp_port1);
1134 prefs_register_uint_preference(nsip_module, "udp.port2", "NSIP UDP Port 2",
1135 "Set the second UDP port",
1136 10, &nsip_udp_port2);
1140 proto_reg_handoff_nsip(void) {
1141 static int nsip_prefs_initialized = FALSE;
1143 nsip_handle = create_dissector_handle(dissect_nsip, proto_nsip);
1145 if (DECODE_AS_NSIP) {
1146 dissector_add("udp.port", NSIP_UDP_PORT1, nsip_handle);
1147 dissector_add("udp.port", NSIP_UDP_PORT2, nsip_handle);
1150 dissector_add_handle("udp.port", nsip_handle);
1154 if (!nsip_prefs_initialized) {
1155 nsip_handle = create_dissector_handle(dissect_nsip, proto_nsip);
1156 nsip_prefs_initialized = TRUE;
1159 dissector_delete("udp.port", nsip_udp_port1, nsip_handle);
1160 dissector_delete("udp.port", nsip_udp_port2, nsip_handle);
1162 global_nsip_udp_port1 = nsip_udp_port1;
1163 global_nsip_udp_port2 = nsip_udp_port2;
1165 dissector_add("udp.port", global_nsip_udp_port1, nsip_handle);
1166 dissector_add("udp.port", global_nsip_udp_port2, nsip_handle);
1168 bssgp_handle = find_dissector("bssgp");