2 * Routines for Banyan VINES protocol packet disassembly
6 * Don Lafontaine <lafont02@cn.ca>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
11 * Joerg Mayer (see AUTHORS file)
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include <epan/packet.h>
35 #include "packet-vines.h"
36 #include <epan/etypes.h>
37 #include <epan/ppptypes.h>
38 #include <epan/ipproto.h>
39 #include <epan/arcnet_pids.h>
40 #include <epan/llcsaps.h>
42 #define UDP_PORT_VINES 573
44 static int proto_vines_frp = -1;
46 static gint ett_vines_frp = -1;
48 static int proto_vines_llc = -1;
50 static gint ett_vines_llc = -1;
52 static int proto_vines_ip = -1;
53 static int hf_vines_ip_protocol = -1;
55 static gint ett_vines_ip = -1;
56 static gint ett_vines_ip_tctl = -1;
58 static int proto_vines_echo = -1;
60 static gint ett_vines_echo = -1;
62 static int proto_vines_ipc = -1;
64 static gint ett_vines_ipc = -1;
65 static gint ett_vines_ipc_control = -1;
67 static int proto_vines_spp = -1;
69 static gint ett_vines_spp = -1;
70 static gint ett_vines_spp_control = -1;
72 static int proto_vines_arp = -1;
74 static gint ett_vines_arp = -1;
76 static int proto_vines_rtp = -1;
78 static gint ett_vines_rtp = -1;
79 static gint ett_vines_rtp_compatibility_flags = -1;
80 static gint ett_vines_rtp_req_info = -1;
81 static gint ett_vines_rtp_control_flags = -1;
82 static gint ett_vines_rtp_mtype = -1;
83 static gint ett_vines_rtp_flags = -1;
85 static int proto_vines_icp = -1;
87 static gint ett_vines_icp = -1;
90 capture_vines(packet_counts *ld)
95 static dissector_handle_t vines_ip_handle;
96 static dissector_handle_t data_handle;
98 /* AFAIK Vines FRP (Fragmentation Protocol) is used on all media except
99 * Ethernet and TR (and probably FDDI) - Fragmentation on these media types
101 * FIXME: Do we need to use this header with PPP too?
104 dissect_vines_frp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
106 guint8 vines_frp_ctrl;
107 proto_tree *vines_frp_tree;
109 gchar *frp_flags_str="";
112 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines FRP");
113 col_clear(pinfo->cinfo, COL_INFO);
116 ti = proto_tree_add_item(tree, proto_vines_frp, tvb, 0, 2,
118 vines_frp_tree = proto_item_add_subtree(ti, ett_vines_frp);
120 vines_frp_ctrl = tvb_get_guint8(tvb, 0);
123 * 1: first fragment of vines packet
124 * 2: last fragment of vines packet
127 switch (vines_frp_ctrl) {
130 frp_flags_str= "middle";
134 frp_flags_str= "first";
138 frp_flags_str= "last";
142 frp_flags_str= "only";
146 frp_flags_str= "please report: unknown";
150 proto_tree_add_text(vines_frp_tree, tvb, 0, 1,
151 "Control Flags: 0x%02x = %s fragment",
152 vines_frp_ctrl, frp_flags_str);
154 proto_tree_add_text(vines_frp_tree, tvb, 1, 1,
155 "Sequence Number: 0x%02x",
156 tvb_get_guint8(tvb, 1));
159 /* Decode the "real" Vines now */
160 next_tvb = tvb_new_subset_remaining(tvb, 2);
161 call_dissector(vines_ip_handle, next_tvb, pinfo, tree);
165 proto_register_vines_frp(void)
167 static gint *ett[] = {
171 proto_vines_frp = proto_register_protocol(
172 "Banyan Vines Fragmentation Protocol", "Vines FRP", "vines_frp");
173 proto_register_subtree_array(ett, array_length(ett));
177 proto_reg_handoff_vines_frp(void)
179 dissector_handle_t vines_frp_handle;
181 vines_frp_handle = create_dissector_handle(dissect_vines_frp,
183 dissector_add("ip.proto", IP_PROTO_VINES, vines_frp_handle);
185 /* XXX: AFAIK, src and dst port must be the same; should
186 the dissector check for that? */
187 dissector_add("udp.port", UDP_PORT_VINES, vines_frp_handle);
190 static dissector_table_t vines_llc_dissector_table;
192 #define VINES_LLC_IP 0xba
193 #define VINES_LLC_ECHO 0xbb
195 static const value_string vines_llc_ptype_vals[] = {
196 { VINES_LLC_IP, "Vines IP" },
197 { VINES_LLC_ECHO, "Vines Echo" },
202 dissect_vines_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
205 proto_tree *vines_llc_tree;
209 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines LLC");
210 col_clear(pinfo->cinfo, COL_INFO);
212 ptype = tvb_get_guint8(tvb, 0);
213 if (check_col(pinfo->cinfo, COL_INFO))
214 col_add_str(pinfo->cinfo, COL_INFO,
215 val_to_str(ptype, vines_llc_ptype_vals,
216 "Unknown protocol 0x%02x"));
218 ti = proto_tree_add_item(tree, proto_vines_llc, tvb, 0, 1,
220 vines_llc_tree = proto_item_add_subtree(ti, ett_vines_llc);
222 proto_tree_add_text(vines_llc_tree, tvb, 0, 1,
223 "Packet Type: %s (0x%02x)",
224 val_to_str(ptype, vines_llc_ptype_vals,
229 next_tvb = tvb_new_subset_remaining(tvb, 1);
230 if (!dissector_try_port(vines_llc_dissector_table, ptype,
231 next_tvb, pinfo, tree))
232 call_dissector(data_handle, next_tvb, pinfo, tree);
236 proto_register_vines_llc(void)
238 static gint *ett[] = {
242 proto_vines_llc = proto_register_protocol(
243 "Banyan Vines LLC", "Vines LLC", "vines_llc");
244 proto_register_subtree_array(ett, array_length(ett));
246 /* subdissector code */
247 vines_llc_dissector_table = register_dissector_table("vines_llc.ptype",
248 "Vines LLC protocol", FT_UINT8, BASE_HEX);
252 proto_reg_handoff_vines_llc(void)
254 dissector_handle_t vines_llc_handle;
256 vines_llc_handle = create_dissector_handle(dissect_vines_llc,
258 dissector_add("llc.dsap", SAP_VINES2, vines_llc_handle);
261 static dissector_table_t vines_ip_dissector_table;
263 static const value_string class_vals[] = {
264 { 0x00, "Reachable regardless of cost" },
265 { 0x10, "Reachable without cost" },
266 { 0x20, "Reachable with low cost (>= 4800 bps)" },
267 { 0x30, "Reachable via LAN" },
271 static const value_string proto_vals[] = {
272 { VIP_PROTO_IPC, "IPC" },
273 { VIP_PROTO_SPP, "SPP" },
274 { VIP_PROTO_ARP, "ARP" },
275 { VIP_PROTO_RTP, "RTP" },
276 { VIP_PROTO_ICP, "ICP" },
280 static const guint8 bcast_addr[VINES_ADDR_LEN] = {
281 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
285 dissect_vines_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
289 proto_tree *vip_tree, *tctl_tree;
291 const guint8 *dst_addr, *src_addr;
292 gboolean is_broadcast = FALSE;
295 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines IP");
296 col_clear(pinfo->cinfo, COL_INFO);
298 /* To do: check for runts, errs, etc. */
300 /* Avoids alignment problems on many architectures. */
301 tvb_memcpy(tvb, (guint8 *)&viph, offset, sizeof(e_vip));
303 viph.vip_chksum = g_ntohs(viph.vip_chksum);
304 viph.vip_pktlen = g_ntohs(viph.vip_pktlen);
306 if (check_col(pinfo->cinfo, COL_INFO)) {
307 col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%02x)",
308 val_to_str(viph.vip_proto, proto_vals,
309 "Unknown VIP protocol"),
313 src_addr = tvb_get_ptr(tvb, offset+12, VINES_ADDR_LEN);
314 SET_ADDRESS(&pinfo->net_src, AT_VINES, VINES_ADDR_LEN, src_addr);
315 SET_ADDRESS(&pinfo->src, AT_VINES, VINES_ADDR_LEN, src_addr);
316 dst_addr = tvb_get_ptr(tvb, offset+6, VINES_ADDR_LEN);
317 SET_ADDRESS(&pinfo->net_dst, AT_VINES, VINES_ADDR_LEN,dst_addr);
318 SET_ADDRESS(&pinfo->dst, AT_VINES, VINES_ADDR_LEN, dst_addr);
320 /* helpers to transport control */
321 if (memcmp(viph.vip_dst, bcast_addr, VINES_ADDR_LEN) == 0)
325 * Adjust the length of this tvbuff to include only the Vines IP
328 set_actual_length(tvb, viph.vip_pktlen < 18 ? 18 : viph.vip_pktlen);
331 ti = proto_tree_add_item(tree, proto_vines_ip, tvb,
332 offset, viph.vip_pktlen,
334 vip_tree = proto_item_add_subtree(ti, ett_vines_ip);
335 proto_tree_add_text(vip_tree, tvb, offset, 2,
336 "Packet checksum: 0x%04x",
338 proto_tree_add_text(vip_tree, tvb, offset + 2, 2,
341 ti = proto_tree_add_text(vip_tree, tvb, offset + 4, 1,
342 "Transport control: 0x%02x",
344 tctl_tree = proto_item_add_subtree(ti, ett_vines_ip_tctl);
346 * XXX - bit 0x80 is "Normal" if 0; what is it if 1?
349 proto_tree_add_text(tctl_tree, tvb, offset + 4, 1, "%s",
350 decode_boolean_bitfield(viph.vip_tctl, 0x40, 1*8,
353 proto_tree_add_text(tctl_tree, tvb, offset + 4, 1, "%s",
354 decode_enumerated_bitfield(viph.vip_tctl, 0x30, 1*8,
357 proto_tree_add_text(tctl_tree, tvb, offset + 4, 1, "%s",
358 decode_boolean_bitfield(viph.vip_tctl, 0x40, 1*8,
359 "Forwarding router can handle redirect packets",
360 "Forwarding router cannot handle redirect packets"));
361 proto_tree_add_text(tctl_tree, tvb, offset + 4, 1, "%s",
362 decode_boolean_bitfield(viph.vip_tctl, 0x20, 1*8,
363 "Return metric notification packet",
364 "Do not return metric notification packet"));
365 proto_tree_add_text(tctl_tree, tvb, offset + 4, 1, "%s",
366 decode_boolean_bitfield(viph.vip_tctl, 0x10, 1*8,
367 "Return exception notification packet",
368 "Do not return exception notification packet"));
370 proto_tree_add_text(tctl_tree, tvb, offset + 4, 1, "%s",
371 decode_numeric_bitfield(viph.vip_tctl, 0x0F, 1*8,
372 "Hop count remaining = %u"));
373 proto_tree_add_uint(vip_tree, hf_vines_ip_protocol, tvb,
376 proto_tree_add_text(vip_tree, tvb, offset + 6,
379 vines_addr_to_str(dst_addr));
380 proto_tree_add_text(vip_tree, tvb, offset + 12,
383 vines_addr_to_str(src_addr));
387 next_tvb = tvb_new_subset_remaining(tvb, offset);
388 if (!dissector_try_port(vines_ip_dissector_table, viph.vip_proto,
389 next_tvb, pinfo, tree))
390 call_dissector(data_handle, next_tvb, pinfo, tree);
394 proto_register_vines_ip(void)
396 static gint *ett[] = {
401 static hf_register_info hf[] = {
402 { &hf_vines_ip_protocol,
403 { "Protocol", "vines_ip.protocol",
404 FT_UINT8, BASE_HEX, VALS(proto_vals), 0x0,
405 "Vines protocol", HFILL }}
408 proto_vines_ip = proto_register_protocol("Banyan Vines IP", "Vines IP",
410 proto_register_field_array(proto_vines_ip, hf, array_length(hf));
411 proto_register_subtree_array(ett, array_length(ett));
413 /* subdissector code */
414 vines_ip_dissector_table = register_dissector_table("vines_ip.protocol",
415 "Vines protocol", FT_UINT8, BASE_HEX);
417 vines_ip_handle = create_dissector_handle(dissect_vines_ip,
422 proto_reg_handoff_vines_ip(void)
424 dissector_add("ethertype", ETHERTYPE_VINES_IP, vines_ip_handle);
425 dissector_add("ppp.protocol", PPP_VINES, vines_ip_handle);
426 dissector_add("arcnet.protocol_id", ARCNET_PROTO_BANYAN,
428 dissector_add("vines_llc.ptype", VINES_LLC_IP, vines_ip_handle);
429 data_handle = find_dissector("data");
433 dissect_vines_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
435 proto_tree *vines_echo_tree = NULL;
438 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines Echo");
439 col_clear(pinfo->cinfo, COL_INFO);
442 ti = proto_tree_add_item(tree, proto_vines_echo, tvb, 0, -1,
444 vines_echo_tree = proto_item_add_subtree(ti, ett_vines_echo);
445 proto_tree_add_text(vines_echo_tree, tvb, 0, -1, "Data");
450 proto_register_vines_echo(void)
452 static gint *ett[] = {
456 proto_vines_echo = proto_register_protocol(
457 "Banyan Vines Echo", "Vines Echo", "vines_echo");
458 proto_register_subtree_array(ett, array_length(ett));
462 proto_reg_handoff_vines_echo(void)
464 dissector_handle_t vines_echo_handle;
466 vines_echo_handle = create_dissector_handle(dissect_vines_echo,
468 dissector_add("vines_llc.ptype", VINES_LLC_ECHO, vines_echo_handle);
469 dissector_add("ethertype", ETHERTYPE_VINES_ECHO, vines_echo_handle);
472 static const value_string pkttype_vals[] = {
473 { PKTTYPE_DGRAM, "Datagram" },
474 { PKTTYPE_DATA, "Data" },
475 { PKTTYPE_ERR, "Error" },
476 { PKTTYPE_DISC, "Disconnect" },
477 { PKTTYPE_PROBE, "Probe" },
478 { PKTTYPE_ACK, "Ack" },
482 static heur_dissector_list_t vines_ipc_heur_subdissector_list;
484 static const value_string vipc_err_vals[] = {
485 { 151, "Bad socket descriptor" },
486 { 152, "Address already in use" },
487 { 153, "Invalid operation" },
488 { 154, "User address parameter fault" },
489 { 155, "Net/host unreachable" },
490 { 156, "Message overflow error" },
491 { 157, "Destination socket does not exist" },
492 { 158, "Address family does not exist" },
493 { 159, "Socket type does not exist" },
494 { 160, "Protocol does not exist" },
495 { 161, "No more sockets available" },
496 { 162, "No buffer space available" },
497 { 163, "Timeout event" },
498 { 164, "Operation not supported" },
499 { 165, "Resource not available" },
500 { 166, "Internal communication service failure" },
501 { 167, "Controller reset failure" },
506 dissect_vines_ipc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
510 proto_tree *vipc_tree = NULL, *control_tree;
514 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VIPC");
515 col_clear(pinfo->cinfo, COL_INFO);
517 /* To do: check for runts, errs, etc. */
519 /* Avoids alignment problems on many architectures. */
520 tvb_memcpy(tvb, (guint8 *)&viph, offset, sizeof(e_vipc));
522 viph.vipc_sport = g_ntohs(viph.vipc_sport);
523 viph.vipc_dport = g_ntohs(viph.vipc_dport);
524 viph.vipc_lclid = g_ntohs(viph.vipc_lclid);
525 viph.vipc_rmtid = g_ntohs(viph.vipc_rmtid);
526 viph.vipc_seqno = g_ntohs(viph.vipc_seqno);
527 viph.vipc_ack = g_ntohs(viph.vipc_ack);
528 viph.vipc_err_len = g_ntohs(viph.vipc_err_len);
530 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines IPC");
531 if (check_col(pinfo->cinfo, COL_INFO)) {
532 switch (viph.vipc_pkttype) {
535 col_add_fstr(pinfo->cinfo, COL_INFO,
537 val_to_str(viph.vipc_pkttype, pkttype_vals,
538 "Unknown packet type (0x%02x)"),
539 viph.vipc_dport, viph.vipc_sport);
543 col_add_fstr(pinfo->cinfo, COL_INFO,
544 "%s NS=%u NR=%u Err=%s RID=%04x LID=%04x D=%04x S=%04x",
545 val_to_str(viph.vipc_pkttype, pkttype_vals,
546 "Unknown packet type (0x%02x)"),
547 viph.vipc_seqno, viph.vipc_ack,
548 val_to_str(viph.vipc_err_len,
549 vipc_err_vals, "Unknown (%u)"),
550 viph.vipc_rmtid, viph.vipc_lclid,
551 viph.vipc_dport, viph.vipc_sport);
555 col_add_fstr(pinfo->cinfo, COL_INFO,
556 "%s NS=%u NR=%u Len=%u RID=%04x LID=%04x D=%04x S=%04x",
557 val_to_str(viph.vipc_pkttype, pkttype_vals,
558 "Unknown packet type (0x%02x)"),
559 viph.vipc_seqno, viph.vipc_ack,
560 viph.vipc_err_len, viph.vipc_rmtid,
561 viph.vipc_lclid, viph.vipc_dport,
568 ti = proto_tree_add_item(tree, proto_vines_ipc, tvb, offset,
569 sizeof(viph), FALSE);
570 vipc_tree = proto_item_add_subtree(ti, ett_vines_ipc);
571 proto_tree_add_text(vipc_tree, tvb, offset, 2,
572 "Source port: 0x%04x", viph.vipc_sport);
576 proto_tree_add_text(vipc_tree, tvb, offset, 2,
577 "Destination port: 0x%04x",
582 proto_tree_add_text(vipc_tree, tvb, offset, 1,
583 "Packet type: 0x%02x (%s)",
585 val_to_str(viph.vipc_pkttype, pkttype_vals,
589 if (viph.vipc_pkttype != PKTTYPE_DGRAM) {
591 ti = proto_tree_add_text(vipc_tree, tvb, offset, 1,
594 control_tree = proto_item_add_subtree(ti,
595 ett_vines_ipc_control);
597 * XXX - do reassembly based on BOM/EOM bits.
599 proto_tree_add_text(control_tree, tvb, offset, 1, "%s",
600 decode_boolean_bitfield(viph.vipc_control, 0x80,
602 "Send immediate acknowledgment",
603 "Do not send immediate acknowledgement"));
604 proto_tree_add_text(control_tree, tvb, offset, 1, "%s",
605 decode_boolean_bitfield(viph.vipc_control, 0x40,
608 "Not end of message"));
609 proto_tree_add_text(control_tree, tvb, offset, 1, "%s",
610 decode_boolean_bitfield(viph.vipc_control, 0x20,
612 "Beginning of message",
613 "Not beginning of message"));
614 proto_tree_add_text(control_tree, tvb, offset, 1, "%s",
615 decode_boolean_bitfield(viph.vipc_control, 0x10,
617 "Abort current message",
618 "Do not abort current message"));
622 if (viph.vipc_pkttype != PKTTYPE_DGRAM) {
624 proto_tree_add_text(vipc_tree, tvb, offset, 2,
625 "Local Connection ID: 0x%04x",
630 proto_tree_add_text(vipc_tree, tvb, offset, 2,
631 "Remote Connection ID: 0x%04x",
636 proto_tree_add_text(vipc_tree, tvb, offset, 2,
637 "Sequence number: %u",
642 proto_tree_add_text(vipc_tree, tvb, offset, 2,
643 "Ack number: %u", viph.vipc_ack);
647 if (viph.vipc_pkttype == PKTTYPE_ERR) {
648 proto_tree_add_text(vipc_tree, tvb, offset, 2,
650 val_to_str(viph.vipc_err_len,
655 proto_tree_add_text(vipc_tree, tvb, offset, 2,
664 * For data packets, try the heuristic dissectors for Vines SPP;
665 * if none of them accept the packet, or if it's not a data packet,
666 * dissect it as data.
668 next_tvb = tvb_new_subset_remaining(tvb, offset);
669 if (viph.vipc_pkttype != PKTTYPE_DATA ||
670 !dissector_try_heuristic(vines_ipc_heur_subdissector_list,
671 next_tvb, pinfo, tree))
672 call_dissector(data_handle, next_tvb, pinfo, tree);
676 proto_register_vines_ipc(void)
678 static gint *ett[] = {
680 &ett_vines_ipc_control,
683 proto_vines_ipc = proto_register_protocol("Banyan Vines IPC",
684 "Vines IPC", "vines_ipc");
685 proto_register_subtree_array(ett, array_length(ett));
687 register_heur_dissector_list("vines_ipc",
688 &vines_ipc_heur_subdissector_list);
692 proto_reg_handoff_vines_ipc(void)
694 dissector_handle_t vines_ipc_handle;
696 vines_ipc_handle = create_dissector_handle(dissect_vines_ipc,
698 dissector_add("vines_ip.protocol", VIP_PROTO_IPC, vines_ipc_handle);
701 static heur_dissector_list_t vines_spp_heur_subdissector_list;
704 dissect_vines_spp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
708 proto_tree *vspp_tree, *control_tree;
712 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSPP");
713 col_clear(pinfo->cinfo, COL_INFO);
715 /* To do: check for runts, errs, etc. */
717 /* Avoids alignment problems on many architectures. */
718 tvb_memcpy(tvb, (guint8 *)&viph, offset, sizeof(e_vspp));
720 viph.vspp_sport = g_ntohs(viph.vspp_sport);
721 viph.vspp_dport = g_ntohs(viph.vspp_dport);
722 viph.vspp_lclid = g_ntohs(viph.vspp_lclid);
723 viph.vspp_rmtid = g_ntohs(viph.vspp_rmtid);
724 viph.vspp_seqno = g_ntohs(viph.vspp_seqno);
725 viph.vspp_ack = g_ntohs(viph.vspp_ack);
726 viph.vspp_win = g_ntohs(viph.vspp_win);
728 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines SPP");
729 if (check_col(pinfo->cinfo, COL_INFO))
730 col_add_fstr(pinfo->cinfo, COL_INFO,
731 "%s NS=%u NR=%u Window=%u RID=%04x LID=%04x D=%04x S=%04x",
732 val_to_str(viph.vspp_pkttype, pkttype_vals,
733 "Unknown packet type (0x%02x)"),
734 viph.vspp_seqno, viph.vspp_ack, viph.vspp_win,
735 viph.vspp_rmtid, viph.vspp_lclid, viph.vspp_dport,
739 ti = proto_tree_add_item(tree, proto_vines_spp, tvb, offset,
740 sizeof(viph), FALSE);
741 vspp_tree = proto_item_add_subtree(ti, ett_vines_spp);
742 proto_tree_add_text(vspp_tree, tvb, offset, 2,
743 "Source port: 0x%04x", viph.vspp_sport);
744 proto_tree_add_text(vspp_tree, tvb, offset + 2, 2,
745 "Destination port: 0x%04x",
747 proto_tree_add_text(vspp_tree, tvb, offset + 4, 1,
748 "Packet type: 0x%02x (%s)",
750 val_to_str(viph.vspp_pkttype, pkttype_vals,
752 ti = proto_tree_add_text(vspp_tree, tvb, offset + 5, 1,
753 "Control: 0x%02x", viph.vspp_control);
754 control_tree = proto_item_add_subtree(ti, ett_vines_spp_control);
756 * XXX - do reassembly based on BOM/EOM bits.
758 proto_tree_add_text(control_tree, tvb, offset + 5, 1, "%s",
759 decode_boolean_bitfield(viph.vspp_control, 0x80, 1*8,
760 "Send immediate acknowledgment",
761 "Do not send immediate acknowledgement"));
762 proto_tree_add_text(control_tree, tvb, offset + 5, 1, "%s",
763 decode_boolean_bitfield(viph.vspp_control, 0x40, 1*8,
765 "Not end of message"));
766 proto_tree_add_text(control_tree, tvb, offset + 5, 1, "%s",
767 decode_boolean_bitfield(viph.vspp_control, 0x20, 1*8,
768 "Beginning of message",
769 "Not beginning of message"));
770 proto_tree_add_text(control_tree, tvb, offset + 5, 1, "%s",
771 decode_boolean_bitfield(viph.vspp_control, 0x10, 1*8,
772 "Abort current message",
773 "Do not abort current message"));
774 proto_tree_add_text(vspp_tree, tvb, offset + 6, 2,
775 "Local Connection ID: 0x%04x",
777 proto_tree_add_text(vspp_tree, tvb, offset + 8, 2,
778 "Remote Connection ID: 0x%04x",
780 proto_tree_add_text(vspp_tree, tvb, offset + 10, 2,
781 "Sequence number: %u",
783 proto_tree_add_text(vspp_tree, tvb, offset + 12, 2,
784 "Ack number: %u", viph.vspp_ack);
785 proto_tree_add_text(vspp_tree, tvb, offset + 14, 2,
786 "Window: %u", viph.vspp_win);
788 offset += 16; /* sizeof SPP */
791 * For data packets, try the heuristic dissectors for Vines SPP;
792 * if none of them accept the packet, or if it's not a data packet,
793 * dissect it as data.
795 next_tvb = tvb_new_subset_remaining(tvb, offset);
796 if (viph.vspp_pkttype != PKTTYPE_DATA ||
797 !dissector_try_heuristic(vines_spp_heur_subdissector_list,
798 next_tvb, pinfo, tree))
799 call_dissector(data_handle, next_tvb, pinfo, tree);
803 proto_register_vines_spp(void)
805 static gint *ett[] = {
807 &ett_vines_spp_control,
810 proto_vines_spp = proto_register_protocol("Banyan Vines SPP",
811 "Vines SPP", "vines_spp");
812 proto_register_subtree_array(ett, array_length(ett));
814 register_heur_dissector_list("vines_spp",
815 &vines_spp_heur_subdissector_list);
819 proto_reg_handoff_vines_spp(void)
821 dissector_handle_t vines_spp_handle;
823 vines_spp_handle = create_dissector_handle(dissect_vines_spp,
825 dissector_add("vines_ip.protocol", VIP_PROTO_SPP, vines_spp_handle);
828 #define VINES_VERS_PRE_5_5 0x00
829 #define VINES_VERS_5_5 0x01
831 static const value_string vines_version_vals[] = {
832 { VINES_VERS_PRE_5_5, "Pre-5.50" },
833 { VINES_VERS_5_5, "5.50" },
837 #define VARP_QUERY_REQ 0x00
838 #define VARP_SERVICE_RESP 0x01
839 #define VARP_ASSIGNMENT_REQ 0x02
840 #define VARP_ASSIGNMENT_RESP 0x03
842 static const value_string vines_arp_packet_type_vals[] = {
843 { VARP_QUERY_REQ, "Query request" },
844 { VARP_SERVICE_RESP, "Service response" },
845 { VARP_ASSIGNMENT_REQ, "Assignment request" },
846 { VARP_ASSIGNMENT_RESP, "Assignment response" },
851 dissect_vines_arp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
853 proto_tree *vines_arp_tree = NULL;
859 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines ARP");
860 col_clear(pinfo->cinfo, COL_INFO);
863 ti = proto_tree_add_item(tree, proto_vines_arp, tvb, 0, -1,
865 vines_arp_tree = proto_item_add_subtree(ti, ett_vines_arp);
868 version = tvb_get_guint8(tvb, 0);
870 proto_tree_add_text(vines_arp_tree, tvb, 0, 1,
871 "Version: %s (0x%02x)",
872 val_to_str(version, vines_version_vals,
876 if (version == VINES_VERS_5_5) {
880 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines SARP");
881 packet_type = tvb_get_guint8(tvb, 1);
882 if (check_col(pinfo->cinfo, COL_INFO)) {
883 col_add_str(pinfo->cinfo, COL_INFO,
884 val_to_str(packet_type, vines_arp_packet_type_vals,
885 "Unknown (0x%02x)"));
888 proto_tree_add_text(vines_arp_tree, tvb, 1, 1,
889 "Packet Type: %s (0x%02x)",
890 val_to_str(packet_type,
891 vines_arp_packet_type_vals,
895 if (packet_type == VARP_ASSIGNMENT_RESP) {
896 if (check_col(pinfo->cinfo, COL_INFO)) {
897 col_append_fstr(pinfo->cinfo, COL_INFO,
899 vines_addr_to_str(tvb_get_ptr(tvb, 2, VINES_ADDR_LEN)));
902 proto_tree_add_text(vines_arp_tree, tvb, 2,
905 vines_addr_to_str(tvb_get_ptr(tvb, 2, VINES_ADDR_LEN)));
909 proto_tree_add_text(vines_arp_tree, tvb,
911 "Sequence Number: %u",
912 tvb_get_ntohl(tvb, 2+VINES_ADDR_LEN));
913 metric = tvb_get_ntohs(tvb, 2+VINES_ADDR_LEN+4);
914 proto_tree_add_text(vines_arp_tree, tvb,
915 2+VINES_ADDR_LEN+4, 2,
916 "Interface Metric: %u ticks (%g seconds)",
923 packet_type = (guint8) tvb_get_ntohs(tvb, 0);
924 if (check_col(pinfo->cinfo, COL_INFO)) {
925 col_add_str(pinfo->cinfo, COL_INFO,
926 val_to_str(packet_type, vines_arp_packet_type_vals,
927 "Unknown (0x%02x)"));
930 proto_tree_add_text(vines_arp_tree, tvb, 0, 2,
931 "Packet Type: %s (0x%04x)",
932 val_to_str(packet_type,
933 vines_arp_packet_type_vals,
937 if (packet_type == VARP_ASSIGNMENT_RESP) {
938 if (check_col(pinfo->cinfo, COL_INFO)) {
939 col_append_fstr(pinfo->cinfo, COL_INFO,
941 vines_addr_to_str(tvb_get_ptr(tvb, 2, VINES_ADDR_LEN)));
944 proto_tree_add_text(vines_arp_tree, tvb, 2,
947 vines_addr_to_str(tvb_get_ptr(tvb, 2, VINES_ADDR_LEN)));
954 proto_register_vines_arp(void)
956 static gint *ett[] = {
960 proto_vines_arp = proto_register_protocol(
961 "Banyan Vines ARP", "Vines ARP", "vines_arp");
962 proto_register_subtree_array(ett, array_length(ett));
966 proto_reg_handoff_vines_arp(void)
968 dissector_handle_t vines_arp_handle;
970 vines_arp_handle = create_dissector_handle(dissect_vines_arp,
972 dissector_add("vines_ip.protocol", VIP_PROTO_ARP, vines_arp_handle);
975 #define VRTP_OP_REQUEST 0x01
976 #define VRTP_OP_UPDATE_RESPONSE 0x02
977 #define VRTP_OP_REDIRECT 0x03
978 #define VRTP_OP_REINITIALIZE 0x04
979 #define VRTP_OP_REDIRECT2 0x06
981 static const value_string vines_rtp_operation_type_vals[] = {
982 { VRTP_OP_REQUEST, "Request" },
983 { VRTP_OP_UPDATE_RESPONSE, "Update/response" },
984 { VRTP_OP_REDIRECT, "Redirect" },
985 { VRTP_OP_REINITIALIZE, "Reinitialize" },
986 { VRTP_OP_REDIRECT2, "Redirect" },
990 static const value_string vines_rtp_node_type_vals[] = {
996 static const value_string vines_rtp_controller_type_vals[] = {
997 { 0x00, "Default Card" },
998 { 0x01, "Multibuffer" },
1002 static const value_string vines_rtp_info_type_vals[] = {
1005 { 0x02, "Response" },
1009 static void rtp_show_machine_type(proto_tree *tree, tvbuff_t *tvb, int offset,
1011 static void rtp_show_flags(proto_tree *tree, tvbuff_t *tvb, int offset,
1013 static int srtp_show_machine_info(proto_tree *tree, tvbuff_t *tvb, int offset,
1015 static int rtp_show_gateway_info(proto_tree *tree, tvbuff_t *tvb, int offset,
1016 guint8 link_addr_length, guint8 source_route_length);
1019 dissect_vines_rtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1022 proto_tree *vines_rtp_tree = NULL;
1024 proto_tree *subtree;
1026 guint8 operation_type;
1028 guint8 controller_type;
1029 guint8 compatibility_flags;
1030 guint8 link_addr_length;
1031 guint8 source_route_length;
1032 guint8 requested_info;
1034 guint8 control_flags;
1037 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines RTP");
1038 col_clear(pinfo->cinfo, COL_INFO);
1041 ti = proto_tree_add_item(tree, proto_vines_rtp, tvb, 0, -1,
1043 vines_rtp_tree = proto_item_add_subtree(ti, ett_vines_rtp);
1046 if (tvb_get_guint8(tvb, 0) != 0) {
1048 * Non-sequenced RTP.
1050 operation_type = tvb_get_guint8(tvb, offset);
1051 if (check_col(pinfo->cinfo, COL_INFO)) {
1052 col_add_str(pinfo->cinfo, COL_INFO,
1053 val_to_str(operation_type, vines_rtp_operation_type_vals,
1054 "Unknown (0x%02x)"));
1057 proto_tree_add_text(vines_rtp_tree, tvb, offset, 1,
1058 "Operation Type: %s (0x%02x)",
1059 val_to_str(operation_type,
1060 vines_rtp_operation_type_vals,
1064 node_type = tvb_get_guint8(tvb, offset);
1065 proto_tree_add_text(vines_rtp_tree, tvb, offset, 1,
1066 "Node Type: %s (0x%02x)",
1067 val_to_str(node_type,
1068 vines_rtp_node_type_vals,
1072 controller_type = tvb_get_guint8(tvb, offset);
1073 proto_tree_add_text(vines_rtp_tree, tvb, offset, 1,
1074 "Controller Type: %s (0x%02x)",
1075 val_to_str(controller_type,
1076 vines_rtp_controller_type_vals,
1080 rtp_show_machine_type(vines_rtp_tree, tvb, offset,
1083 switch (operation_type) {
1085 case VRTP_OP_REDIRECT:
1086 case VRTP_OP_REDIRECT2:
1087 proto_tree_add_text(vines_rtp_tree, tvb,
1090 tvb_get_ntohs(tvb, offset));
1092 link_addr_length = tvb_get_guint8(tvb, offset);
1093 proto_tree_add_text(vines_rtp_tree, tvb,
1095 "Link Address Length: %u",
1098 source_route_length = tvb_get_guint8(tvb, offset);
1099 proto_tree_add_text(vines_rtp_tree, tvb,
1101 "Source Route Length: %u",
1102 source_route_length);
1104 offset = srtp_show_machine_info(vines_rtp_tree,
1105 tvb, offset, "Destination");
1107 offset = srtp_show_machine_info(vines_rtp_tree,
1108 tvb, offset, "Preferred Gateway");
1110 offset = rtp_show_gateway_info(vines_rtp_tree,
1111 tvb,offset, link_addr_length,
1112 source_route_length);
1116 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1117 proto_tree_add_text(vines_rtp_tree, tvb,
1119 "Network Number: 0x%08x",
1120 tvb_get_ntohl(tvb, offset));
1122 metric = tvb_get_ntohs(tvb, offset);
1123 proto_tree_add_text(vines_rtp_tree, tvb,
1125 "Neighbor Metric: %u ticks (%g seconds)",
1134 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines SRTP");
1136 version = tvb_get_ntohs(tvb, offset);
1137 proto_tree_add_text(vines_rtp_tree, tvb, offset, 2,
1138 "Version: %s (0x%04x)",
1139 val_to_str(version, vines_version_vals,
1144 operation_type = tvb_get_guint8(tvb, offset);
1145 if (check_col(pinfo->cinfo, COL_INFO)) {
1146 col_add_str(pinfo->cinfo, COL_INFO,
1147 val_to_str(operation_type, vines_rtp_operation_type_vals,
1148 "Unknown (0x%02x)"));
1151 proto_tree_add_text(vines_rtp_tree, tvb, offset, 1,
1152 "Operation Type: %s (0x%02x)",
1153 val_to_str(operation_type,
1154 vines_rtp_operation_type_vals,
1158 node_type = tvb_get_guint8(tvb, offset);
1159 proto_tree_add_text(vines_rtp_tree, tvb, offset, 1,
1160 "Node Type: %s (0x%02x)",
1161 val_to_str(node_type,
1162 vines_rtp_node_type_vals,
1166 compatibility_flags = tvb_get_guint8(tvb, offset);
1167 ti = proto_tree_add_text(vines_rtp_tree, tvb, offset, 1,
1168 "Compatibility Flags: 0x%02x",
1169 compatibility_flags);
1170 subtree = proto_item_add_subtree(ti,
1171 ett_vines_rtp_compatibility_flags);
1172 proto_tree_add_text(subtree, tvb,
1174 decode_boolean_bitfield(compatibility_flags,
1176 "Auto-configured non-Vines-reachable neighbor router",
1177 "Not an auto-configured non-Vines-reachable neighbor router"));
1178 proto_tree_add_text(subtree, tvb,
1180 decode_boolean_bitfield(compatibility_flags,
1182 "Not all neighbor routers support Sequenced RTP",
1183 "All neighbor routers support Sequenced RTP"));
1184 proto_tree_add_text(subtree, tvb,
1186 decode_boolean_bitfield(compatibility_flags,
1188 "Sequenced RTP version mismatch",
1189 "No Sequenced RTP version mismatch"));
1191 offset += 1; /* reserved */
1192 switch (operation_type) {
1194 case VRTP_OP_REQUEST:
1195 requested_info = tvb_get_guint8(tvb, offset);
1196 proto_tree_add_text(vines_rtp_tree, tvb,
1198 "Requested Info: 0x%02x",
1202 case VRTP_OP_UPDATE_RESPONSE:
1203 info_type = tvb_get_guint8(tvb, offset);
1204 proto_tree_add_text(vines_rtp_tree, tvb,
1206 "Information Type: %s (0x%02x)",
1207 val_to_str(info_type,
1208 vines_rtp_info_type_vals,
1212 control_flags = tvb_get_guint8(tvb, offset);
1213 ti = proto_tree_add_text(vines_rtp_tree, tvb,
1215 "Control Flags: 0x%02x",
1217 subtree = proto_item_add_subtree(ti,
1218 ett_vines_rtp_control_flags);
1219 proto_tree_add_text(subtree, tvb,
1221 decode_boolean_bitfield(control_flags,
1223 "Part of routing table synchronization broadcast",
1224 "Not part of routing table synchronization broadcast"));
1225 proto_tree_add_text(subtree, tvb,
1227 decode_boolean_bitfield(control_flags,
1229 "Part of full topology update",
1230 "Not part of full topology update"));
1231 proto_tree_add_text(subtree, tvb,
1233 decode_boolean_bitfield(control_flags,
1235 "Contains info specifically requested or network changes",
1236 "Not a response to a specific request"));
1237 /* XXX - need reassembly? */
1238 proto_tree_add_text(subtree, tvb,
1240 decode_boolean_bitfield(control_flags,
1243 "Not end of message"));
1244 proto_tree_add_text(subtree, tvb,
1246 decode_boolean_bitfield(control_flags,
1248 "Beginning of message",
1249 "Not beginning of message"));
1251 proto_tree_add_text(vines_rtp_tree, tvb,
1254 tvb_get_ntohs(tvb, offset));
1256 proto_tree_add_text(vines_rtp_tree, tvb,
1259 tvb_get_ntohs(tvb, offset));
1261 proto_tree_add_text(vines_rtp_tree, tvb,
1263 "Router Sequence Number: %u",
1264 tvb_get_ntohl(tvb, offset));
1266 metric = tvb_get_ntohs(tvb, offset);
1267 proto_tree_add_text(vines_rtp_tree, tvb,
1269 "Metric: %u ticks (%g seconds)",
1272 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1273 proto_tree_add_text(vines_rtp_tree, tvb,
1275 "Network Number: 0x%08x",
1276 tvb_get_ntohl(tvb, offset));
1278 metric = tvb_get_ntohs(tvb, offset);
1279 if (metric == 0xffff) {
1280 proto_tree_add_text(vines_rtp_tree, tvb,
1282 "Neighbor Metric: Unreachable");
1284 proto_tree_add_text(vines_rtp_tree, tvb,
1286 "Neighbor Metric: %u ticks (%g seconds)",
1290 proto_tree_add_text(vines_rtp_tree, tvb,
1292 "Sequence Number: %u",
1293 tvb_get_ntohl(tvb, offset));
1295 rtp_show_flags(vines_rtp_tree, tvb,
1298 offset += 1; /* reserved */
1302 case VRTP_OP_REDIRECT:
1303 link_addr_length = tvb_get_guint8(tvb, offset);
1304 proto_tree_add_text(vines_rtp_tree, tvb,
1306 "Link Address Length: %u",
1309 source_route_length = tvb_get_guint8(tvb, offset);
1310 proto_tree_add_text(vines_rtp_tree, tvb,
1312 "Source Route Length: %u",
1313 source_route_length);
1315 proto_tree_add_text(vines_rtp_tree, tvb,
1316 offset, VINES_ADDR_LEN,
1318 vines_addr_to_str(tvb_get_ptr(tvb, offset, VINES_ADDR_LEN)));
1319 offset += VINES_ADDR_LEN;
1320 metric = tvb_get_ntohs(tvb, offset);
1321 proto_tree_add_text(vines_rtp_tree, tvb,
1323 "Metric to Destination: %u ticks (%g seconds)",
1326 node_type = tvb_get_guint8(tvb, offset);
1327 proto_tree_add_text(vines_rtp_tree, tvb,
1329 "Destination Node Type: %s (0x%02x)",
1330 val_to_str(node_type,
1331 vines_rtp_node_type_vals,
1335 rtp_show_flags(vines_rtp_tree, tvb,
1336 offset, "Destination");
1338 proto_tree_add_text(vines_rtp_tree, tvb,
1340 "Destination Sequence Number: %u",
1341 tvb_get_ntohl(tvb, offset));
1343 proto_tree_add_text(vines_rtp_tree, tvb,
1344 offset, VINES_ADDR_LEN,
1345 "Preferred Gateway: %s",
1346 vines_addr_to_str(tvb_get_ptr(tvb, offset, VINES_ADDR_LEN)));
1347 offset += VINES_ADDR_LEN;
1348 metric = tvb_get_ntohs(tvb, offset);
1349 proto_tree_add_text(vines_rtp_tree, tvb,
1351 "Metric to Preferred Gateway: %u ticks (%g seconds)",
1354 node_type = tvb_get_guint8(tvb, offset);
1355 proto_tree_add_text(vines_rtp_tree, tvb,
1357 "Preferred Gateway Node Type: %s (0x%02x)",
1358 val_to_str(node_type,
1359 vines_rtp_node_type_vals,
1363 rtp_show_flags(vines_rtp_tree, tvb,
1364 offset, "Preferred Gateway");
1366 proto_tree_add_text(vines_rtp_tree, tvb,
1368 "Preferred Gateway Sequence Number: %u",
1369 tvb_get_ntohl(tvb, offset));
1371 offset = rtp_show_gateway_info(vines_rtp_tree,
1372 tvb,offset, link_addr_length,
1373 source_route_length);
1376 case VRTP_OP_REINITIALIZE:
1385 rtp_show_machine_type(proto_tree *tree, tvbuff_t *tvb, int offset, const char *tag)
1387 guint8 machine_type;
1389 proto_tree *subtree;
1391 machine_type = tvb_get_guint8(tvb, offset);
1392 ti = proto_tree_add_text(tree, tvb, offset, 1,
1393 "%s%sMachine Type: 0x%02x",
1394 tag == NULL ? "" : tag,
1395 tag == NULL ? "" : " ",
1397 subtree = proto_item_add_subtree(ti, ett_vines_rtp_mtype);
1398 proto_tree_add_text(subtree, tvb, offset, 1, "%s",
1399 decode_boolean_bitfield(machine_type, 0x04, 1*8,
1400 "Sequenced RTP supported",
1401 "Sequenced RTP not supported"));
1402 proto_tree_add_text(subtree, tvb, offset, 1, "%s",
1403 decode_boolean_bitfield(machine_type, 0x02, 1*8,
1405 "TCP/IP not supported"));
1406 proto_tree_add_text(subtree, tvb, offset, 1, "%s",
1407 decode_boolean_bitfield(machine_type, 0x01, 1*8,
1413 rtp_show_flags(proto_tree *tree, tvbuff_t *tvb, int offset, const char *tag)
1417 proto_tree *flags_tree;
1419 flags = tvb_get_guint8(tvb, offset);
1420 ti = proto_tree_add_text(tree, tvb, offset, 1, "%s Flags: 0x%02x",
1422 flags_tree = proto_item_add_subtree(ti, ett_vines_rtp_flags);
1423 proto_tree_add_text(flags_tree, tvb, offset, 1, "%s",
1424 decode_boolean_bitfield(flags, 0x08, 1*8,
1425 "Network doesn't support Sequenced RTP",
1426 "Network supports Sequenced RTP"));
1427 proto_tree_add_text(flags_tree, tvb, offset, 1, "%s",
1428 decode_boolean_bitfield(flags, 0x04, 1*8,
1429 "Network accessed point-to-point on non-Vines network",
1430 "Network not accessed point-to-point on non-Vines network"));
1431 proto_tree_add_text(flags_tree, tvb, offset, 1, "%s",
1432 decode_boolean_bitfield(flags, 0x02, 1*8,
1433 "Data link to network uses point-to-point connection",
1434 "Data link to network doesn't use point-to-point connection"));
1435 proto_tree_add_text(flags_tree, tvb, offset, 1, "%s",
1436 decode_boolean_bitfield(flags, 0x01, 1*8,
1437 "Network accessed across broadcast medium",
1438 "Network not accessed across broadcast medium"));
1442 srtp_show_machine_info(proto_tree *tree, tvbuff_t *tvb, int offset, const char *tag)
1446 guint8 controller_type;
1448 proto_tree_add_text(tree, tvb, offset, VINES_ADDR_LEN,
1450 vines_addr_to_str(tvb_get_ptr(tvb, offset, VINES_ADDR_LEN)));
1451 offset += VINES_ADDR_LEN;
1452 metric = tvb_get_ntohs(tvb, offset);
1453 proto_tree_add_text(tree, tvb, offset, 2,
1454 "Metric to %s: %u ticks (%g seconds)", tag, metric, metric*.2);
1456 node_type = tvb_get_guint8(tvb, offset);
1457 proto_tree_add_text(tree, tvb, offset, 1,
1458 "%s Node Type: %s (0x%02x)", tag,
1459 val_to_str(node_type, vines_rtp_node_type_vals, "Unknown"),
1462 rtp_show_machine_type(tree, tvb, offset, tag);
1464 controller_type = tvb_get_guint8(tvb, offset);
1465 proto_tree_add_text(tree, tvb, offset, 1,
1466 "%s Controller Type: %s (0x%02x)", tag,
1467 val_to_str(controller_type, vines_rtp_controller_type_vals, "Unknown"),
1474 rtp_show_gateway_info(proto_tree *tree, tvbuff_t *tvb, int offset,
1475 guint8 link_addr_length, guint8 source_route_length)
1477 if (link_addr_length != 0) {
1478 proto_tree_add_text(tree, tvb, offset, link_addr_length,
1479 "Preferred Gateway Data Link Address: %s",
1480 link_addr_length == 6 ?
1481 ether_to_str(tvb_get_ptr(tvb, offset, link_addr_length)) :
1482 tvb_bytes_to_str(tvb, offset, link_addr_length));
1483 offset += link_addr_length;
1485 if (source_route_length != 0) {
1486 proto_tree_add_text(tree, tvb, offset, source_route_length,
1487 "Preferred Gateway Source Route: %s",
1488 tvb_bytes_to_str(tvb, offset, source_route_length));
1489 offset += source_route_length;
1495 proto_register_vines_rtp(void)
1497 static gint *ett[] = {
1499 &ett_vines_rtp_compatibility_flags,
1500 &ett_vines_rtp_req_info,
1501 &ett_vines_rtp_control_flags,
1502 &ett_vines_rtp_mtype,
1503 &ett_vines_rtp_flags,
1506 proto_vines_rtp = proto_register_protocol(
1507 "Banyan Vines RTP", "Vines RTP", "vines_rtp");
1508 proto_register_subtree_array(ett, array_length(ett));
1512 proto_reg_handoff_vines_rtp(void)
1514 dissector_handle_t vines_rtp_handle;
1516 vines_rtp_handle = create_dissector_handle(dissect_vines_rtp,
1518 dissector_add("vines_ip.protocol", VIP_PROTO_RTP, vines_rtp_handle);
1521 #define VICP_EXCEPTION_NOTIFICATION 0x0000
1522 #define VICP_METRIC_NOTIFICATION 0x0001
1524 static const value_string vines_icp_packet_type_vals[] = {
1525 { VICP_EXCEPTION_NOTIFICATION, "Exception notification" },
1526 { VICP_METRIC_NOTIFICATION, "Metric notification" },
1531 dissect_vines_icp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1534 proto_tree *vines_icp_tree = NULL;
1536 guint16 packet_type;
1537 guint16 exception_code;
1539 gboolean save_in_error_pkt;
1542 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines ICP");
1543 col_clear(pinfo->cinfo, COL_INFO);
1546 ti = proto_tree_add_item(tree, proto_vines_icp, tvb, 0, -1,
1548 vines_icp_tree = proto_item_add_subtree(ti, ett_vines_icp);
1551 packet_type = tvb_get_ntohs(tvb, offset);
1552 if (check_col(pinfo->cinfo, COL_INFO)) {
1553 col_add_str(pinfo->cinfo, COL_INFO,
1554 val_to_str(packet_type, vines_icp_packet_type_vals,
1555 "Unknown (0x%02x)"));
1558 proto_tree_add_text(vines_icp_tree, tvb, offset, 2,
1559 "Packet Type: %s (0x%04x)",
1560 val_to_str(packet_type,
1561 vines_icp_packet_type_vals,
1567 switch (packet_type) {
1569 case VICP_EXCEPTION_NOTIFICATION:
1570 exception_code = tvb_get_ntohs(tvb, offset);
1571 if (check_col(pinfo->cinfo, COL_INFO)) {
1572 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
1573 val_to_str(exception_code, vipc_err_vals,
1574 "Unknown exception code (%u)"));
1577 proto_tree_add_text(vines_icp_tree, tvb, offset, 2,
1578 "Exception Code: %s (%u)",
1579 val_to_str(exception_code,
1586 case VICP_METRIC_NOTIFICATION:
1587 metric = tvb_get_ntohs(tvb, offset);
1588 if (check_col(pinfo->cinfo, COL_INFO)) {
1589 col_append_fstr(pinfo->cinfo, COL_INFO, ", metric %u",
1593 proto_tree_add_text(vines_icp_tree, tvb, offset, 2,
1594 "Metric: %u", metric);
1601 * Save the current value of the "we're inside an error packet"
1602 * flag, and set that flag; subdissectors may treat packets
1603 * that are the payload of error packets differently from
1606 save_in_error_pkt = pinfo->in_error_pkt;
1607 pinfo->in_error_pkt = TRUE;
1609 /* Decode the first 40 bytes of the original VIP datagram. */
1610 next_tvb = tvb_new_subset_remaining(tvb, offset);
1611 call_dissector(vines_ip_handle, next_tvb, pinfo, vines_icp_tree);
1613 /* Restore the "we're inside an error packet" flag. */
1614 pinfo->in_error_pkt = save_in_error_pkt;
1618 proto_register_vines_icp(void)
1620 static gint *ett[] = {
1624 proto_vines_icp = proto_register_protocol(
1625 "Banyan Vines ICP", "Vines ICP", "vines_icp");
1626 proto_register_subtree_array(ett, array_length(ett));
1630 proto_reg_handoff_vines_icp(void)
1632 dissector_handle_t vines_icp_handle;
1634 vines_icp_handle = create_dissector_handle(dissect_vines_icp,
1636 dissector_add("vines_ip.protocol", VIP_PROTO_ICP, vines_icp_handle);