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
34 #include <epan/packet.h>
35 #include <epan/ipproto.h>
36 #include <epan/in_cksum.h>
39 #define XTP_VERSION_4 0x001
41 /* XTP type of Service */
42 #define XTP_TOS_UNSPEC 0
43 #define XTP_TOS_UNACKED_DGRAM 1
44 #define XTP_TOS_ACKED_DGRAM 2
45 #define XTP_TOS_TRANS 3
46 #define XTP_TOS_UNICAST_STREAM 4
47 #define XTP_TOS_UNACKED_MULTICAST_STREAM 5
48 #define XTP_TOS_MULTICAST_STREAM 6
51 #define XTP_ADDR_NULL 0
53 #define XTP_ADDR_ISO 2
54 #define XTP_ADDR_XEROX 3
55 #define XTP_ADDR_IPX 4
56 #define XTP_ADDR_LOCAL 5
57 #define XTP_ADDR_IP6 6
60 #define XTP_DATA_PKT 0
61 #define XTP_CNTL_PKT 1
62 #define XTP_FIRST_PKT 2
63 #define XTP_ECNTL_PKT 3
64 #define XTP_TCNTL_PKT 5
65 #define XTP_JOIN_PKT 6
66 #define XTP_JCNTL_PKT 7
67 #define XTP_DIAG_PKT 8
69 /* cmd options mask */
70 #define XTP_CMD_OPTIONS_NOCHECK 0x400000
71 #define XTP_CMD_OPTIONS_EDGE 0x200000
72 #define XTP_CMD_OPTIONS_NOERR 0x100000
73 #define XTP_CMD_OPTIONS_MULTI 0x080000
74 #define XTP_CMD_OPTIONS_RES 0x040000
75 #define XTP_CMD_OPTIONS_SORT 0x020000
76 #define XTP_CMD_OPTIONS_NOFLOW 0x010000
77 #define XTP_CMD_OPTIONS_FASTNAK 0x008000
78 #define XTP_CMD_OPTIONS_SREQ 0x004000
79 #define XTP_CMD_OPTIONS_DREQ 0x002000
80 #define XTP_CMD_OPTIONS_RCLOSE 0x001000
81 #define XTP_CMD_OPTIONS_WCLOSE 0x000800
82 #define XTP_CMD_OPTIONS_EOM 0x000400
83 #define XTP_CMD_OPTIONS_END 0x000200
84 #define XTP_CMD_OPTIONS_BTAG 0x000100
86 #define XTP_KEY_RTN ((guint64)1<<63)
88 /** packet structures definition **/
94 #define XTP_CNTL_PKT_LEN 20
102 #define MIN_XTP_ECNTL_PKT_LEN 24
104 struct xtp_traffic_cntl {
111 #define XTP_TRAFFIC_CNTL_LEN 32
114 struct xtp_traffic_spec0 {
120 #define XTP_TRAFFIC_SPEC0_LEN 8
123 struct xtp_traffic_spec1 {
133 #define XTP_TRAFFIC_SPEC1_LEN 24
135 struct xtp_ip_addr_seg {
144 #define XTP_IP_ADDR_SEG_LEN 16
145 #define XTP_NULL_ADDR_SEG_LEN 8
152 #define XTP_DIAG_PKT_HEADER_LEN 8
157 guint32 cmd_options; /* 24 bits */
159 guint8 cmd_ptype_ver; /* 3 bits */
160 guint8 cmd_ptype_pformat; /* 5 bits */
167 #define XTP_HEADER_LEN 32
170 static const value_string version_vals[] = {
171 { XTP_VERSION_4, "XTP version 4.0" },
175 static const value_string service_vals[] = {
176 { XTP_TOS_UNSPEC, "Unspecified" },
177 { XTP_TOS_UNACKED_DGRAM, "Traditional Unacknowledged Datagram Service" },
178 { XTP_TOS_ACKED_DGRAM, "Acknowledged Datagram Service" },
179 { XTP_TOS_TRANS, "Transaction Service" },
180 { XTP_TOS_UNICAST_STREAM, "Traditional Reliable Unicast Stream Service" },
181 { XTP_TOS_UNACKED_MULTICAST_STREAM, "Unacknowledged Multicast Stream Service" },
182 { XTP_TOS_MULTICAST_STREAM, "Reliable Multicast Stream Service" },
186 static const value_string aformat_vals[] = {
187 { XTP_ADDR_NULL, "Null Address" },
188 { XTP_ADDR_IP, "Internet Protocol Address" },
189 { XTP_ADDR_ISO, "ISO Connectionless Network Layer Protocol Address" },
190 { XTP_ADDR_XEROX, "Xerox Network System Address" },
191 { XTP_ADDR_IPX, "IPX Address" },
192 { XTP_ADDR_LOCAL, "Local Address" },
193 { XTP_ADDR_IP6, "Internet Protocl Version 6 Address" },
197 static const value_string pformat_vals[] = {
198 { XTP_DATA_PKT, "DATA" },
199 { XTP_CNTL_PKT, "CNTL" },
200 { XTP_FIRST_PKT, "FIRST" },
201 { XTP_ECNTL_PKT, "ECNTL" },
202 { XTP_TCNTL_PKT, "TCNTL" },
203 { XTP_JOIN_PKT, "JOIN<obsolete>" },
204 { XTP_JCNTL_PKT, "JCNTL" },
205 { XTP_DIAG_PKT, "DIAG" },
209 static const value_string diag_code_vals[] = {
210 { 1, "Context Refused" },
211 { 2, "Context Abandoned" },
212 { 3, "Invalid Context" },
213 { 4, "Request Refused" },
214 { 5, "Join Refused" },
215 { 6, "Protocol Error" },
216 { 7, "Maximum Packet Size Error" },
220 static const value_string diag_val_vals[] = {
221 { 0, "Unspecified" },
222 { 1, "No listener" },
223 { 2, "Options refused" },
224 { 3, "Address format not supported" },
225 { 4, "Malformed address format" },
226 { 5, "Traffic format not supported" },
227 { 6, "Traffic specification refused" },
228 { 7, "Malformed traffic format" },
229 { 8, "No provider for service" },
230 { 9, "No resource" },
231 { 10, "Host going down" },
232 { 11, "Invalid retransmission request" },
233 { 12, "Context in improper state" },
234 { 13, "Join request denied" },
238 /* Initialize the protocol and registered fields */
239 static int proto_xtp = -1;
241 static int hf_xtp_key = -1;
242 static int hf_xtp_cmd = -1;
243 static int hf_xtp_cmd_options = -1;
244 static int hf_xtp_cmd_options_nocheck = -1;
245 static int hf_xtp_cmd_options_edge = -1;
246 static int hf_xtp_cmd_options_noerr = -1;
247 static int hf_xtp_cmd_options_multi = -1;
248 static int hf_xtp_cmd_options_res = -1;
249 static int hf_xtp_cmd_options_sort = -1;
250 static int hf_xtp_cmd_options_noflow = -1;
251 static int hf_xtp_cmd_options_fastnak = -1;
252 static int hf_xtp_cmd_options_sreq = -1;
253 static int hf_xtp_cmd_options_dreq = -1;
254 static int hf_xtp_cmd_options_rclose = -1;
255 static int hf_xtp_cmd_options_wclose = -1;
256 static int hf_xtp_cmd_options_eom = -1;
257 static int hf_xtp_cmd_options_end = -1;
258 static int hf_xtp_cmd_options_btag = -1;
259 static int hf_xtp_cmd_ptype = -1;
260 static int hf_xtp_cmd_ptype_ver = -1;
261 static int hf_xtp_cmd_ptype_pformat = -1;
262 static int hf_xtp_dlen = -1;
263 static int hf_xtp_sort = -1;
264 static int hf_xtp_sync = -1;
265 static int hf_xtp_seq = -1;
266 /* control segment */
267 static int hf_xtp_cntl_rseq = -1;
268 static int hf_xtp_cntl_alloc = -1;
269 static int hf_xtp_cntl_echo = -1;
270 static int hf_xtp_ecntl_rseq = -1;
271 static int hf_xtp_ecntl_alloc = -1;
272 static int hf_xtp_ecntl_echo = -1;
273 static int hf_xtp_ecntl_nspan = -1;
274 static int hf_xtp_ecntl_span_left = -1;
275 static int hf_xtp_ecntl_span_right = -1;
276 static int hf_xtp_tcntl_rseq = -1;
277 static int hf_xtp_tcntl_alloc = -1;
278 static int hf_xtp_tcntl_echo = -1;
279 static int hf_xtp_tcntl_rsvd = -1;
280 static int hf_xtp_tcntl_xkey = -1;
281 /* traffic specifier */
282 static int hf_xtp_tspec_tlen = -1;
283 static int hf_xtp_tspec_service = -1;
284 static int hf_xtp_tspec_tformat = -1;
285 static int hf_xtp_tspec_traffic = -1;
286 static int hf_xtp_tspec_maxdata = -1;
287 static int hf_xtp_tspec_inrate = -1;
288 static int hf_xtp_tspec_outrate = -1;
289 static int hf_xtp_tspec_inburst = -1;
290 static int hf_xtp_tspec_outburst = -1;
291 /* address segment */
292 static int hf_xtp_aseg_alen = -1;
293 static int hf_xtp_aseg_adomain = -1;
294 static int hf_xtp_aseg_aformat = -1;
295 static int hf_xtp_aseg_address = -1;
296 static int hf_xtp_aseg_dsthost = -1;
297 static int hf_xtp_aseg_srchost = -1;
298 static int hf_xtp_aseg_dstport = -1;
299 static int hf_xtp_aseg_srcport = -1;
301 static int hf_xtp_btag = -1;
302 static int hf_xtp_diag_code = -1;
303 static int hf_xtp_diag_val = -1;
304 static int hf_xtp_diag_msg = -1;
306 /* Initialize the subtree pointers */
307 static gint ett_xtp = -1;
308 static gint ett_xtp_cmd = -1;
309 static gint ett_xtp_cmd_options = -1;
310 static gint ett_xtp_cmd_ptype = -1;
311 static gint ett_xtp_cntl = -1;
312 static gint ett_xtp_ecntl = -1;
313 static gint ett_xtp_tcntl = -1;
314 static gint ett_xtp_tspec = -1;
315 static gint ett_xtp_jcntl = -1;
316 static gint ett_xtp_first = -1;
317 static gint ett_xtp_aseg = -1;
318 static gint ett_xtp_data = -1;
319 static gint ett_xtp_diag = -1;
321 /* dissector of each payload */
323 dissect_xtp_aseg(tvbuff_t *tvb, proto_tree *tree, guint32 offset) {
324 guint32 len = tvb_length_remaining(tvb, offset);
325 guint32 start = offset;
326 proto_item *ti, *ti2, *top_ti;
327 proto_tree *xtp_subtree;
328 struct xtp_ip_addr_seg aseg[1];
331 top_ti = proto_tree_add_text(tree, tvb, offset, len, "Address Segment");
332 xtp_subtree = proto_item_add_subtree(top_ti, ett_xtp_aseg);
334 if (len < XTP_NULL_ADDR_SEG_LEN) {
335 proto_item_append_text(top_ti, ", bogus length(%u, must be at least %u)",
336 len, XTP_NULL_ADDR_SEG_LEN);
340 /** parse common fields **/
342 aseg->alen = tvb_get_ntohs(tvb, offset);
345 aseg->adomain = tvb_get_guint8(tvb, offset);
348 aseg->aformat = tvb_get_guint8(tvb, offset);
351 /** display common fields **/
354 ti = proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_alen,
355 tvb, offset, 2, aseg->alen);
357 if (aseg->alen > len) {
358 proto_item_append_text(ti, ", bogus length(%u, must be at most %u)",
363 proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_adomain,
364 tvb, offset, 1, aseg->adomain);
367 ti2 = proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_aformat,
368 tvb, offset, 1, aseg->aformat);
370 switch (aseg->aformat) {
372 if (aseg->alen != XTP_NULL_ADDR_SEG_LEN) {
373 proto_item_append_text(ti, ", bogus length(%u, must be %u)",
374 aseg->alen, XTP_NULL_ADDR_SEG_LEN);
379 if (aseg->alen != XTP_IP_ADDR_SEG_LEN) {
380 proto_item_append_text(ti, ", bogus length(%u, must be %u)",
381 aseg->alen, XTP_IP_ADDR_SEG_LEN);
386 if (aseg->aformat < 128) {
387 proto_item_append_text(ti2,
388 ", Unsupported aformat(%u)", aseg->aformat);
395 return (offset - start);
397 /** parse and display each address fileds */
398 switch (aseg->aformat) {
401 aseg->dsthost = tvb_get_ntohl(tvb, offset);
402 proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_address,
403 tvb, offset, 4, aseg->dsthost);
408 aseg->dsthost = tvb_get_ipv4(tvb, offset);
409 proto_tree_add_ipv4(xtp_subtree, hf_xtp_aseg_dsthost,
410 tvb, offset, 4, aseg->dsthost);
413 aseg->srchost = tvb_get_ipv4(tvb, offset);
414 proto_tree_add_ipv4(xtp_subtree, hf_xtp_aseg_srchost,
415 tvb, offset, 4, aseg->srchost);
418 aseg->dstport = tvb_get_ntohs(tvb, offset);
419 proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_dstport,
420 tvb, offset, 2, aseg->dstport);
423 aseg->srcport = tvb_get_ntohs(tvb, offset);
424 proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_srcport,
425 tvb, offset, 2, aseg->srcport);
429 proto_item_append_text(top_ti, ", Dst Port: %u", aseg->dstport);
430 proto_item_append_text(top_ti, ", Src Port: %u", aseg->srcport);
436 return (offset - start);
440 dissect_xtp_traffic_cntl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
442 guint32 len = tvb_length_remaining(tvb, offset);
443 guint32 start = offset;
445 proto_tree *xtp_subtree;
446 struct xtp_traffic_cntl tcntl[1];
448 top_ti = proto_tree_add_text(tree, tvb, offset, len,
449 "Traffic Control Segment");
450 xtp_subtree = proto_item_add_subtree(top_ti, ett_xtp_tcntl);
452 if (len < XTP_TRAFFIC_CNTL_LEN) {
453 proto_item_append_text(top_ti,
454 ", bogus length(%u, must be at least %u)",
455 len, XTP_TRAFFIC_CNTL_LEN);
461 tcntl->rseq = tvb_get_ntohl(tvb, offset);
463 tcntl->rseq += tvb_get_ntohl(tvb, offset+4);
466 tcntl->alloc = tvb_get_ntohl(tvb, offset);
468 tcntl->alloc += tvb_get_ntohl(tvb, offset+4);
471 tcntl->echo = tvb_get_ntohl(tvb, offset);
474 tcntl->rsvd = tvb_get_ntohl(tvb, offset);
477 tcntl->xkey = tvb_get_ntohl(tvb, offset);
479 tcntl->xkey += tvb_get_ntohl(tvb, offset+4);
482 if (check_col(pinfo->cinfo, COL_INFO)) {
483 col_append_fstr(pinfo->cinfo, COL_INFO,
484 " Recv-Seq=%" G_GINT64_MODIFIER "u", tcntl->rseq);
485 col_append_fstr(pinfo->cinfo, COL_INFO,
486 " Alloc=%" G_GINT64_MODIFIER "u", tcntl->alloc);
488 proto_item_append_text(top_ti,
489 ", Recv-Seq: %" G_GINT64_MODIFIER "u", tcntl->rseq);
494 proto_tree_add_uint64(xtp_subtree, hf_xtp_tcntl_rseq,
495 tvb, offset, 8, tcntl->rseq);
498 proto_tree_add_uint64(xtp_subtree, hf_xtp_tcntl_alloc,
499 tvb, offset, 8, tcntl->alloc);
502 proto_tree_add_uint(xtp_subtree, hf_xtp_tcntl_echo,
503 tvb, offset, 4, tcntl->echo);
506 proto_tree_add_uint(xtp_subtree, hf_xtp_tcntl_rsvd,
507 tvb, offset, 4, tcntl->rsvd);
510 proto_tree_add_uint64(xtp_subtree, hf_xtp_tcntl_xkey,
511 tvb, offset, 8, tcntl->xkey);
514 return (offset - start);
518 dissect_xtp_tspec(tvbuff_t *tvb, proto_tree *tree, guint32 offset) {
519 guint32 len = tvb_length_remaining(tvb, offset);
520 guint32 start = offset;
521 proto_item *ti, *ti2;
522 proto_tree *xtp_subtree;
523 struct xtp_traffic_spec1 tspec[1];
526 ti = proto_tree_add_text(tree, tvb, offset, len, "Traffic Specifier");
527 xtp_subtree = proto_item_add_subtree(ti, ett_xtp_tspec);
529 if (len < XTP_TRAFFIC_SPEC0_LEN) {
530 proto_item_append_text(ti,
531 ", bogus length(%u, must be at least %u)",
532 len, XTP_TRAFFIC_SPEC0_LEN);
536 /** parse common fields **/
538 tspec->tlen = tvb_get_ntohs(tvb, offset);
541 tspec->service = tvb_get_guint8(tvb, offset);
544 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 if (check_col(pinfo->cinfo, COL_INFO)) {
695 col_append_fstr(pinfo->cinfo, COL_INFO,
696 " Recv-Seq=%" G_GINT64_MODIFIER "u", cntl->rseq);
697 col_append_fstr(pinfo->cinfo, COL_INFO,
698 " Alloc=%" G_GINT64_MODIFIER "u", cntl->alloc);
700 proto_item_append_text(top_ti,
701 ", Recv-Seq: %" G_GINT64_MODIFIER "u", cntl->rseq);
706 proto_tree_add_uint64(xtp_subtree, hf_xtp_cntl_rseq,
707 tvb, offset, 8, cntl->rseq);
710 proto_tree_add_uint64(xtp_subtree, hf_xtp_cntl_alloc,
711 tvb, offset, 8, cntl->alloc);
714 proto_tree_add_uint(xtp_subtree, hf_xtp_cntl_echo,
715 tvb, offset, 4, cntl->echo);
721 dissect_xtp_first(tvbuff_t *tvb, proto_tree *tree, guint32 offset) {
723 if (!dissect_xtp_aseg(tvb, tree, offset))
726 offset += XTP_IP_ADDR_SEG_LEN;
727 dissect_xtp_tspec(tvb, tree, offset);
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];
744 top_ti = proto_tree_add_text(tree, tvb, offset, len,
745 "Error Control Segment");
746 xtp_subtree = proto_item_add_subtree(top_ti, ett_xtp_ecntl);
748 if (len < MIN_XTP_ECNTL_PKT_LEN) {
749 proto_item_append_text(top_ti,
750 ", bogus length (%u, must be at least %u)",
751 len, MIN_XTP_ECNTL_PKT_LEN);
757 ecntl->rseq = tvb_get_ntohl(tvb, offset);
759 ecntl->rseq += tvb_get_ntohl(tvb, offset+4);
762 ecntl->alloc = tvb_get_ntohl(tvb, offset);
764 ecntl->alloc += tvb_get_ntohl(tvb, offset+4);
767 ecntl->echo = tvb_get_ntohl(tvb, offset);
770 ecntl->nspan = tvb_get_ntohl(tvb, offset);
772 len = len + XTP_HEADER_LEN - offset;
773 spans_len = 16 * ecntl->nspan;
774 if (len != spans_len) {
775 proto_item_append_text(top_ti,
776 ", bogus spans field length (%u, must be %u)",
781 spans = ep_alloc0(spans_len);
783 for (i = 0; i < ecntl->nspan*2; i++) {
784 guint64 span = tvb_get_ntohl(tvb, offset);
786 span += tvb_get_ntohl(tvb, offset+4);
792 if (check_col(pinfo->cinfo, COL_INFO)) {
793 col_append_fstr(pinfo->cinfo, COL_INFO,
794 " Recv-Seq=%" G_GINT64_MODIFIER "u", ecntl->rseq);
795 col_append_fstr(pinfo->cinfo, COL_INFO,
796 " Alloc=%" G_GINT64_MODIFIER "u", ecntl->alloc);
798 proto_item_append_text(top_ti,
799 ", Recv-Seq: %" G_GINT64_MODIFIER "u", ecntl->rseq);
804 proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_rseq,
805 tvb, offset, 8, ecntl->rseq);
808 proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_alloc,
809 tvb, offset, 8, ecntl->alloc);
812 proto_tree_add_uint(xtp_subtree, hf_xtp_ecntl_echo,
813 tvb, offset, 4, ecntl->echo);
816 proto_tree_add_uint(xtp_subtree, hf_xtp_ecntl_nspan,
817 tvb, offset, 4, ecntl->nspan);
821 for (i = 0; i < ecntl->nspan; i++) {
822 proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_span_left,
826 proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_span_right,
836 dissect_xtp_tcntl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
839 if (!dissect_xtp_traffic_cntl(tvb, pinfo, tree, offset))
842 offset += XTP_TRAFFIC_CNTL_LEN;
843 dissect_xtp_tspec(tvb, tree, offset);
849 dissect_xtp_jcntl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
852 if (!dissect_xtp_traffic_cntl(tvb, pinfo, tree, offset))
855 offset += XTP_TRAFFIC_CNTL_LEN;
856 if (!dissect_xtp_aseg(tvb, tree, offset))
859 offset += XTP_IP_ADDR_SEG_LEN;
860 dissect_xtp_tspec(tvb, tree, offset);
866 dissect_xtp_diag(tvbuff_t *tvb, proto_tree *tree, guint32 offset) {
867 guint32 len = tvb_length_remaining(tvb, offset);
868 guint32 start = offset;
870 proto_tree *xtp_subtree;
871 struct xtp_diag diag[1];
874 ti = proto_tree_add_text(tree, tvb, offset, len, "Diagnostic Segment");
875 xtp_subtree = proto_item_add_subtree(ti, ett_xtp_diag);
877 if (len < XTP_DIAG_PKT_HEADER_LEN) {
878 proto_item_append_text(ti,
879 ", bogus length (%u, must be at least %u)",
880 len, XTP_DIAG_PKT_HEADER_LEN);
886 diag->code = tvb_get_ntohl(tvb, offset);
889 diag->val = tvb_get_ntohl(tvb, offset);
892 msg_len = tvb_length_remaining(tvb, offset);
893 diag->msg = tvb_get_string(tvb, offset, msg_len);
898 proto_tree_add_uint(xtp_subtree, hf_xtp_diag_code,
899 tvb, offset, 4, diag->code);
902 proto_tree_add_uint(xtp_subtree, hf_xtp_diag_val,
903 tvb, offset, 4, diag->val);
906 proto_tree_add_string(xtp_subtree, hf_xtp_diag_msg,
907 tvb, offset, msg_len, diag->msg);
914 dissect_xtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
917 proto_tree *xtp_tree, *xtp_cmd_tree, *xtp_subtree;
918 struct xtphdr xtph[1];
920 gchar *options = "<None>";
921 const char *fstr[] = { "<None>", "NOCHECK", "EDGE", "NOERR", "MULTI", "RES",
922 "SORT", "NOFLOW", "FASTNAK", "SREQ", "DREQ",
923 "RCLOSE", "WCLOSE", "EOM", "END", "BTAG" };
924 gint fpos = 0, returned_length;
928 guint16 computed_cksum;
931 if ((len = tvb_length(tvb)) < XTP_HEADER_LEN)
934 col_set_str(pinfo->cinfo, COL_PROTOCOL, "XTP");
935 col_clear(pinfo->cinfo, COL_INFO);
940 xtph->key = tvb_get_ntohl(tvb, offset);
942 xtph->key += tvb_get_ntohl(tvb, offset+4);
945 xtph->cmd = tvb_get_ntohl(tvb, offset);
946 xtph->cmd_options = xtph->cmd >> 8;
947 xtph->cmd_ptype = xtph->cmd & 0xff;
948 xtph->cmd_ptype_ver = (xtph->cmd_ptype & 0xe0) >> 5;
949 xtph->cmd_ptype_pformat = xtph->cmd_ptype & 0x1f;
952 xtph->dlen = tvb_get_ntohl(tvb, offset);
955 xtph->check = tvb_get_ntohs(tvb, offset);
958 xtph->sort = tvb_get_ntohs(tvb, offset);
961 xtph->sync = tvb_get_ntohl(tvb, offset);
964 xtph->seq = tvb_get_ntohl(tvb, offset);
966 xtph->seq += tvb_get_ntohl(tvb, offset+4);
968 #define MAX_OPTIONS_LEN 128
969 options=ep_alloc(MAX_OPTIONS_LEN);
971 cmd_options = xtph->cmd_options >> 8;
972 for (i = 0; i < 16; i++) {
973 bpos = 1 << (15 - i);
974 if (cmd_options & bpos) {
975 returned_length = g_snprintf(&options[fpos],
976 MAX_OPTIONS_LEN-fpos, "%s%s",
979 fpos += MIN(returned_length, MAX_OPTIONS_LEN-fpos);
983 if (check_col(pinfo->cinfo, COL_INFO)) {
984 col_add_str(pinfo->cinfo, COL_INFO,
985 val_to_str(xtph->cmd_ptype_pformat,
986 pformat_vals, "Unknown pformat (%u)"));
987 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", options);
988 col_append_fstr(pinfo->cinfo, COL_INFO,
989 " Seq=%" G_GINT64_MODIFIER "u", xtph->seq);
990 col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", xtph->dlen);
994 ti = proto_tree_add_item(tree, proto_xtp, tvb, 0, -1, ENC_NA);
996 proto_item_append_text(ti,
997 ", Key: 0x%016" G_GINT64_MODIFIER "X", xtph->key);
998 proto_item_append_text(ti,
999 ", Seq: %" G_GINT64_MODIFIER "u", xtph->seq);
1000 proto_item_append_text(ti, ", Len: %u", xtph->dlen);
1002 xtp_tree = proto_item_add_subtree(ti, ett_xtp);
1005 proto_tree_add_uint64(xtp_tree, hf_xtp_key,
1006 tvb, offset, 8, xtph->key);
1009 ti = proto_tree_add_uint(xtp_tree, hf_xtp_cmd,
1010 tvb, offset, 4, xtph->cmd);
1011 xtp_cmd_tree = proto_item_add_subtree(ti, ett_xtp_cmd);
1012 ti = proto_tree_add_uint(xtp_cmd_tree, hf_xtp_cmd_options,
1013 tvb, offset, 3, xtph->cmd_options);
1015 proto_item_append_text(ti, " [%s]", options);
1017 xtp_subtree = proto_item_add_subtree(ti, ett_xtp_cmd_options);
1018 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_nocheck,
1019 tvb, offset, 3, xtph->cmd_options);
1020 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_edge,
1021 tvb, offset, 3, xtph->cmd_options);
1022 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_noerr,
1023 tvb, offset, 3, xtph->cmd_options);
1024 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_multi,
1025 tvb, offset, 3, xtph->cmd_options);
1026 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_res,
1027 tvb, offset, 3, xtph->cmd_options);
1028 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_sort,
1029 tvb, offset, 3, xtph->cmd_options);
1030 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_noflow,
1031 tvb, offset, 3, xtph->cmd_options);
1032 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_fastnak,
1033 tvb, offset, 3, xtph->cmd_options);
1034 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_sreq,
1035 tvb, offset, 3, xtph->cmd_options);
1036 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_dreq,
1037 tvb, offset, 3, xtph->cmd_options);
1038 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_rclose,
1039 tvb, offset, 3, xtph->cmd_options);
1040 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_wclose,
1041 tvb, offset, 3, xtph->cmd_options);
1042 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_eom,
1043 tvb, offset, 3, xtph->cmd_options);
1044 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_end,
1045 tvb, offset, 3, xtph->cmd_options);
1046 proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_btag,
1047 tvb, offset, 3, xtph->cmd_options);
1049 ti = proto_tree_add_uint(xtp_cmd_tree, hf_xtp_cmd_ptype,
1050 tvb, offset, 1, xtph->cmd_ptype);
1051 xtp_subtree = proto_item_add_subtree(ti, ett_xtp_cmd_ptype);
1052 proto_tree_add_uint(xtp_subtree, hf_xtp_cmd_ptype_ver,
1053 tvb, offset, 1, xtph->cmd_ptype_ver);
1054 if (xtph->cmd_ptype_ver != XTP_VERSION_4) {
1055 proto_item_append_text(ti,
1056 ", Unknown XTP version (%03X)", xtph->cmd_ptype_ver);
1059 proto_tree_add_uint(xtp_subtree, hf_xtp_cmd_ptype_pformat,
1060 tvb, offset, 1, xtph->cmd_ptype_pformat);
1063 ti = proto_tree_add_uint(xtp_tree, hf_xtp_dlen,
1064 tvb, offset, 4, xtph->dlen);
1065 if (xtph->dlen != len - XTP_HEADER_LEN) {
1066 proto_item_append_text(ti, ", bogus length (%u, must be %u)",
1067 xtph->dlen, len - XTP_HEADER_LEN);
1072 if (!pinfo->fragmented) {
1073 guint32 check_len = XTP_HEADER_LEN;
1074 if (!(xtph->cmd_options & XTP_CMD_OPTIONS_NOCHECK))
1075 check_len += xtph->dlen;
1076 cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, check_len);
1077 cksum_vec[0].len = check_len;
1078 computed_cksum = in_cksum(cksum_vec, 1);
1079 if (computed_cksum == 0) {
1080 proto_tree_add_text(xtp_tree, tvb, offset, 2,
1081 "Checksum: 0x%04x [correct]", xtph->check);
1083 proto_tree_add_text(xtp_tree, tvb, offset, 2,
1084 "Checksum: 0x%04x [incorrect, should be 0x%04x]",
1086 in_cksum_shouldbe(xtph->check, computed_cksum));
1090 proto_tree_add_text(xtp_tree, tvb, offset, 2,
1091 "Checksum: 0x%04x", xtph->check);
1095 proto_tree_add_uint(xtp_tree, hf_xtp_sort, tvb, offset, 2, xtph->sort);
1098 proto_tree_add_uint(xtp_tree, hf_xtp_sync, tvb, offset, 4, xtph->sync);
1101 proto_tree_add_uint64(xtp_tree, hf_xtp_seq, tvb, offset, 8, xtph->seq);
1105 switch (xtph->cmd_ptype_pformat) {
1107 have_btag = !!(xtph->cmd_options & XTP_CMD_OPTIONS_BTAG);
1108 dissect_xtp_data(tvb, xtp_tree, offset, have_btag);
1111 dissect_xtp_cntl(tvb, pinfo, xtp_tree, offset);
1114 dissect_xtp_first(tvb, xtp_tree, offset);
1117 dissect_xtp_ecntl(tvb, pinfo, xtp_tree, offset);
1120 dissect_xtp_tcntl(tvb, pinfo, xtp_tree, offset);
1126 dissect_xtp_jcntl(tvb, pinfo, xtp_tree, offset);
1129 dissect_xtp_diag(tvb, xtp_tree, offset);
1138 return tvb_length(tvb);
1142 proto_register_xtp(void)
1144 static hf_register_info hf[] = {
1145 /* command header */
1148 FT_UINT64, BASE_HEX, NULL, 0x0,
1152 { "Command", "xtp.cmd",
1153 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
1155 { &hf_xtp_cmd_options,
1156 { "Options", "xtp.cmd.options",
1157 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }
1159 { &hf_xtp_cmd_options_nocheck,
1160 { "NOCHECK", "xtp.cmd.options.nocheck",
1161 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1162 XTP_CMD_OPTIONS_NOCHECK, NULL, HFILL }
1164 { &hf_xtp_cmd_options_edge,
1165 { "EDGE", "xtp.cmd.options.edge",
1166 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1167 XTP_CMD_OPTIONS_EDGE, NULL, HFILL }
1169 { &hf_xtp_cmd_options_noerr,
1170 { "NOERR", "xtp.cmd.options.noerr",
1171 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1172 XTP_CMD_OPTIONS_NOERR, NULL, HFILL }
1174 { &hf_xtp_cmd_options_multi,
1175 { "MULTI", "xtp.cmd.options.multi",
1176 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1177 XTP_CMD_OPTIONS_MULTI, NULL, HFILL }
1179 { &hf_xtp_cmd_options_res,
1180 { "RES", "xtp.cmd.options.res",
1181 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1182 XTP_CMD_OPTIONS_RES, NULL, HFILL }
1184 { &hf_xtp_cmd_options_sort,
1185 { "SORT", "xtp.cmd.options.sort",
1186 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1187 XTP_CMD_OPTIONS_SORT, NULL, HFILL }
1189 { &hf_xtp_cmd_options_noflow,
1190 { "NOFLOW", "xtp.cmd.options.noflow",
1191 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1192 XTP_CMD_OPTIONS_NOFLOW, NULL, HFILL }
1194 { &hf_xtp_cmd_options_fastnak,
1195 { "FASTNAK", "xtp.cmd.options.fastnak",
1196 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1197 XTP_CMD_OPTIONS_FASTNAK, NULL, HFILL }
1199 { &hf_xtp_cmd_options_sreq,
1200 { "SREQ", "xtp.cmd.options.sreq",
1201 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1202 XTP_CMD_OPTIONS_SREQ, NULL, HFILL }
1204 { &hf_xtp_cmd_options_dreq,
1205 { "DREQ", "xtp.cmd.options.dreq",
1206 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1207 XTP_CMD_OPTIONS_DREQ, NULL, HFILL }
1209 { &hf_xtp_cmd_options_rclose,
1210 { "RCLOSE", "xtp.cmd.options.rclose",
1211 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1212 XTP_CMD_OPTIONS_RCLOSE, NULL, HFILL }
1214 { &hf_xtp_cmd_options_wclose,
1215 { "WCLOSE", "xtp.cmd.options.wclose",
1216 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1217 XTP_CMD_OPTIONS_WCLOSE, NULL, HFILL }
1219 { &hf_xtp_cmd_options_eom,
1220 { "EOM", "xtp.cmd.options.eom",
1221 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1222 XTP_CMD_OPTIONS_EOM, NULL, HFILL }
1224 { &hf_xtp_cmd_options_end,
1225 { "END", "xtp.cmd.options.end",
1226 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1227 XTP_CMD_OPTIONS_END, NULL, HFILL }
1229 { &hf_xtp_cmd_options_btag,
1230 { "BTAG", "xtp.cmd.options.btag",
1231 FT_BOOLEAN, 24, TFS(&tfs_set_notset),
1232 XTP_CMD_OPTIONS_BTAG, NULL, HFILL }
1234 { &hf_xtp_cmd_ptype,
1235 { "Packet type", "xtp.cmd.ptype",
1236 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
1238 { &hf_xtp_cmd_ptype_ver,
1239 { "Version", "xtp.cmd.ptype.ver",
1240 FT_UINT8, BASE_DEC, VALS(version_vals), 0x0, NULL, HFILL }
1242 { &hf_xtp_cmd_ptype_pformat,
1243 { "Format", "xtp.cmd.ptype.pformat",
1244 FT_UINT8, BASE_DEC, VALS(pformat_vals), 0x0, NULL, HFILL }
1247 { "Data length", "xtp.dlen",
1248 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1251 { "Sort", "xtp.sort",
1252 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1255 { "Synchronizing handshake", "xtp.sync",
1256 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1259 { "Sequence number", "xtp.seq",
1260 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1262 /* control segment */
1263 { &hf_xtp_cntl_rseq,
1264 { "Received sequence number", "xtp.cntl.rseq",
1265 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1267 { &hf_xtp_cntl_alloc,
1268 { "Allocation", "xtp.cntl.alloc",
1269 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1271 { &hf_xtp_cntl_echo,
1272 { "Synchronizing handshake echo", "xtp.cntl.echo",
1273 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1275 { &hf_xtp_ecntl_rseq,
1276 { "Received sequence number", "xtp.ecntl.rseq",
1277 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1279 { &hf_xtp_ecntl_alloc,
1280 { "Allocation", "xtp.ecntl.alloc",
1281 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1283 { &hf_xtp_ecntl_echo,
1284 { "Synchronizing handshake echo", "xtp.ecntl.echo",
1285 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1287 { &hf_xtp_ecntl_nspan,
1288 { "Number of spans", "xtp.ecntl.nspan",
1289 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1291 { &hf_xtp_ecntl_span_left,
1292 { "Span left edge", "xtp.ecntl.span_le",
1293 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1295 { &hf_xtp_ecntl_span_right,
1296 { "Span right edge", "xtp.ecntl.span_re",
1297 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1299 { &hf_xtp_tcntl_rseq,
1300 { "Received sequence number", "xtp.tcntl.rseq",
1301 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1303 { &hf_xtp_tcntl_alloc,
1304 { "Allocation", "xtp.tcntl.alloc",
1305 FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }
1307 { &hf_xtp_tcntl_echo,
1308 { "Synchronizing handshake echo", "xtp.tcntl.echo",
1309 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1311 { &hf_xtp_tcntl_rsvd,
1312 { "Reserved", "xtp.tcntl.rsvd",
1313 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1315 { &hf_xtp_tcntl_xkey,
1316 { "Exchange key", "xtp.tcntl.xkey",
1317 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1319 /* traffic specifier */
1320 { &hf_xtp_tspec_tlen,
1321 { "Length", "xtp.tspec.tlen",
1322 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1324 { &hf_xtp_tspec_service,
1325 { "Service", "xtp.tspec.service",
1326 FT_UINT8, BASE_DEC, VALS(service_vals), 0x0, NULL, HFILL }
1328 { &hf_xtp_tspec_tformat,
1329 { "Format", "xtp.tspec.format",
1330 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1332 { &hf_xtp_tspec_traffic,
1333 { "Traffic", "xtp.tspec.traffic",
1334 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1336 { &hf_xtp_tspec_maxdata,
1337 { "Maxdata", "xtp.tspec.maxdata",
1338 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1340 { &hf_xtp_tspec_inrate,
1341 { "Incoming rate", "xtp.tspec.inrate",
1342 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1344 { &hf_xtp_tspec_inburst,
1345 { "Incoming burst size", "xtp.tspec.inburst",
1346 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1348 { &hf_xtp_tspec_outrate,
1349 { "Outgoing rate", "xtp.tspec.outrate",
1350 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1352 { &hf_xtp_tspec_outburst,
1353 { "Outgoing burst size", "xtp.tspec.outburst",
1354 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1356 /* address segment */
1357 { &hf_xtp_aseg_alen,
1358 { "Length", "xtp.aseg.alen",
1359 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1361 { &hf_xtp_aseg_adomain,
1362 { "Domain", "xtp.aseg.alen",
1363 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
1365 { &hf_xtp_aseg_aformat,
1366 { "Format", "xtp.aseg.aformat",
1367 FT_UINT8, BASE_DEC, VALS(aformat_vals), 0x0, NULL, HFILL }
1369 { &hf_xtp_aseg_address,
1370 { "Traffic", "xtp.aseg.address",
1371 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
1373 { &hf_xtp_aseg_dsthost,
1374 { "Destination host", "xtp.aseg.dsthost",
1375 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
1377 { &hf_xtp_aseg_srchost,
1378 { "Source host", "xtp.aseg.srchost",
1379 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
1381 { &hf_xtp_aseg_dstport,
1382 { "Destination port", "xtp.aseg.dstport",
1383 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1385 { &hf_xtp_aseg_srcport,
1386 { "Source port", "xtp.aseg.srcport",
1387 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
1391 { "Beginning tag", "xtp.data.btag",
1392 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
1394 { &hf_xtp_diag_code,
1395 { "Diagnostic code", "xtp.diag.code",
1396 FT_UINT32, BASE_DEC, VALS(diag_code_vals), 0x0, NULL, HFILL }
1399 { "Diagnostic value", "xtp.diag.val",
1400 FT_UINT32, BASE_DEC, VALS(diag_val_vals), 0x0, NULL, HFILL }
1403 { "Message", "xtp.diag.msg",
1404 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }
1408 static gint *ett[] = {
1411 &ett_xtp_cmd_options,
1424 proto_xtp = proto_register_protocol("Xpress Transport Protocol",
1426 proto_register_field_array(proto_xtp, hf, array_length(hf));
1427 proto_register_subtree_array(ett, array_length(ett));
1431 proto_reg_handoff_xtp(void)
1433 dissector_handle_t xtp_handle;
1435 xtp_handle = new_create_dissector_handle(dissect_xtp, proto_xtp);
1436 dissector_add_uint("ip.proto", IP_PROTO_XTP, xtp_handle);