2 * Routines for Xpress Transport Protocol dissection
3 * Copyright 2008, Shigeo Nakamura <naka_shigeo@yahoo.co.jp>
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.
25 * Ref: http://www.packeteer.com/resources/prod-sol/XTP.pdf
32 #include <epan/packet.h>
33 #include <epan/exceptions.h>
34 #include <epan/expert.h>
35 #include <epan/ipproto.h>
36 #include <epan/in_cksum.h>
37 #include <epan/wmem/wmem.h>
40 #define XTP_VERSION_4 0x001
42 /* XTP type of Service */
43 #define XTP_TOS_UNSPEC 0
44 #define XTP_TOS_UNACKED_DGRAM 1
45 #define XTP_TOS_ACKED_DGRAM 2
46 #define XTP_TOS_TRANS 3
47 #define XTP_TOS_UNICAST_STREAM 4
48 #define XTP_TOS_UNACKED_MULTICAST_STREAM 5
49 #define XTP_TOS_MULTICAST_STREAM 6
52 #define XTP_ADDR_NULL 0
54 #define XTP_ADDR_ISO 2
55 #define XTP_ADDR_XEROX 3
56 #define XTP_ADDR_IPX 4
57 #define XTP_ADDR_LOCAL 5
58 #define XTP_ADDR_IP6 6
61 #define XTP_DATA_PKT 0
62 #define XTP_CNTL_PKT 1
63 #define XTP_FIRST_PKT 2
64 #define XTP_ECNTL_PKT 3
65 #define XTP_TCNTL_PKT 5
66 #define XTP_JOIN_PKT 6
67 #define XTP_JCNTL_PKT 7
68 #define XTP_DIAG_PKT 8
70 /* cmd options mask */
71 #define XTP_CMD_OPTIONS_NOCHECK 0x400000
72 #define XTP_CMD_OPTIONS_EDGE 0x200000
73 #define XTP_CMD_OPTIONS_NOERR 0x100000
74 #define XTP_CMD_OPTIONS_MULTI 0x080000
75 #define XTP_CMD_OPTIONS_RES 0x040000
76 #define XTP_CMD_OPTIONS_SORT 0x020000
77 #define XTP_CMD_OPTIONS_NOFLOW 0x010000
78 #define XTP_CMD_OPTIONS_FASTNAK 0x008000
79 #define XTP_CMD_OPTIONS_SREQ 0x004000
80 #define XTP_CMD_OPTIONS_DREQ 0x002000
81 #define XTP_CMD_OPTIONS_RCLOSE 0x001000
82 #define XTP_CMD_OPTIONS_WCLOSE 0x000800
83 #define XTP_CMD_OPTIONS_EOM 0x000400
84 #define XTP_CMD_OPTIONS_END 0x000200
85 #define XTP_CMD_OPTIONS_BTAG 0x000100
87 #define XTP_KEY_RTN ((guint64)1<<63)
89 /** packet structures definition **/
95 #define XTP_CNTL_PKT_LEN 20
103 #define MIN_XTP_ECNTL_PKT_LEN 24
105 struct xtp_traffic_cntl
{
112 #define XTP_TRAFFIC_CNTL_LEN 32
115 struct xtp_traffic_spec0
{
121 #define XTP_TRAFFIC_SPEC0_LEN 8
124 struct xtp_traffic_spec1
{
134 #define XTP_TRAFFIC_SPEC1_LEN 24
136 struct xtp_ip_addr_seg
{
145 #define XTP_IP_ADDR_SEG_LEN 16
146 #define XTP_NULL_ADDR_SEG_LEN 8
153 #define XTP_DIAG_PKT_HEADER_LEN 8
158 guint32 cmd_options
; /* 24 bits */
160 guint8 cmd_ptype_ver
; /* 3 bits */
161 guint8 cmd_ptype_pformat
; /* 5 bits */
168 #define XTP_HEADER_LEN 32
171 static const value_string version_vals
[] = {
172 { XTP_VERSION_4
, "XTP version 4.0" },
176 static const value_string service_vals
[] = {
177 { XTP_TOS_UNSPEC
, "Unspecified" },
178 { XTP_TOS_UNACKED_DGRAM
, "Traditional Unacknowledged Datagram Service" },
179 { XTP_TOS_ACKED_DGRAM
, "Acknowledged Datagram Service" },
180 { XTP_TOS_TRANS
, "Transaction Service" },
181 { XTP_TOS_UNICAST_STREAM
, "Traditional Reliable Unicast Stream Service" },
182 { XTP_TOS_UNACKED_MULTICAST_STREAM
, "Unacknowledged Multicast Stream Service" },
183 { XTP_TOS_MULTICAST_STREAM
, "Reliable Multicast Stream Service" },
187 static const value_string aformat_vals
[] = {
188 { XTP_ADDR_NULL
, "Null Address" },
189 { XTP_ADDR_IP
, "Internet Protocol Address" },
190 { XTP_ADDR_ISO
, "ISO Connectionless Network Layer Protocol Address" },
191 { XTP_ADDR_XEROX
, "Xerox Network System Address" },
192 { XTP_ADDR_IPX
, "IPX Address" },
193 { XTP_ADDR_LOCAL
, "Local Address" },
194 { XTP_ADDR_IP6
, "Internet Protocol Version 6 Address" },
198 static const value_string pformat_vals
[] = {
199 { XTP_DATA_PKT
, "DATA" },
200 { XTP_CNTL_PKT
, "CNTL" },
201 { XTP_FIRST_PKT
, "FIRST" },
202 { XTP_ECNTL_PKT
, "ECNTL" },
203 { XTP_TCNTL_PKT
, "TCNTL" },
204 { XTP_JOIN_PKT
, "JOIN<obsolete>" },
205 { XTP_JCNTL_PKT
, "JCNTL" },
206 { XTP_DIAG_PKT
, "DIAG" },
210 static const value_string diag_code_vals
[] = {
211 { 1, "Context Refused" },
212 { 2, "Context Abandoned" },
213 { 3, "Invalid Context" },
214 { 4, "Request Refused" },
215 { 5, "Join Refused" },
216 { 6, "Protocol Error" },
217 { 7, "Maximum Packet Size Error" },
221 static const value_string diag_val_vals
[] = {
222 { 0, "Unspecified" },
223 { 1, "No listener" },
224 { 2, "Options refused" },
225 { 3, "Address format not supported" },
226 { 4, "Malformed address format" },
227 { 5, "Traffic format not supported" },
228 { 6, "Traffic specification refused" },
229 { 7, "Malformed traffic format" },
230 { 8, "No provider for service" },
231 { 9, "No resource" },
232 { 10, "Host going down" },
233 { 11, "Invalid retransmission request" },
234 { 12, "Context in improper state" },
235 { 13, "Join request denied" },
239 /* Initialize the protocol and registered fields */
240 static int proto_xtp
= -1;
242 static int hf_xtp_key
= -1;
243 static int hf_xtp_cmd
= -1;
244 static int hf_xtp_cmd_options
= -1;
245 static int hf_xtp_cmd_options_nocheck
= -1;
246 static int hf_xtp_cmd_options_edge
= -1;
247 static int hf_xtp_cmd_options_noerr
= -1;
248 static int hf_xtp_cmd_options_multi
= -1;
249 static int hf_xtp_cmd_options_res
= -1;
250 static int hf_xtp_cmd_options_sort
= -1;
251 static int hf_xtp_cmd_options_noflow
= -1;
252 static int hf_xtp_cmd_options_fastnak
= -1;
253 static int hf_xtp_cmd_options_sreq
= -1;
254 static int hf_xtp_cmd_options_dreq
= -1;
255 static int hf_xtp_cmd_options_rclose
= -1;
256 static int hf_xtp_cmd_options_wclose
= -1;
257 static int hf_xtp_cmd_options_eom
= -1;
258 static int hf_xtp_cmd_options_end
= -1;
259 static int hf_xtp_cmd_options_btag
= -1;
260 static int hf_xtp_cmd_ptype
= -1;
261 static int hf_xtp_cmd_ptype_ver
= -1;
262 static int hf_xtp_cmd_ptype_pformat
= -1;
263 static int hf_xtp_dlen
= -1;
264 static int hf_xtp_sort
= -1;
265 static int hf_xtp_sync
= -1;
266 static int hf_xtp_seq
= -1;
267 /* control segment */
268 static int hf_xtp_cntl_rseq
= -1;
269 static int hf_xtp_cntl_alloc
= -1;
270 static int hf_xtp_cntl_echo
= -1;
271 static int hf_xtp_ecntl_rseq
= -1;
272 static int hf_xtp_ecntl_alloc
= -1;
273 static int hf_xtp_ecntl_echo
= -1;
274 static int hf_xtp_ecntl_nspan
= -1;
275 static int hf_xtp_ecntl_span_left
= -1;
276 static int hf_xtp_ecntl_span_right
= -1;
277 static int hf_xtp_tcntl_rseq
= -1;
278 static int hf_xtp_tcntl_alloc
= -1;
279 static int hf_xtp_tcntl_echo
= -1;
280 static int hf_xtp_tcntl_rsvd
= -1;
281 static int hf_xtp_tcntl_xkey
= -1;
282 /* traffic specifier */
283 static int hf_xtp_tspec_tlen
= -1;
284 static int hf_xtp_tspec_service
= -1;
285 static int hf_xtp_tspec_tformat
= -1;
286 static int hf_xtp_tspec_traffic
= -1;
287 static int hf_xtp_tspec_maxdata
= -1;
288 static int hf_xtp_tspec_inrate
= -1;
289 static int hf_xtp_tspec_outrate
= -1;
290 static int hf_xtp_tspec_inburst
= -1;
291 static int hf_xtp_tspec_outburst
= -1;
292 /* address segment */
293 static int hf_xtp_aseg_alen
= -1;
294 static int hf_xtp_aseg_adomain
= -1;
295 static int hf_xtp_aseg_aformat
= -1;
296 static int hf_xtp_aseg_address
= -1;
297 static int hf_xtp_aseg_dsthost
= -1;
298 static int hf_xtp_aseg_srchost
= -1;
299 static int hf_xtp_aseg_dstport
= -1;
300 static int hf_xtp_aseg_srcport
= -1;
302 static int hf_xtp_btag
= -1;
303 static int hf_xtp_diag_code
= -1;
304 static int hf_xtp_diag_val
= -1;
305 static int hf_xtp_diag_msg
= -1;
307 /* Initialize the subtree pointers */
308 static gint ett_xtp
= -1;
309 static gint ett_xtp_cmd
= -1;
310 static gint ett_xtp_cmd_options
= -1;
311 static gint ett_xtp_cmd_ptype
= -1;
312 static gint ett_xtp_cntl
= -1;
313 static gint ett_xtp_ecntl
= -1;
314 static gint ett_xtp_tcntl
= -1;
315 static gint ett_xtp_tspec
= -1;
316 static gint ett_xtp_jcntl
= -1;
317 static gint ett_xtp_first
= -1;
318 static gint ett_xtp_aseg
= -1;
319 static gint ett_xtp_data
= -1;
320 static gint ett_xtp_diag
= -1;
322 static expert_field ei_xtp_spans_bad
= EI_INIT
;
324 /* dissector of each payload */
326 dissect_xtp_aseg(tvbuff_t
*tvb
, proto_tree
*tree
, guint32 offset
) {
327 guint32 len
= tvb_length_remaining(tvb
, offset
);
328 guint32 start
= offset
;
329 proto_item
*ti
, *ti2
, *top_ti
;
330 proto_tree
*xtp_subtree
;
331 struct xtp_ip_addr_seg aseg
[1];
334 top_ti
= proto_tree_add_text(tree
, tvb
, offset
, len
, "Address Segment");
335 xtp_subtree
= proto_item_add_subtree(top_ti
, ett_xtp_aseg
);
337 if (len
< XTP_NULL_ADDR_SEG_LEN
) {
338 proto_item_append_text(top_ti
, ", bogus length(%u, must be at least %u)",
339 len
, XTP_NULL_ADDR_SEG_LEN
);
343 /** parse common fields **/
345 aseg
->alen
= tvb_get_ntohs(tvb
, offset
);
348 aseg
->adomain
= tvb_get_guint8(tvb
, offset
);
351 aseg
->aformat
= tvb_get_guint8(tvb
, offset
);
353 /** display common fields **/
356 ti
= proto_tree_add_uint(xtp_subtree
, hf_xtp_aseg_alen
,
357 tvb
, offset
, 2, aseg
->alen
);
359 if (aseg
->alen
> len
) {
360 proto_item_append_text(ti
, ", bogus length(%u, must be at most %u)",
365 proto_tree_add_uint(xtp_subtree
, hf_xtp_aseg_adomain
,
366 tvb
, offset
, 1, aseg
->adomain
);
369 ti2
= proto_tree_add_uint(xtp_subtree
, hf_xtp_aseg_aformat
,
370 tvb
, offset
, 1, aseg
->aformat
);
372 switch (aseg
->aformat
) {
374 if (aseg
->alen
!= XTP_NULL_ADDR_SEG_LEN
) {
375 proto_item_append_text(ti
, ", bogus length(%u, must be %u)",
376 aseg
->alen
, XTP_NULL_ADDR_SEG_LEN
);
381 if (aseg
->alen
!= XTP_IP_ADDR_SEG_LEN
) {
382 proto_item_append_text(ti
, ", bogus length(%u, must be %u)",
383 aseg
->alen
, XTP_IP_ADDR_SEG_LEN
);
388 if (aseg
->aformat
< 128) {
389 proto_item_append_text(ti2
,
390 ", Unsupported aformat(%u)", aseg
->aformat
);
397 return (offset
- start
);
399 /** parse and display each address fileds */
400 switch (aseg
->aformat
) {
403 aseg
->dsthost
= tvb_get_ntohl(tvb
, offset
);
404 proto_tree_add_uint(xtp_subtree
, hf_xtp_aseg_address
,
405 tvb
, offset
, 4, aseg
->dsthost
);
410 aseg
->dsthost
= tvb_get_ipv4(tvb
, offset
);
411 proto_tree_add_ipv4(xtp_subtree
, hf_xtp_aseg_dsthost
,
412 tvb
, offset
, 4, aseg
->dsthost
);
415 aseg
->srchost
= tvb_get_ipv4(tvb
, offset
);
416 proto_tree_add_ipv4(xtp_subtree
, hf_xtp_aseg_srchost
,
417 tvb
, offset
, 4, aseg
->srchost
);
420 aseg
->dstport
= tvb_get_ntohs(tvb
, offset
);
421 proto_tree_add_uint(xtp_subtree
, hf_xtp_aseg_dstport
,
422 tvb
, offset
, 2, aseg
->dstport
);
425 aseg
->srcport
= tvb_get_ntohs(tvb
, offset
);
426 proto_tree_add_uint(xtp_subtree
, hf_xtp_aseg_srcport
,
427 tvb
, offset
, 2, aseg
->srcport
);
431 proto_item_append_text(top_ti
, ", Dst Port: %u", aseg
->dstport
);
432 proto_item_append_text(top_ti
, ", Src Port: %u", aseg
->srcport
);
438 return (offset
- start
);
442 dissect_xtp_traffic_cntl(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
444 guint32 len
= tvb_length_remaining(tvb
, offset
);
445 guint32 start
= offset
;
447 proto_tree
*xtp_subtree
;
448 struct xtp_traffic_cntl tcntl
[1];
450 top_ti
= proto_tree_add_text(tree
, tvb
, offset
, len
,
451 "Traffic Control Segment");
452 xtp_subtree
= proto_item_add_subtree(top_ti
, ett_xtp_tcntl
);
454 if (len
< XTP_TRAFFIC_CNTL_LEN
) {
455 proto_item_append_text(top_ti
,
456 ", bogus length(%u, must be at least %u)",
457 len
, XTP_TRAFFIC_CNTL_LEN
);
463 tcntl
->rseq
= tvb_get_ntohl(tvb
, offset
);
465 tcntl
->rseq
+= tvb_get_ntohl(tvb
, offset
+4);
468 tcntl
->alloc
= tvb_get_ntohl(tvb
, offset
);
470 tcntl
->alloc
+= tvb_get_ntohl(tvb
, offset
+4);
473 tcntl
->echo
= tvb_get_ntohl(tvb
, offset
);
476 tcntl
->rsvd
= tvb_get_ntohl(tvb
, offset
);
479 tcntl
->xkey
= tvb_get_ntohl(tvb
, offset
);
481 tcntl
->xkey
+= tvb_get_ntohl(tvb
, offset
+4);
484 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
485 " Recv-Seq=%" G_GINT64_MODIFIER
"u", tcntl
->rseq
);
486 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
487 " Alloc=%" G_GINT64_MODIFIER
"u", tcntl
->alloc
);
489 proto_item_append_text(top_ti
,
490 ", Recv-Seq: %" G_GINT64_MODIFIER
"u", tcntl
->rseq
);
495 proto_tree_add_uint64(xtp_subtree
, hf_xtp_tcntl_rseq
,
496 tvb
, offset
, 8, tcntl
->rseq
);
499 proto_tree_add_uint64(xtp_subtree
, hf_xtp_tcntl_alloc
,
500 tvb
, offset
, 8, tcntl
->alloc
);
503 proto_tree_add_uint(xtp_subtree
, hf_xtp_tcntl_echo
,
504 tvb
, offset
, 4, tcntl
->echo
);
507 proto_tree_add_uint(xtp_subtree
, hf_xtp_tcntl_rsvd
,
508 tvb
, offset
, 4, tcntl
->rsvd
);
511 proto_tree_add_uint64(xtp_subtree
, hf_xtp_tcntl_xkey
,
512 tvb
, offset
, 8, tcntl
->xkey
);
515 return (offset
- start
);
519 dissect_xtp_tspec(tvbuff_t
*tvb
, proto_tree
*tree
, guint32 offset
) {
520 guint32 len
= tvb_length_remaining(tvb
, offset
);
521 guint32 start
= offset
;
522 proto_item
*ti
, *ti2
;
523 proto_tree
*xtp_subtree
;
524 struct xtp_traffic_spec1 tspec
[1];
527 ti
= proto_tree_add_text(tree
, tvb
, offset
, len
, "Traffic Specifier");
528 xtp_subtree
= proto_item_add_subtree(ti
, ett_xtp_tspec
);
530 if (len
< XTP_TRAFFIC_SPEC0_LEN
) {
531 proto_item_append_text(ti
,
532 ", bogus length(%u, must be at least %u)",
533 len
, XTP_TRAFFIC_SPEC0_LEN
);
537 /** parse common fields **/
539 tspec
->tlen
= tvb_get_ntohs(tvb
, offset
);
542 tspec
->service
= tvb_get_guint8(tvb
, offset
);
545 tspec
->tformat
= tvb_get_guint8(tvb
, offset
);
547 /** display common fields */
550 ti
= proto_tree_add_uint(xtp_subtree
, hf_xtp_tspec_tlen
,
551 tvb
, offset
, 2, tspec
->tlen
);
553 if (tspec
->tlen
> len
) {
554 proto_item_append_text(ti
, ", bogus length(%u, must be at most %u)",
559 proto_tree_add_uint(xtp_subtree
, hf_xtp_tspec_service
,
560 tvb
, offset
, 1, tspec
->service
);
563 ti2
= proto_tree_add_uint(xtp_subtree
, hf_xtp_tspec_tformat
,
564 tvb
, offset
, 1, tspec
->tformat
);
566 switch (tspec
->tformat
) {
568 if (tspec
->tlen
!= XTP_TRAFFIC_SPEC0_LEN
) {
569 proto_item_append_text(ti
, ", bogus length(%u, must be %u)",
570 tspec
->tlen
, XTP_TRAFFIC_SPEC0_LEN
);
575 if (tspec
->tlen
!= XTP_TRAFFIC_SPEC1_LEN
) {
576 proto_item_append_text(ti
, ", bogus length(%u, must be %u)",
577 tspec
->tlen
, XTP_TRAFFIC_SPEC1_LEN
);
582 proto_item_append_text(ti2
, ", Unsupported tformat(%u)",
589 return (offset
- start
);
591 /** parse and display each traffic fields **/
592 switch (tspec
->tformat
) {
595 tspec
->maxdata
= tvb_get_ntohl(tvb
, offset
);
596 proto_tree_add_uint(xtp_subtree
, hf_xtp_tspec_traffic
,
597 tvb
, offset
, 4, tspec
->maxdata
);
602 tspec
->maxdata
= tvb_get_ntohl(tvb
, offset
);
603 proto_tree_add_uint(xtp_subtree
, hf_xtp_tspec_maxdata
,
604 tvb
, offset
, 4, tspec
->maxdata
);
607 tspec
->inrate
= tvb_get_ntohl(tvb
, offset
);
608 proto_tree_add_uint(xtp_subtree
, hf_xtp_tspec_inrate
,
609 tvb
, offset
, 4, tspec
->inrate
);
612 tspec
->inburst
= tvb_get_ntohl(tvb
, offset
);
613 proto_tree_add_uint(xtp_subtree
, hf_xtp_tspec_inburst
,
614 tvb
, offset
, 4, tspec
->inburst
);
617 tspec
->outrate
= tvb_get_ntohl(tvb
, offset
);
618 proto_tree_add_uint(xtp_subtree
, hf_xtp_tspec_outrate
,
619 tvb
, offset
, 4, tspec
->outrate
);
622 tspec
->outburst
= tvb_get_ntohl(tvb
, offset
);
623 proto_tree_add_uint(xtp_subtree
, hf_xtp_tspec_outburst
,
624 tvb
, offset
, 4, tspec
->outburst
);
631 return (offset
- start
);
635 dissect_xtp_data(tvbuff_t
*tvb
, proto_tree
*tree
, guint32 offset
, gboolean have_btag
) {
636 guint32 len
= tvb_length_remaining(tvb
, offset
);
638 proto_tree
*xtp_subtree
;
641 ti
= proto_tree_add_text(tree
, tvb
, offset
, len
, "Data Segment");
642 xtp_subtree
= proto_item_add_subtree(ti
, ett_xtp_data
);
645 btag
= tvb_get_ntohl(tvb
, offset
);
647 btag
+= tvb_get_ntohl(tvb
, offset
+4);
648 proto_tree_add_uint64(xtp_subtree
, hf_xtp_btag
, tvb
, offset
, 8, btag
);
653 proto_tree_add_text(xtp_subtree
, tvb
, offset
, len
,
654 "Data (%u byte%s)", len
,
655 plurality(len
, "", "s"));
661 dissect_xtp_cntl(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
663 guint32 len
= tvb_length_remaining(tvb
, offset
);
664 guint32 start
= offset
;
666 proto_tree
*xtp_subtree
;
667 struct xtp_cntl cntl
[1];
669 top_ti
= proto_tree_add_text(tree
, tvb
, offset
, len
,
670 "Common Control Segment");
671 xtp_subtree
= proto_item_add_subtree(top_ti
, ett_xtp_cntl
);
673 if (len
!= XTP_CNTL_PKT_LEN
) {
674 proto_item_append_text(top_ti
, ", bogus length(%u, must be %u)",
675 len
, XTP_CNTL_PKT_LEN
);
681 cntl
->rseq
= tvb_get_ntohl(tvb
, offset
);
683 cntl
->rseq
+= tvb_get_ntohl(tvb
, offset
+4);
686 cntl
->alloc
= tvb_get_ntohl(tvb
, offset
);
688 cntl
->alloc
+= tvb_get_ntohl(tvb
, offset
+4);
691 cntl
->echo
= tvb_get_ntohl(tvb
, offset
);
694 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
695 " Recv-Seq=%" G_GINT64_MODIFIER
"u", cntl
->rseq
);
696 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
697 " Alloc=%" G_GINT64_MODIFIER
"u", cntl
->alloc
);
699 proto_item_append_text(top_ti
,
700 ", Recv-Seq: %" G_GINT64_MODIFIER
"u", cntl
->rseq
);
705 proto_tree_add_uint64(xtp_subtree
, hf_xtp_cntl_rseq
,
706 tvb
, offset
, 8, cntl
->rseq
);
709 proto_tree_add_uint64(xtp_subtree
, hf_xtp_cntl_alloc
,
710 tvb
, offset
, 8, cntl
->alloc
);
713 proto_tree_add_uint(xtp_subtree
, hf_xtp_cntl_echo
,
714 tvb
, offset
, 4, cntl
->echo
);
720 dissect_xtp_first(tvbuff_t
*tvb
, proto_tree
*tree
, guint32 offset
) {
722 if (!dissect_xtp_aseg(tvb
, tree
, offset
))
725 offset
+= XTP_IP_ADDR_SEG_LEN
;
726 dissect_xtp_tspec(tvb
, tree
, offset
);
731 #define XTP_MAX_NSPANS 10000 /* Arbitrary. (Documentation link is dead.) */
733 dissect_xtp_ecntl(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
735 guint32 len
= tvb_length_remaining(tvb
, offset
);
736 guint32 start
= offset
;
738 proto_tree
*xtp_subtree
;
739 struct xtp_ecntl ecntl
[1];
743 top_ti
= proto_tree_add_text(tree
, tvb
, offset
, len
,
744 "Error Control Segment");
745 xtp_subtree
= proto_item_add_subtree(top_ti
, ett_xtp_ecntl
);
747 if (len
< MIN_XTP_ECNTL_PKT_LEN
) {
748 proto_item_append_text(top_ti
,
749 ", bogus length (%u, must be at least %u)",
750 len
, MIN_XTP_ECNTL_PKT_LEN
);
756 ecntl
->rseq
= tvb_get_ntohl(tvb
, offset
);
758 ecntl
->rseq
+= tvb_get_ntohl(tvb
, offset
+4);
761 ecntl
->alloc
= tvb_get_ntohl(tvb
, offset
);
763 ecntl
->alloc
+= tvb_get_ntohl(tvb
, offset
+4);
766 ecntl
->echo
= tvb_get_ntohl(tvb
, offset
);
769 ecntl
->nspan
= tvb_get_ntohl(tvb
, offset
);
771 len
= len
+ XTP_HEADER_LEN
- offset
;
772 spans_len
= 16 * ecntl
->nspan
;
774 if (len
!= spans_len
) {
775 expert_add_info_format(pinfo
, top_ti
, &ei_xtp_spans_bad
, "Number of spans (%u) incorrect. Should be %u.", ecntl
->nspan
, len
);
776 THROW(ReportedBoundsError
);
779 if (ecntl
->nspan
> XTP_MAX_NSPANS
) {
780 expert_add_info_format(pinfo
, top_ti
, &ei_xtp_spans_bad
, "Too many spans: %u", ecntl
->nspan
);
781 THROW(ReportedBoundsError
);
785 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
786 " Recv-Seq=%" G_GINT64_MODIFIER
"u", ecntl
->rseq
);
787 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
788 " Alloc=%" G_GINT64_MODIFIER
"u", ecntl
->alloc
);
790 proto_item_append_text(top_ti
,
791 ", Recv-Seq: %" G_GINT64_MODIFIER
"u", ecntl
->rseq
);
796 proto_tree_add_uint64(xtp_subtree
, hf_xtp_ecntl_rseq
,
797 tvb
, offset
, 8, ecntl
->rseq
);
800 proto_tree_add_uint64(xtp_subtree
, hf_xtp_ecntl_alloc
,
801 tvb
, offset
, 8, ecntl
->alloc
);
804 proto_tree_add_uint(xtp_subtree
, hf_xtp_ecntl_echo
,
805 tvb
, offset
, 4, ecntl
->echo
);
808 proto_tree_add_uint(xtp_subtree
, hf_xtp_ecntl_nspan
,
809 tvb
, offset
, 4, ecntl
->nspan
);
812 for (i
= 0; i
< ecntl
->nspan
; i
++) {
813 proto_tree_add_item(xtp_subtree
, hf_xtp_ecntl_span_left
,
814 tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
816 proto_tree_add_item(xtp_subtree
, hf_xtp_ecntl_span_right
,
817 tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
825 dissect_xtp_tcntl(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
828 if (!dissect_xtp_traffic_cntl(tvb
, pinfo
, tree
, offset
))
831 offset
+= XTP_TRAFFIC_CNTL_LEN
;
832 dissect_xtp_tspec(tvb
, tree
, offset
);
838 dissect_xtp_jcntl(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
841 if (!dissect_xtp_traffic_cntl(tvb
, pinfo
, tree
, offset
))
844 offset
+= XTP_TRAFFIC_CNTL_LEN
;
845 if (!dissect_xtp_aseg(tvb
, tree
, offset
))
848 offset
+= XTP_IP_ADDR_SEG_LEN
;
849 dissect_xtp_tspec(tvb
, tree
, offset
);
855 dissect_xtp_diag(tvbuff_t
*tvb
, proto_tree
*tree
, guint32 offset
) {
856 guint32 len
= tvb_length_remaining(tvb
, offset
);
857 guint32 start
= offset
;
859 proto_tree
*xtp_subtree
;
860 struct xtp_diag diag
[1];
863 ti
= proto_tree_add_text(tree
, tvb
, offset
, len
, "Diagnostic Segment");
864 xtp_subtree
= proto_item_add_subtree(ti
, ett_xtp_diag
);
866 if (len
< XTP_DIAG_PKT_HEADER_LEN
) {
867 proto_item_append_text(ti
,
868 ", bogus length (%u, must be at least %u)",
869 len
, XTP_DIAG_PKT_HEADER_LEN
);
875 diag
->code
= tvb_get_ntohl(tvb
, offset
);
878 diag
->val
= tvb_get_ntohl(tvb
, offset
);
881 msg_len
= tvb_length_remaining(tvb
, offset
);
882 diag
->msg
= tvb_get_string(NULL
, tvb
, offset
, msg_len
);
887 proto_tree_add_uint(xtp_subtree
, hf_xtp_diag_code
,
888 tvb
, offset
, 4, diag
->code
);
891 proto_tree_add_uint(xtp_subtree
, hf_xtp_diag_val
,
892 tvb
, offset
, 4, diag
->val
);
895 proto_tree_add_string(xtp_subtree
, hf_xtp_diag_msg
,
896 tvb
, offset
, msg_len
, diag
->msg
);
904 dissect_xtp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
) {
907 proto_tree
*xtp_tree
, *xtp_cmd_tree
, *xtp_subtree
;
908 struct xtphdr xtph
[1];
911 static const char *fstr
[] = { "<None>", "NOCHECK", "EDGE", "NOERR", "MULTI", "RES",
912 "SORT", "NOFLOW", "FASTNAK", "SREQ", "DREQ",
913 "RCLOSE", "WCLOSE", "EOM", "END", "BTAG" };
914 gint fpos
= 0, returned_length
;
918 guint16 computed_cksum
;
921 if ((len
= tvb_length(tvb
)) < XTP_HEADER_LEN
)
924 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "XTP");
925 col_clear(pinfo
->cinfo
, COL_INFO
);
930 xtph
->key
= tvb_get_ntohl(tvb
, offset
);
932 xtph
->key
+= tvb_get_ntohl(tvb
, offset
+4);
935 xtph
->cmd
= tvb_get_ntohl(tvb
, offset
);
936 xtph
->cmd_options
= xtph
->cmd
>> 8;
937 xtph
->cmd_ptype
= xtph
->cmd
& 0xff;
938 xtph
->cmd_ptype_ver
= (xtph
->cmd_ptype
& 0xe0) >> 5;
939 xtph
->cmd_ptype_pformat
= xtph
->cmd_ptype
& 0x1f;
942 xtph
->dlen
= tvb_get_ntohl(tvb
, offset
);
945 xtph
->check
= tvb_get_ntohs(tvb
, offset
);
948 xtph
->sort
= tvb_get_ntohs(tvb
, offset
);
951 xtph
->sync
= tvb_get_ntohl(tvb
, offset
);
954 xtph
->seq
= tvb_get_ntohl(tvb
, offset
);
956 xtph
->seq
+= tvb_get_ntohl(tvb
, offset
+4);
958 #define MAX_OPTIONS_LEN 128
959 options
=(gchar
*)wmem_alloc(wmem_packet_scope(), MAX_OPTIONS_LEN
);
961 cmd_options
= xtph
->cmd_options
>> 8;
962 for (i
= 0; i
< 16; i
++) {
963 bpos
= 1 << (15 - i
);
964 if (cmd_options
& bpos
) {
965 returned_length
= g_snprintf(&options
[fpos
],
966 MAX_OPTIONS_LEN
-fpos
, "%s%s",
969 fpos
+= MIN(returned_length
, MAX_OPTIONS_LEN
-fpos
);
973 col_add_str(pinfo
->cinfo
, COL_INFO
,
974 val_to_str(xtph
->cmd_ptype_pformat
,
975 pformat_vals
, "Unknown pformat (%u)"));
976 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " [%s]", options
);
977 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
978 " Seq=%" G_GINT64_MODIFIER
"u", xtph
->seq
);
979 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Len=%u", xtph
->dlen
);
982 ti
= proto_tree_add_item(tree
, proto_xtp
, tvb
, 0, -1, ENC_NA
);
984 proto_item_append_text(ti
,
985 ", Key: 0x%016" G_GINT64_MODIFIER
"X", xtph
->key
);
986 proto_item_append_text(ti
,
987 ", Seq: %" G_GINT64_MODIFIER
"u", xtph
->seq
);
988 proto_item_append_text(ti
, ", Len: %u", xtph
->dlen
);
990 xtp_tree
= proto_item_add_subtree(ti
, ett_xtp
);
993 proto_tree_add_uint64(xtp_tree
, hf_xtp_key
,
994 tvb
, offset
, 8, xtph
->key
);
997 ti
= proto_tree_add_uint(xtp_tree
, hf_xtp_cmd
,
998 tvb
, offset
, 4, xtph
->cmd
);
999 xtp_cmd_tree
= proto_item_add_subtree(ti
, ett_xtp_cmd
);
1000 ti
= proto_tree_add_uint(xtp_cmd_tree
, hf_xtp_cmd_options
,
1001 tvb
, offset
, 3, xtph
->cmd_options
);
1003 proto_item_append_text(ti
, " [%s]", options
);
1005 xtp_subtree
= proto_item_add_subtree(ti
, ett_xtp_cmd_options
);
1006 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_nocheck
,
1007 tvb
, offset
, 3, xtph
->cmd_options
);
1008 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_edge
,
1009 tvb
, offset
, 3, xtph
->cmd_options
);
1010 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_noerr
,
1011 tvb
, offset
, 3, xtph
->cmd_options
);
1012 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_multi
,
1013 tvb
, offset
, 3, xtph
->cmd_options
);
1014 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_res
,
1015 tvb
, offset
, 3, xtph
->cmd_options
);
1016 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_sort
,
1017 tvb
, offset
, 3, xtph
->cmd_options
);
1018 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_noflow
,
1019 tvb
, offset
, 3, xtph
->cmd_options
);
1020 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_fastnak
,
1021 tvb
, offset
, 3, xtph
->cmd_options
);
1022 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_sreq
,
1023 tvb
, offset
, 3, xtph
->cmd_options
);
1024 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_dreq
,
1025 tvb
, offset
, 3, xtph
->cmd_options
);
1026 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_rclose
,
1027 tvb
, offset
, 3, xtph
->cmd_options
);
1028 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_wclose
,
1029 tvb
, offset
, 3, xtph
->cmd_options
);
1030 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_eom
,
1031 tvb
, offset
, 3, xtph
->cmd_options
);
1032 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_end
,
1033 tvb
, offset
, 3, xtph
->cmd_options
);
1034 proto_tree_add_boolean(xtp_subtree
, hf_xtp_cmd_options_btag
,
1035 tvb
, offset
, 3, xtph
->cmd_options
);
1037 ti
= proto_tree_add_uint(xtp_cmd_tree
, hf_xtp_cmd_ptype
,
1038 tvb
, offset
, 1, xtph
->cmd_ptype
);
1039 xtp_subtree
= proto_item_add_subtree(ti
, ett_xtp_cmd_ptype
);
1040 proto_tree_add_uint(xtp_subtree
, hf_xtp_cmd_ptype_ver
,
1041 tvb
, offset
, 1, xtph
->cmd_ptype_ver
);
1042 if (xtph
->cmd_ptype_ver
!= XTP_VERSION_4
) {
1043 proto_item_append_text(ti
,
1044 ", Unknown XTP version (%03X)", xtph
->cmd_ptype_ver
);
1047 proto_tree_add_uint(xtp_subtree
, hf_xtp_cmd_ptype_pformat
,
1048 tvb
, offset
, 1, xtph
->cmd_ptype_pformat
);
1051 ti
= proto_tree_add_uint(xtp_tree
, hf_xtp_dlen
,
1052 tvb
, offset
, 4, xtph
->dlen
);
1053 if (xtph
->dlen
!= len
- XTP_HEADER_LEN
) {
1054 proto_item_append_text(ti
, ", bogus length (%u, must be %u)",
1055 xtph
->dlen
, len
- XTP_HEADER_LEN
);
1060 if (!pinfo
->fragmented
) {
1061 guint32 check_len
= XTP_HEADER_LEN
;
1062 if (!(xtph
->cmd_options
& XTP_CMD_OPTIONS_NOCHECK
))
1063 check_len
+= xtph
->dlen
;
1064 cksum_vec
[0].ptr
= tvb_get_ptr(tvb
, 0, check_len
);
1065 cksum_vec
[0].len
= check_len
;
1066 computed_cksum
= in_cksum(cksum_vec
, 1);
1067 if (computed_cksum
== 0) {
1068 proto_tree_add_text(xtp_tree
, tvb
, offset
, 2,
1069 "Checksum: 0x%04x [correct]", xtph
->check
);
1071 proto_tree_add_text(xtp_tree
, tvb
, offset
, 2,
1072 "Checksum: 0x%04x [incorrect, should be 0x%04x]",
1074 in_cksum_shouldbe(xtph
->check
, computed_cksum
));
1078 proto_tree_add_text(xtp_tree
, tvb
, offset
, 2,
1079 "Checksum: 0x%04x", xtph
->check
);
1083 proto_tree_add_uint(xtp_tree
, hf_xtp_sort
, tvb
, offset
, 2, xtph
->sort
);
1086 proto_tree_add_uint(xtp_tree
, hf_xtp_sync
, tvb
, offset
, 4, xtph
->sync
);
1089 proto_tree_add_uint64(xtp_tree
, hf_xtp_seq
, tvb
, offset
, 8, xtph
->seq
);
1093 switch (xtph
->cmd_ptype_pformat
) {
1095 have_btag
= !!(xtph
->cmd_options
& XTP_CMD_OPTIONS_BTAG
);
1096 dissect_xtp_data(tvb
, xtp_tree
, offset
, have_btag
);
1099 dissect_xtp_cntl(tvb
, pinfo
, xtp_tree
, offset
);
1102 dissect_xtp_first(tvb
, xtp_tree
, offset
);
1105 dissect_xtp_ecntl(tvb
, pinfo
, xtp_tree
, offset
);
1108 dissect_xtp_tcntl(tvb
, pinfo
, xtp_tree
, offset
);
1114 dissect_xtp_jcntl(tvb
, pinfo
, xtp_tree
, offset
);
1117 dissect_xtp_diag(tvb
, xtp_tree
, offset
);
1126 return tvb_length(tvb
);
1130 proto_register_xtp(void)
1132 static hf_register_info hf
[] = {
1133 /* command header */
1136 FT_UINT64
, BASE_HEX
, NULL
, 0x0,
1140 { "Command", "xtp.cmd",
1141 FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
1143 { &hf_xtp_cmd_options
,
1144 { "Options", "xtp.cmd.options",
1145 FT_UINT24
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
1147 { &hf_xtp_cmd_options_nocheck
,
1148 { "NOCHECK", "xtp.cmd.options.nocheck",
1149 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1150 XTP_CMD_OPTIONS_NOCHECK
, NULL
, HFILL
}
1152 { &hf_xtp_cmd_options_edge
,
1153 { "EDGE", "xtp.cmd.options.edge",
1154 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1155 XTP_CMD_OPTIONS_EDGE
, NULL
, HFILL
}
1157 { &hf_xtp_cmd_options_noerr
,
1158 { "NOERR", "xtp.cmd.options.noerr",
1159 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1160 XTP_CMD_OPTIONS_NOERR
, NULL
, HFILL
}
1162 { &hf_xtp_cmd_options_multi
,
1163 { "MULTI", "xtp.cmd.options.multi",
1164 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1165 XTP_CMD_OPTIONS_MULTI
, NULL
, HFILL
}
1167 { &hf_xtp_cmd_options_res
,
1168 { "RES", "xtp.cmd.options.res",
1169 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1170 XTP_CMD_OPTIONS_RES
, NULL
, HFILL
}
1172 { &hf_xtp_cmd_options_sort
,
1173 { "SORT", "xtp.cmd.options.sort",
1174 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1175 XTP_CMD_OPTIONS_SORT
, NULL
, HFILL
}
1177 { &hf_xtp_cmd_options_noflow
,
1178 { "NOFLOW", "xtp.cmd.options.noflow",
1179 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1180 XTP_CMD_OPTIONS_NOFLOW
, NULL
, HFILL
}
1182 { &hf_xtp_cmd_options_fastnak
,
1183 { "FASTNAK", "xtp.cmd.options.fastnak",
1184 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1185 XTP_CMD_OPTIONS_FASTNAK
, NULL
, HFILL
}
1187 { &hf_xtp_cmd_options_sreq
,
1188 { "SREQ", "xtp.cmd.options.sreq",
1189 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1190 XTP_CMD_OPTIONS_SREQ
, NULL
, HFILL
}
1192 { &hf_xtp_cmd_options_dreq
,
1193 { "DREQ", "xtp.cmd.options.dreq",
1194 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1195 XTP_CMD_OPTIONS_DREQ
, NULL
, HFILL
}
1197 { &hf_xtp_cmd_options_rclose
,
1198 { "RCLOSE", "xtp.cmd.options.rclose",
1199 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1200 XTP_CMD_OPTIONS_RCLOSE
, NULL
, HFILL
}
1202 { &hf_xtp_cmd_options_wclose
,
1203 { "WCLOSE", "xtp.cmd.options.wclose",
1204 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1205 XTP_CMD_OPTIONS_WCLOSE
, NULL
, HFILL
}
1207 { &hf_xtp_cmd_options_eom
,
1208 { "EOM", "xtp.cmd.options.eom",
1209 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1210 XTP_CMD_OPTIONS_EOM
, NULL
, HFILL
}
1212 { &hf_xtp_cmd_options_end
,
1213 { "END", "xtp.cmd.options.end",
1214 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1215 XTP_CMD_OPTIONS_END
, NULL
, HFILL
}
1217 { &hf_xtp_cmd_options_btag
,
1218 { "BTAG", "xtp.cmd.options.btag",
1219 FT_BOOLEAN
, 24, TFS(&tfs_set_notset
),
1220 XTP_CMD_OPTIONS_BTAG
, NULL
, HFILL
}
1222 { &hf_xtp_cmd_ptype
,
1223 { "Packet type", "xtp.cmd.ptype",
1224 FT_UINT8
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
1226 { &hf_xtp_cmd_ptype_ver
,
1227 { "Version", "xtp.cmd.ptype.ver",
1228 FT_UINT8
, BASE_DEC
, VALS(version_vals
), 0x0, NULL
, HFILL
}
1230 { &hf_xtp_cmd_ptype_pformat
,
1231 { "Format", "xtp.cmd.ptype.pformat",
1232 FT_UINT8
, BASE_DEC
, VALS(pformat_vals
), 0x0, NULL
, HFILL
}
1235 { "Data length", "xtp.dlen",
1236 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1239 { "Sort", "xtp.sort",
1240 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1243 { "Synchronizing handshake", "xtp.sync",
1244 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1247 { "Sequence number", "xtp.seq",
1248 FT_UINT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1250 /* control segment */
1251 { &hf_xtp_cntl_rseq
,
1252 { "Received sequence number", "xtp.cntl.rseq",
1253 FT_UINT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1255 { &hf_xtp_cntl_alloc
,
1256 { "Allocation", "xtp.cntl.alloc",
1257 FT_UINT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1259 { &hf_xtp_cntl_echo
,
1260 { "Synchronizing handshake echo", "xtp.cntl.echo",
1261 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1263 { &hf_xtp_ecntl_rseq
,
1264 { "Received sequence number", "xtp.ecntl.rseq",
1265 FT_UINT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1267 { &hf_xtp_ecntl_alloc
,
1268 { "Allocation", "xtp.ecntl.alloc",
1269 FT_UINT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1271 { &hf_xtp_ecntl_echo
,
1272 { "Synchronizing handshake echo", "xtp.ecntl.echo",
1273 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1275 { &hf_xtp_ecntl_nspan
,
1276 { "Number of spans", "xtp.ecntl.nspan",
1277 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1279 { &hf_xtp_ecntl_span_left
,
1280 { "Span left edge", "xtp.ecntl.span_le",
1281 FT_UINT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1283 { &hf_xtp_ecntl_span_right
,
1284 { "Span right edge", "xtp.ecntl.span_re",
1285 FT_UINT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1287 { &hf_xtp_tcntl_rseq
,
1288 { "Received sequence number", "xtp.tcntl.rseq",
1289 FT_UINT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1291 { &hf_xtp_tcntl_alloc
,
1292 { "Allocation", "xtp.tcntl.alloc",
1293 FT_UINT64
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1295 { &hf_xtp_tcntl_echo
,
1296 { "Synchronizing handshake echo", "xtp.tcntl.echo",
1297 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1299 { &hf_xtp_tcntl_rsvd
,
1300 { "Reserved", "xtp.tcntl.rsvd",
1301 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1303 { &hf_xtp_tcntl_xkey
,
1304 { "Exchange key", "xtp.tcntl.xkey",
1305 FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
1307 /* traffic specifier */
1308 { &hf_xtp_tspec_tlen
,
1309 { "Length", "xtp.tspec.tlen",
1310 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1312 { &hf_xtp_tspec_service
,
1313 { "Service", "xtp.tspec.service",
1314 FT_UINT8
, BASE_DEC
, VALS(service_vals
), 0x0, NULL
, HFILL
}
1316 { &hf_xtp_tspec_tformat
,
1317 { "Format", "xtp.tspec.format",
1318 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1320 { &hf_xtp_tspec_traffic
,
1321 { "Traffic", "xtp.tspec.traffic",
1322 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1324 { &hf_xtp_tspec_maxdata
,
1325 { "Maxdata", "xtp.tspec.maxdata",
1326 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1328 { &hf_xtp_tspec_inrate
,
1329 { "Incoming rate", "xtp.tspec.inrate",
1330 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1332 { &hf_xtp_tspec_inburst
,
1333 { "Incoming burst size", "xtp.tspec.inburst",
1334 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1336 { &hf_xtp_tspec_outrate
,
1337 { "Outgoing rate", "xtp.tspec.outrate",
1338 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1340 { &hf_xtp_tspec_outburst
,
1341 { "Outgoing burst size", "xtp.tspec.outburst",
1342 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1344 /* address segment */
1345 { &hf_xtp_aseg_alen
,
1346 { "Length", "xtp.aseg.alen",
1347 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1349 { &hf_xtp_aseg_adomain
,
1350 { "Domain", "xtp.aseg.adomain",
1351 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1353 { &hf_xtp_aseg_aformat
,
1354 { "Format", "xtp.aseg.aformat",
1355 FT_UINT8
, BASE_DEC
, VALS(aformat_vals
), 0x0, NULL
, HFILL
}
1357 { &hf_xtp_aseg_address
,
1358 { "Traffic", "xtp.aseg.address",
1359 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1361 { &hf_xtp_aseg_dsthost
,
1362 { "Destination host", "xtp.aseg.dsthost",
1363 FT_IPv4
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
1365 { &hf_xtp_aseg_srchost
,
1366 { "Source host", "xtp.aseg.srchost",
1367 FT_IPv4
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
1369 { &hf_xtp_aseg_dstport
,
1370 { "Destination port", "xtp.aseg.dstport",
1371 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1373 { &hf_xtp_aseg_srcport
,
1374 { "Source port", "xtp.aseg.srcport",
1375 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
1379 { "Beginning tag", "xtp.data.btag",
1380 FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
1382 { &hf_xtp_diag_code
,
1383 { "Diagnostic code", "xtp.diag.code",
1384 FT_UINT32
, BASE_DEC
, VALS(diag_code_vals
), 0x0, NULL
, HFILL
}
1387 { "Diagnostic value", "xtp.diag.val",
1388 FT_UINT32
, BASE_DEC
, VALS(diag_val_vals
), 0x0, NULL
, HFILL
}
1391 { "Message", "xtp.diag.msg",
1392 FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
1396 static gint
*ett
[] = {
1399 &ett_xtp_cmd_options
,
1412 static ei_register_info ei
[] = {
1413 { &ei_xtp_spans_bad
, { "xtp.spans_bad", PI_MALFORMED
, PI_ERROR
, "Number of spans incorrect", EXPFILL
}},
1416 expert_module_t
* expert_xtp
;
1418 expert_xtp
= expert_register_protocol(proto_xtp
);
1419 expert_register_field_array(expert_xtp
, ei
, array_length(ei
));
1421 proto_xtp
= proto_register_protocol("Xpress Transport Protocol",
1423 proto_register_field_array(proto_xtp
, hf
, array_length(hf
));
1424 proto_register_subtree_array(ett
, array_length(ett
));
1428 proto_reg_handoff_xtp(void)
1430 dissector_handle_t xtp_handle
;
1432 xtp_handle
= new_create_dissector_handle(dissect_xtp
, proto_xtp
);
1433 dissector_add_uint("ip.proto", IP_PROTO_XTP
, xtp_handle
);