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 <jmayer@loplof.de>
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 if (check_col(pinfo->cinfo, COL_PROTOCOL))
113 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines FRP");
114 if (check_col(pinfo->cinfo, COL_INFO))
115 col_clear(pinfo->cinfo, COL_INFO);
118 ti = proto_tree_add_item(tree, proto_vines_frp, tvb, 0, 2,
120 vines_frp_tree = proto_item_add_subtree(ti, ett_vines_frp);
122 vines_frp_ctrl = tvb_get_guint8(tvb, 0);
125 * 1: first fragment of vines packet
126 * 2: last fragment of vines packet
129 switch (vines_frp_ctrl) {
132 frp_flags_str= "middle";
136 frp_flags_str= "first";
140 frp_flags_str= "last";
144 frp_flags_str= "only";
148 frp_flags_str= "please report: unknown";
152 proto_tree_add_text(vines_frp_tree, tvb, 0, 1,
153 "Control Flags: 0x%02x = %s fragment",
154 vines_frp_ctrl, frp_flags_str);
156 proto_tree_add_text(vines_frp_tree, tvb, 1, 1,
157 "Sequence Number: 0x%02x",
158 tvb_get_guint8(tvb, 1));
161 /* Decode the "real" Vines now */
162 next_tvb = tvb_new_subset(tvb, 2, -1, -1);
163 call_dissector(vines_ip_handle, next_tvb, pinfo, tree);
167 proto_register_vines_frp(void)
169 static gint *ett[] = {
173 proto_vines_frp = proto_register_protocol(
174 "Banyan Vines Fragmentation Protocol", "Vines FRP", "vines_frp");
175 proto_register_subtree_array(ett, array_length(ett));
179 proto_reg_handoff_vines_frp(void)
181 dissector_handle_t vines_frp_handle;
183 vines_frp_handle = create_dissector_handle(dissect_vines_frp,
185 dissector_add("ip.proto", IP_PROTO_VINES, vines_frp_handle);
187 /* XXX: AFAIK, src and dst port must be the same; should
188 the dissector check for that? */
189 dissector_add("udp.port", UDP_PORT_VINES, vines_frp_handle);
192 static dissector_table_t vines_llc_dissector_table;
194 #define VINES_LLC_IP 0xba
195 #define VINES_LLC_ECHO 0xbb
197 static const value_string vines_llc_ptype_vals[] = {
198 { VINES_LLC_IP, "Vines IP" },
199 { VINES_LLC_ECHO, "Vines Echo" },
204 dissect_vines_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
207 proto_tree *vines_llc_tree;
211 if (check_col(pinfo->cinfo, COL_PROTOCOL))
212 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines LLC");
213 if (check_col(pinfo->cinfo, COL_INFO))
214 col_clear(pinfo->cinfo, COL_INFO);
216 ptype = tvb_get_guint8(tvb, 0);
217 if (check_col(pinfo->cinfo, COL_INFO))
218 col_add_str(pinfo->cinfo, COL_INFO,
219 val_to_str(ptype, vines_llc_ptype_vals,
220 "Unknown protocol 0x%02x"));
222 ti = proto_tree_add_item(tree, proto_vines_llc, tvb, 0, 1,
224 vines_llc_tree = proto_item_add_subtree(ti, ett_vines_llc);
226 proto_tree_add_text(vines_llc_tree, tvb, 0, 1,
227 "Packet Type: %s (0x%02x)",
228 val_to_str(ptype, vines_llc_ptype_vals,
233 next_tvb = tvb_new_subset(tvb, 1, -1, -1);
234 if (!dissector_try_port(vines_llc_dissector_table, ptype,
235 next_tvb, pinfo, tree))
236 call_dissector(data_handle, next_tvb, pinfo, tree);
240 proto_register_vines_llc(void)
242 static gint *ett[] = {
246 proto_vines_llc = proto_register_protocol(
247 "Banyan Vines LLC", "Vines LLC", "vines_llc");
248 proto_register_subtree_array(ett, array_length(ett));
250 /* subdissector code */
251 vines_llc_dissector_table = register_dissector_table("vines_llc.ptype",
252 "Vines LLC protocol", FT_UINT8, BASE_HEX);
256 proto_reg_handoff_vines_llc(void)
258 dissector_handle_t vines_llc_handle;
260 vines_llc_handle = create_dissector_handle(dissect_vines_llc,
262 dissector_add("llc.dsap", SAP_VINES2, vines_llc_handle);
265 static dissector_table_t vines_ip_dissector_table;
267 static const value_string class_vals[] = {
268 { 0x00, "Reachable regardless of cost" },
269 { 0x10, "Reachable without cost" },
270 { 0x20, "Reachable with low cost (>= 4800 bps)" },
271 { 0x30, "Reachable via LAN" },
275 static const value_string proto_vals[] = {
276 { VIP_PROTO_IPC, "IPC" },
277 { VIP_PROTO_SPP, "SPP" },
278 { VIP_PROTO_ARP, "ARP" },
279 { VIP_PROTO_RTP, "RTP" },
280 { VIP_PROTO_ICP, "ICP" },
284 static const guint8 bcast_addr[VINES_ADDR_LEN] = {
285 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
289 dissect_vines_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
293 proto_tree *vip_tree, *tctl_tree;
295 const guint8 *dst_addr, *src_addr;
296 gboolean is_broadcast = FALSE;
300 if (check_col(pinfo->cinfo, COL_PROTOCOL))
301 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines IP");
302 if (check_col(pinfo->cinfo, COL_INFO))
303 col_clear(pinfo->cinfo, COL_INFO);
305 /* To do: check for runts, errs, etc. */
307 /* Avoids alignment problems on many architectures. */
308 tvb_memcpy(tvb, (guint8 *)&viph, offset, sizeof(e_vip));
310 viph.vip_chksum = g_ntohs(viph.vip_chksum);
311 viph.vip_pktlen = g_ntohs(viph.vip_pktlen);
313 if (check_col(pinfo->cinfo, COL_INFO)) {
314 col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%02x)",
315 val_to_str(viph.vip_proto, proto_vals,
316 "Unknown VIP protocol"),
320 src_addr = tvb_get_ptr(tvb, offset+12, VINES_ADDR_LEN);
321 SET_ADDRESS(&pinfo->net_src, AT_VINES, VINES_ADDR_LEN, src_addr);
322 SET_ADDRESS(&pinfo->src, AT_VINES, VINES_ADDR_LEN, src_addr);
323 dst_addr = tvb_get_ptr(tvb, offset+6, VINES_ADDR_LEN);
324 SET_ADDRESS(&pinfo->net_dst, AT_VINES, VINES_ADDR_LEN,dst_addr);
325 SET_ADDRESS(&pinfo->dst, AT_VINES, VINES_ADDR_LEN, dst_addr);
327 /* helpers to transport control */
328 if (memcmp(viph.vip_dst, bcast_addr, VINES_ADDR_LEN) == 0)
330 hops = viph.vip_tctl & 0xf;
333 * Adjust the length of this tvbuff to include only the Vines IP
336 set_actual_length(tvb, viph.vip_pktlen < 18 ? 18 : viph.vip_pktlen);
339 ti = proto_tree_add_item(tree, proto_vines_ip, tvb,
340 offset, viph.vip_pktlen,
342 vip_tree = proto_item_add_subtree(ti, ett_vines_ip);
343 proto_tree_add_text(vip_tree, tvb, offset, 2,
344 "Packet checksum: 0x%04x",
346 proto_tree_add_text(vip_tree, tvb, offset + 2, 2,
349 ti = proto_tree_add_text(vip_tree, tvb, offset + 4, 1,
350 "Transport control: 0x%02x",
352 tctl_tree = proto_item_add_subtree(ti, ett_vines_ip_tctl);
354 * XXX - bit 0x80 is "Normal" if 0; what is it if 1?
357 proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
358 decode_boolean_bitfield(viph.vip_tctl, 0x40, 1*8,
361 proto_tree_add_text(tctl_tree, tvb, offset + 4, 1, "%s",
362 decode_enumerated_bitfield(viph.vip_tctl, 0x30, 1*8,
365 proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
366 decode_boolean_bitfield(viph.vip_tctl, 0x40, 1*8,
367 "Forwarding router can handle redirect packets",
368 "Forwarding router cannot handle redirect packets"));
369 proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
370 decode_boolean_bitfield(viph.vip_tctl, 0x20, 1*8,
371 "Return metric notification packet",
372 "Do not return metric notification packet"));
373 proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
374 decode_boolean_bitfield(viph.vip_tctl, 0x10, 1*8,
375 "Return exception notification packet",
376 "Do not return exception notification packet"));
378 proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
379 decode_numeric_bitfield(viph.vip_tctl, 0x0F, 1*8,
380 "Hop count remaining = %u"));
381 proto_tree_add_uint(vip_tree, hf_vines_ip_protocol, tvb,
384 proto_tree_add_text(vip_tree, tvb, offset + 6,
387 vines_addr_to_str(dst_addr));
388 proto_tree_add_text(vip_tree, tvb, offset + 12,
391 vines_addr_to_str(src_addr));
395 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
396 if (!dissector_try_port(vines_ip_dissector_table, viph.vip_proto,
397 next_tvb, pinfo, tree))
398 call_dissector(data_handle, next_tvb, pinfo, tree);
402 proto_register_vines_ip(void)
404 static gint *ett[] = {
409 static hf_register_info hf[] = {
410 { &hf_vines_ip_protocol,
411 { "Protocol", "vines_ip.protocol",
412 FT_UINT8, BASE_HEX, VALS(proto_vals), 0x0,
413 "Vines protocol", HFILL }}
416 proto_vines_ip = proto_register_protocol("Banyan Vines IP", "Vines IP",
418 proto_register_field_array(proto_vines_ip, hf, array_length(hf));
419 proto_register_subtree_array(ett, array_length(ett));
421 /* subdissector code */
422 vines_ip_dissector_table = register_dissector_table("vines_ip.protocol",
423 "Vines protocol", FT_UINT8, BASE_HEX);
425 vines_ip_handle = create_dissector_handle(dissect_vines_ip,
430 proto_reg_handoff_vines_ip(void)
432 dissector_add("ethertype", ETHERTYPE_VINES_IP, vines_ip_handle);
433 dissector_add("ppp.protocol", PPP_VINES, vines_ip_handle);
434 dissector_add("arcnet.protocol_id", ARCNET_PROTO_BANYAN,
436 dissector_add("vines_llc.ptype", VINES_LLC_IP, vines_ip_handle);
437 data_handle = find_dissector("data");
441 dissect_vines_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
443 proto_tree *vines_echo_tree = NULL;
446 if (check_col(pinfo->cinfo, COL_PROTOCOL))
447 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines Echo");
448 if (check_col(pinfo->cinfo, COL_INFO))
449 col_clear(pinfo->cinfo, COL_INFO);
452 ti = proto_tree_add_item(tree, proto_vines_echo, tvb, 0, -1,
454 vines_echo_tree = proto_item_add_subtree(ti, ett_vines_echo);
455 proto_tree_add_text(vines_echo_tree, tvb, 0, -1, "Data");
460 proto_register_vines_echo(void)
462 static gint *ett[] = {
466 proto_vines_echo = proto_register_protocol(
467 "Banyan Vines Echo", "Vines Echo", "vines_echo");
468 proto_register_subtree_array(ett, array_length(ett));
472 proto_reg_handoff_vines_echo(void)
474 dissector_handle_t vines_echo_handle;
476 vines_echo_handle = create_dissector_handle(dissect_vines_echo,
478 dissector_add("vines_llc.ptype", VINES_LLC_ECHO, vines_echo_handle);
479 dissector_add("ethertype", ETHERTYPE_VINES_ECHO, vines_echo_handle);
482 static const value_string pkttype_vals[] = {
483 { PKTTYPE_DGRAM, "Datagram" },
484 { PKTTYPE_DATA, "Data" },
485 { PKTTYPE_ERR, "Error" },
486 { PKTTYPE_DISC, "Disconnect" },
487 { PKTTYPE_PROBE, "Probe" },
488 { PKTTYPE_ACK, "Ack" },
492 static heur_dissector_list_t vines_ipc_heur_subdissector_list;
494 static const value_string vipc_err_vals[] = {
495 { 151, "Bad socket descriptor" },
496 { 152, "Address already in use" },
497 { 153, "Invalid operation" },
498 { 154, "User address parameter fault" },
499 { 155, "Net/host unreachable" },
500 { 156, "Message overflow error" },
501 { 157, "Destination socket does not exist" },
502 { 158, "Address family does not exist" },
503 { 159, "Socket type does not exist" },
504 { 160, "Protocol does not exist" },
505 { 161, "No more sockets available" },
506 { 162, "No buffer space available" },
507 { 163, "Timeout event" },
508 { 164, "Operation not supported" },
509 { 165, "Resource not available" },
510 { 166, "Internal communication service failure" },
511 { 167, "Controller reset failure" },
516 dissect_vines_ipc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
520 proto_tree *vipc_tree = NULL, *control_tree;
524 if (check_col(pinfo->cinfo, COL_PROTOCOL))
525 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VIPC");
526 if (check_col(pinfo->cinfo, COL_INFO))
527 col_clear(pinfo->cinfo, COL_INFO);
529 /* To do: check for runts, errs, etc. */
531 /* Avoids alignment problems on many architectures. */
532 tvb_memcpy(tvb, (guint8 *)&viph, offset, sizeof(e_vipc));
534 viph.vipc_sport = g_ntohs(viph.vipc_sport);
535 viph.vipc_dport = g_ntohs(viph.vipc_dport);
536 viph.vipc_lclid = g_ntohs(viph.vipc_lclid);
537 viph.vipc_rmtid = g_ntohs(viph.vipc_rmtid);
538 viph.vipc_seqno = g_ntohs(viph.vipc_seqno);
539 viph.vipc_ack = g_ntohs(viph.vipc_ack);
540 viph.vipc_err_len = g_ntohs(viph.vipc_err_len);
542 if (check_col(pinfo->cinfo, COL_PROTOCOL))
543 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines IPC");
544 if (check_col(pinfo->cinfo, COL_INFO)) {
545 switch (viph.vipc_pkttype) {
548 col_add_fstr(pinfo->cinfo, COL_INFO,
550 val_to_str(viph.vipc_pkttype, pkttype_vals,
551 "Unknown packet type (0x%02x)"),
552 viph.vipc_dport, viph.vipc_sport);
556 col_add_fstr(pinfo->cinfo, COL_INFO,
557 "%s NS=%u NR=%u Err=%s RID=%04x LID=%04x D=%04x S=%04x",
558 val_to_str(viph.vipc_pkttype, pkttype_vals,
559 "Unknown packet type (0x%02x)"),
560 viph.vipc_seqno, viph.vipc_ack,
561 val_to_str(viph.vipc_err_len,
562 vipc_err_vals, "Unknown (%u)"),
563 viph.vipc_rmtid, viph.vipc_lclid,
564 viph.vipc_dport, viph.vipc_sport);
568 col_add_fstr(pinfo->cinfo, COL_INFO,
569 "%s NS=%u NR=%u Len=%u RID=%04x LID=%04x D=%04x S=%04x",
570 val_to_str(viph.vipc_pkttype, pkttype_vals,
571 "Unknown packet type (0x%02x)"),
572 viph.vipc_seqno, viph.vipc_ack,
573 viph.vipc_err_len, viph.vipc_rmtid,
574 viph.vipc_lclid, viph.vipc_dport,
581 ti = proto_tree_add_item(tree, proto_vines_ipc, tvb, offset,
582 sizeof(viph), FALSE);
583 vipc_tree = proto_item_add_subtree(ti, ett_vines_ipc);
584 proto_tree_add_text(vipc_tree, tvb, offset, 2,
585 "Source port: 0x%04x", viph.vipc_sport);
589 proto_tree_add_text(vipc_tree, tvb, offset, 2,
590 "Destination port: 0x%04x",
595 proto_tree_add_text(vipc_tree, tvb, offset, 1,
596 "Packet type: 0x%02x (%s)",
598 val_to_str(viph.vipc_pkttype, pkttype_vals,
602 if (viph.vipc_pkttype != PKTTYPE_DGRAM) {
604 ti = proto_tree_add_text(vipc_tree, tvb, offset, 1,
607 control_tree = proto_item_add_subtree(ti,
608 ett_vines_ipc_control);
610 * XXX - do reassembly based on BOM/EOM bits.
612 proto_tree_add_text(control_tree, tvb, offset, 1,
613 decode_boolean_bitfield(viph.vipc_control, 0x80,
615 "Send immediate acknowledgment",
616 "Do not send immediate acknowledgement"));
617 proto_tree_add_text(control_tree, tvb, offset, 1,
618 decode_boolean_bitfield(viph.vipc_control, 0x40,
621 "Not end of message"));
622 proto_tree_add_text(control_tree, tvb, offset, 1,
623 decode_boolean_bitfield(viph.vipc_control, 0x20,
625 "Beginning of message",
626 "Not beginning of message"));
627 proto_tree_add_text(control_tree, tvb, offset, 1,
628 decode_boolean_bitfield(viph.vipc_control, 0x10,
630 "Abort current message",
631 "Do not abort current message"));
635 if (viph.vipc_pkttype != PKTTYPE_DGRAM) {
637 proto_tree_add_text(vipc_tree, tvb, offset, 2,
638 "Local Connection ID: 0x%04x",
643 proto_tree_add_text(vipc_tree, tvb, offset, 2,
644 "Remote Connection ID: 0x%04x",
649 proto_tree_add_text(vipc_tree, tvb, offset, 2,
650 "Sequence number: %u",
655 proto_tree_add_text(vipc_tree, tvb, offset, 2,
656 "Ack number: %u", viph.vipc_ack);
660 if (viph.vipc_pkttype == PKTTYPE_ERR) {
661 proto_tree_add_text(vipc_tree, tvb, offset, 2,
663 val_to_str(viph.vipc_err_len,
668 proto_tree_add_text(vipc_tree, tvb, offset, 2,
677 * For data packets, try the heuristic dissectors for Vines SPP;
678 * if none of them accept the packet, or if it's not a data packet,
679 * dissect it as data.
681 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
682 if (viph.vipc_pkttype != PKTTYPE_DATA ||
683 !dissector_try_heuristic(vines_ipc_heur_subdissector_list,
684 next_tvb, pinfo, tree))
685 call_dissector(data_handle, next_tvb, pinfo, tree);
689 proto_register_vines_ipc(void)
691 static gint *ett[] = {
693 &ett_vines_ipc_control,
696 proto_vines_ipc = proto_register_protocol("Banyan Vines IPC",
697 "Vines IPC", "vines_ipc");
698 proto_register_subtree_array(ett, array_length(ett));
700 register_heur_dissector_list("vines_ipc",
701 &vines_ipc_heur_subdissector_list);
705 proto_reg_handoff_vines_ipc(void)
707 dissector_handle_t vines_ipc_handle;
709 vines_ipc_handle = create_dissector_handle(dissect_vines_ipc,
711 dissector_add("vines_ip.protocol", VIP_PROTO_IPC, vines_ipc_handle);
714 static heur_dissector_list_t vines_spp_heur_subdissector_list;
717 dissect_vines_spp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
721 proto_tree *vspp_tree, *control_tree;
725 if (check_col(pinfo->cinfo, COL_PROTOCOL))
726 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSPP");
727 if (check_col(pinfo->cinfo, COL_INFO))
728 col_clear(pinfo->cinfo, COL_INFO);
730 /* To do: check for runts, errs, etc. */
732 /* Avoids alignment problems on many architectures. */
733 tvb_memcpy(tvb, (guint8 *)&viph, offset, sizeof(e_vspp));
735 viph.vspp_sport = g_ntohs(viph.vspp_sport);
736 viph.vspp_dport = g_ntohs(viph.vspp_dport);
737 viph.vspp_lclid = g_ntohs(viph.vspp_lclid);
738 viph.vspp_rmtid = g_ntohs(viph.vspp_rmtid);
739 viph.vspp_seqno = g_ntohs(viph.vspp_seqno);
740 viph.vspp_ack = g_ntohs(viph.vspp_ack);
741 viph.vspp_win = g_ntohs(viph.vspp_win);
743 if (check_col(pinfo->cinfo, COL_PROTOCOL))
744 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines SPP");
745 if (check_col(pinfo->cinfo, COL_INFO))
746 col_add_fstr(pinfo->cinfo, COL_INFO,
747 "%s NS=%u NR=%u Window=%u RID=%04x LID=%04x D=%04x S=%04x",
748 val_to_str(viph.vspp_pkttype, pkttype_vals,
749 "Unknown packet type (0x%02x)"),
750 viph.vspp_seqno, viph.vspp_ack, viph.vspp_win,
751 viph.vspp_rmtid, viph.vspp_lclid, viph.vspp_dport,
755 ti = proto_tree_add_item(tree, proto_vines_spp, tvb, offset,
756 sizeof(viph), FALSE);
757 vspp_tree = proto_item_add_subtree(ti, ett_vines_spp);
758 proto_tree_add_text(vspp_tree, tvb, offset, 2,
759 "Source port: 0x%04x", viph.vspp_sport);
760 proto_tree_add_text(vspp_tree, tvb, offset + 2, 2,
761 "Destination port: 0x%04x",
763 proto_tree_add_text(vspp_tree, tvb, offset + 4, 1,
764 "Packet type: 0x%02x (%s)",
766 val_to_str(viph.vspp_pkttype, pkttype_vals,
768 ti = proto_tree_add_text(vspp_tree, tvb, offset + 5, 1,
769 "Control: 0x%02x", viph.vspp_control);
770 control_tree = proto_item_add_subtree(ti, ett_vines_spp_control);
772 * XXX - do reassembly based on BOM/EOM bits.
774 proto_tree_add_text(control_tree, tvb, offset + 5, 1,
775 decode_boolean_bitfield(viph.vspp_control, 0x80, 1*8,
776 "Send immediate acknowledgment",
777 "Do not send immediate acknowledgement"));
778 proto_tree_add_text(control_tree, tvb, offset + 5, 1,
779 decode_boolean_bitfield(viph.vspp_control, 0x40, 1*8,
781 "Not end of message"));
782 proto_tree_add_text(control_tree, tvb, offset + 5, 1,
783 decode_boolean_bitfield(viph.vspp_control, 0x20, 1*8,
784 "Beginning of message",
785 "Not beginning of message"));
786 proto_tree_add_text(control_tree, tvb, offset + 5, 1,
787 decode_boolean_bitfield(viph.vspp_control, 0x10, 1*8,
788 "Abort current message",
789 "Do not abort current message"));
790 proto_tree_add_text(vspp_tree, tvb, offset + 6, 2,
791 "Local Connection ID: 0x%04x",
793 proto_tree_add_text(vspp_tree, tvb, offset + 8, 2,
794 "Remote Connection ID: 0x%04x",
796 proto_tree_add_text(vspp_tree, tvb, offset + 10, 2,
797 "Sequence number: %u",
799 proto_tree_add_text(vspp_tree, tvb, offset + 12, 2,
800 "Ack number: %u", viph.vspp_ack);
801 proto_tree_add_text(vspp_tree, tvb, offset + 14, 2,
802 "Window: %u", viph.vspp_win);
804 offset += 16; /* sizeof SPP */
807 * For data packets, try the heuristic dissectors for Vines SPP;
808 * if none of them accept the packet, or if it's not a data packet,
809 * dissect it as data.
811 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
812 if (viph.vspp_pkttype != PKTTYPE_DATA ||
813 !dissector_try_heuristic(vines_spp_heur_subdissector_list,
814 next_tvb, pinfo, tree))
815 call_dissector(data_handle, next_tvb, pinfo, tree);
819 proto_register_vines_spp(void)
821 static gint *ett[] = {
823 &ett_vines_spp_control,
826 proto_vines_spp = proto_register_protocol("Banyan Vines SPP",
827 "Vines SPP", "vines_spp");
828 proto_register_subtree_array(ett, array_length(ett));
830 register_heur_dissector_list("vines_spp",
831 &vines_spp_heur_subdissector_list);
835 proto_reg_handoff_vines_spp(void)
837 dissector_handle_t vines_spp_handle;
839 vines_spp_handle = create_dissector_handle(dissect_vines_spp,
841 dissector_add("vines_ip.protocol", VIP_PROTO_SPP, vines_spp_handle);
844 #define VINES_VERS_PRE_5_5 0x00
845 #define VINES_VERS_5_5 0x01
847 static const value_string vines_version_vals[] = {
848 { VINES_VERS_PRE_5_5, "Pre-5.50" },
849 { VINES_VERS_5_5, "5.50" },
853 #define VARP_QUERY_REQ 0x00
854 #define VARP_SERVICE_RESP 0x01
855 #define VARP_ASSIGNMENT_REQ 0x02
856 #define VARP_ASSIGNMENT_RESP 0x03
858 static const value_string vines_arp_packet_type_vals[] = {
859 { VARP_QUERY_REQ, "Query request" },
860 { VARP_SERVICE_RESP, "Service response" },
861 { VARP_ASSIGNMENT_REQ, "Assignment request" },
862 { VARP_ASSIGNMENT_RESP, "Assignment response" },
867 dissect_vines_arp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
869 proto_tree *vines_arp_tree = NULL;
875 if (check_col(pinfo->cinfo, COL_PROTOCOL))
876 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines ARP");
877 if (check_col(pinfo->cinfo, COL_INFO))
878 col_clear(pinfo->cinfo, COL_INFO);
881 ti = proto_tree_add_item(tree, proto_vines_arp, tvb, 0, -1,
883 vines_arp_tree = proto_item_add_subtree(ti, ett_vines_arp);
886 version = tvb_get_guint8(tvb, 0);
888 proto_tree_add_text(vines_arp_tree, tvb, 0, 1,
889 "Version: %s (0x%02x)",
890 val_to_str(version, vines_version_vals,
894 if (version == VINES_VERS_5_5) {
898 if (check_col(pinfo->cinfo, COL_PROTOCOL))
899 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines SARP");
900 packet_type = tvb_get_guint8(tvb, 1);
901 if (check_col(pinfo->cinfo, COL_INFO)) {
902 col_add_str(pinfo->cinfo, COL_INFO,
903 val_to_str(packet_type, vines_arp_packet_type_vals,
904 "Unknown (0x%02x)"));
907 proto_tree_add_text(vines_arp_tree, tvb, 1, 1,
908 "Packet Type: %s (0x%02x)",
909 val_to_str(packet_type,
910 vines_arp_packet_type_vals,
914 if (packet_type == VARP_ASSIGNMENT_RESP) {
915 if (check_col(pinfo->cinfo, COL_INFO)) {
916 col_append_fstr(pinfo->cinfo, COL_INFO,
918 vines_addr_to_str(tvb_get_ptr(tvb, 2, VINES_ADDR_LEN)));
921 proto_tree_add_text(vines_arp_tree, tvb, 2,
924 vines_addr_to_str(tvb_get_ptr(tvb, 2, VINES_ADDR_LEN)));
928 proto_tree_add_text(vines_arp_tree, tvb,
930 "Sequence Number: %u",
931 tvb_get_ntohl(tvb, 2+VINES_ADDR_LEN));
932 metric = tvb_get_ntohs(tvb, 2+VINES_ADDR_LEN+4);
933 proto_tree_add_text(vines_arp_tree, tvb,
934 2+VINES_ADDR_LEN+4, 2,
935 "Interface Metric: %u ticks (%g seconds)",
942 packet_type = (guint8) tvb_get_ntohs(tvb, 0);
943 if (check_col(pinfo->cinfo, COL_INFO)) {
944 col_add_str(pinfo->cinfo, COL_INFO,
945 val_to_str(packet_type, vines_arp_packet_type_vals,
946 "Unknown (0x%02x)"));
949 proto_tree_add_text(vines_arp_tree, tvb, 0, 2,
950 "Packet Type: %s (0x%04x)",
951 val_to_str(packet_type,
952 vines_arp_packet_type_vals,
956 if (packet_type == VARP_ASSIGNMENT_RESP) {
957 if (check_col(pinfo->cinfo, COL_INFO)) {
958 col_append_fstr(pinfo->cinfo, COL_INFO,
960 vines_addr_to_str(tvb_get_ptr(tvb, 2, VINES_ADDR_LEN)));
963 proto_tree_add_text(vines_arp_tree, tvb, 2,
966 vines_addr_to_str(tvb_get_ptr(tvb, 2, VINES_ADDR_LEN)));
973 proto_register_vines_arp(void)
975 static gint *ett[] = {
979 proto_vines_arp = proto_register_protocol(
980 "Banyan Vines ARP", "Vines ARP", "vines_arp");
981 proto_register_subtree_array(ett, array_length(ett));
985 proto_reg_handoff_vines_arp(void)
987 dissector_handle_t vines_arp_handle;
989 vines_arp_handle = create_dissector_handle(dissect_vines_arp,
991 dissector_add("vines_ip.protocol", VIP_PROTO_ARP, vines_arp_handle);
994 #define VRTP_OP_REQUEST 0x01
995 #define VRTP_OP_UPDATE_RESPONSE 0x02
996 #define VRTP_OP_REDIRECT 0x03
997 #define VRTP_OP_REINITIALIZE 0x04
998 #define VRTP_OP_REDIRECT2 0x06
1000 static const value_string vines_rtp_operation_type_vals[] = {
1001 { VRTP_OP_REQUEST, "Request" },
1002 { VRTP_OP_UPDATE_RESPONSE, "Update/response" },
1003 { VRTP_OP_REDIRECT, "Redirect" },
1004 { VRTP_OP_REINITIALIZE, "Reinitialize" },
1005 { VRTP_OP_REDIRECT2, "Redirect" },
1009 static const value_string vines_rtp_node_type_vals[] = {
1015 static const value_string vines_rtp_controller_type_vals[] = {
1016 { 0x00, "Default Card" },
1017 { 0x01, "Multibuffer" },
1021 static const value_string vines_rtp_info_type_vals[] = {
1024 { 0x02, "Response" },
1028 static void rtp_show_machine_type(proto_tree *tree, tvbuff_t *tvb, int offset,
1030 static void rtp_show_flags(proto_tree *tree, tvbuff_t *tvb, int offset,
1032 static int srtp_show_machine_info(proto_tree *tree, tvbuff_t *tvb, int offset,
1034 static int rtp_show_gateway_info(proto_tree *tree, tvbuff_t *tvb, int offset,
1035 guint8 link_addr_length, guint8 source_route_length);
1038 dissect_vines_rtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1041 proto_tree *vines_rtp_tree = NULL;
1043 proto_tree *subtree;
1045 guint8 operation_type;
1047 guint8 controller_type;
1048 guint8 compatibility_flags;
1049 guint8 link_addr_length;
1050 guint8 source_route_length;
1051 guint8 requested_info;
1053 guint8 control_flags;
1056 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1057 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines RTP");
1058 if (check_col(pinfo->cinfo, COL_INFO))
1059 col_clear(pinfo->cinfo, COL_INFO);
1062 ti = proto_tree_add_item(tree, proto_vines_rtp, tvb, 0, -1,
1064 vines_rtp_tree = proto_item_add_subtree(ti, ett_vines_rtp);
1067 if (tvb_get_guint8(tvb, 0) != 0) {
1069 * Non-sequenced RTP.
1071 operation_type = tvb_get_guint8(tvb, offset);
1072 if (check_col(pinfo->cinfo, COL_INFO)) {
1073 col_add_str(pinfo->cinfo, COL_INFO,
1074 val_to_str(operation_type, vines_rtp_operation_type_vals,
1075 "Unknown (0x%02x)"));
1078 proto_tree_add_text(vines_rtp_tree, tvb, offset, 1,
1079 "Operation Type: %s (0x%02x)",
1080 val_to_str(operation_type,
1081 vines_rtp_operation_type_vals,
1085 node_type = tvb_get_guint8(tvb, offset);
1086 proto_tree_add_text(vines_rtp_tree, tvb, offset, 1,
1087 "Node Type: %s (0x%02x)",
1088 val_to_str(node_type,
1089 vines_rtp_node_type_vals,
1093 controller_type = tvb_get_guint8(tvb, offset);
1094 proto_tree_add_text(vines_rtp_tree, tvb, offset, 1,
1095 "Controller Type: %s (0x%02x)",
1096 val_to_str(controller_type,
1097 vines_rtp_controller_type_vals,
1101 rtp_show_machine_type(vines_rtp_tree, tvb, offset,
1104 switch (operation_type) {
1106 case VRTP_OP_REDIRECT:
1107 case VRTP_OP_REDIRECT2:
1108 proto_tree_add_text(vines_rtp_tree, tvb,
1111 tvb_get_ntohs(tvb, offset));
1113 link_addr_length = tvb_get_guint8(tvb, offset);
1114 proto_tree_add_text(vines_rtp_tree, tvb,
1116 "Link Address Length: %u",
1119 source_route_length = tvb_get_guint8(tvb, offset);
1120 proto_tree_add_text(vines_rtp_tree, tvb,
1122 "Source Route Length: %u",
1123 source_route_length);
1125 offset = srtp_show_machine_info(vines_rtp_tree,
1126 tvb, offset, "Destination");
1128 offset = srtp_show_machine_info(vines_rtp_tree,
1129 tvb, offset, "Preferred Gateway");
1131 offset = rtp_show_gateway_info(vines_rtp_tree,
1132 tvb,offset, link_addr_length,
1133 source_route_length);
1137 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1138 proto_tree_add_text(vines_rtp_tree, tvb,
1140 "Network Number: 0x%08x",
1141 tvb_get_ntohl(tvb, offset));
1143 metric = tvb_get_ntohs(tvb, offset);
1144 proto_tree_add_text(vines_rtp_tree, tvb,
1146 "Neighbor Metric: %u ticks (%g seconds)",
1155 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1156 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines SRTP");
1158 version = tvb_get_ntohs(tvb, offset);
1159 proto_tree_add_text(vines_rtp_tree, tvb, offset, 2,
1160 "Version: %s (0x%04x)",
1161 val_to_str(version, vines_version_vals,
1166 operation_type = tvb_get_guint8(tvb, offset);
1167 if (check_col(pinfo->cinfo, COL_INFO)) {
1168 col_add_str(pinfo->cinfo, COL_INFO,
1169 val_to_str(operation_type, vines_rtp_operation_type_vals,
1170 "Unknown (0x%02x)"));
1173 proto_tree_add_text(vines_rtp_tree, tvb, offset, 1,
1174 "Operation Type: %s (0x%02x)",
1175 val_to_str(operation_type,
1176 vines_rtp_operation_type_vals,
1180 node_type = tvb_get_guint8(tvb, offset);
1181 proto_tree_add_text(vines_rtp_tree, tvb, offset, 1,
1182 "Node Type: %s (0x%02x)",
1183 val_to_str(node_type,
1184 vines_rtp_node_type_vals,
1188 compatibility_flags = tvb_get_guint8(tvb, offset);
1189 ti = proto_tree_add_text(vines_rtp_tree, tvb, offset, 1,
1190 "Compatibility Flags: 0x%02x",
1191 compatibility_flags);
1192 subtree = proto_item_add_subtree(ti,
1193 ett_vines_rtp_compatibility_flags);
1194 proto_tree_add_text(subtree, tvb,
1196 decode_boolean_bitfield(compatibility_flags,
1198 "Auto-configured non-Vines-reachable neighbor router",
1199 "Not an auto-configured non-Vines-reachable neighbor router"));
1200 proto_tree_add_text(subtree, tvb,
1202 decode_boolean_bitfield(compatibility_flags,
1204 "Not all neighbor routers support Sequenced RTP",
1205 "All neighbor routers support Sequenced RTP"));
1206 proto_tree_add_text(subtree, tvb,
1208 decode_boolean_bitfield(compatibility_flags,
1210 "Sequenced RTP version mismatch",
1211 "No Sequenced RTP version mismatch"));
1213 offset += 1; /* reserved */
1214 switch (operation_type) {
1216 case VRTP_OP_REQUEST:
1217 requested_info = tvb_get_guint8(tvb, offset);
1218 proto_tree_add_text(vines_rtp_tree, tvb,
1220 "Requested Info: 0x%02x",
1224 case VRTP_OP_UPDATE_RESPONSE:
1225 info_type = tvb_get_guint8(tvb, offset);
1226 proto_tree_add_text(vines_rtp_tree, tvb,
1228 "Information Type: %s (0x%02x)",
1229 val_to_str(info_type,
1230 vines_rtp_info_type_vals,
1234 control_flags = tvb_get_guint8(tvb, offset);
1235 ti = proto_tree_add_text(vines_rtp_tree, tvb,
1237 "Control Flags: 0x%02x",
1239 subtree = proto_item_add_subtree(ti,
1240 ett_vines_rtp_control_flags);
1241 proto_tree_add_text(subtree, tvb,
1243 decode_boolean_bitfield(control_flags,
1245 "Part of routing table synchronization broadcast",
1246 "Not part of routing table synchronization broadcast"));
1247 proto_tree_add_text(subtree, tvb,
1249 decode_boolean_bitfield(control_flags,
1251 "Part of full topology update",
1252 "Not part of full topology update"));
1253 proto_tree_add_text(subtree, tvb,
1255 decode_boolean_bitfield(control_flags,
1257 "Contains info specifically requested or network changes",
1258 "Not a response to a specific request"));
1259 /* XXX - need reassembly? */
1260 proto_tree_add_text(subtree, tvb,
1262 decode_boolean_bitfield(control_flags,
1265 "Not end of message"));
1266 proto_tree_add_text(subtree, tvb,
1268 decode_boolean_bitfield(control_flags,
1270 "Beginning of message",
1271 "Not beginning of message"));
1273 proto_tree_add_text(vines_rtp_tree, tvb,
1276 tvb_get_ntohs(tvb, offset));
1278 proto_tree_add_text(vines_rtp_tree, tvb,
1281 tvb_get_ntohs(tvb, offset));
1283 proto_tree_add_text(vines_rtp_tree, tvb,
1285 "Router Sequence Number: %u",
1286 tvb_get_ntohl(tvb, offset));
1288 metric = tvb_get_ntohs(tvb, offset);
1289 proto_tree_add_text(vines_rtp_tree, tvb,
1291 "Metric: %u ticks (%g seconds)",
1294 while (tvb_reported_length_remaining(tvb, offset) > 0) {
1295 proto_tree_add_text(vines_rtp_tree, tvb,
1297 "Network Number: 0x%08x",
1298 tvb_get_ntohl(tvb, offset));
1300 metric = tvb_get_ntohs(tvb, offset);
1301 if (metric == 0xffff) {
1302 proto_tree_add_text(vines_rtp_tree, tvb,
1304 "Neighbor Metric: Unreachable");
1306 proto_tree_add_text(vines_rtp_tree, tvb,
1308 "Neighbor Metric: %u ticks (%g seconds)",
1312 proto_tree_add_text(vines_rtp_tree, tvb,
1314 "Sequence Number: %u",
1315 tvb_get_ntohl(tvb, offset));
1317 rtp_show_flags(vines_rtp_tree, tvb,
1320 offset += 1; /* reserved */
1324 case VRTP_OP_REDIRECT:
1325 link_addr_length = tvb_get_guint8(tvb, offset);
1326 proto_tree_add_text(vines_rtp_tree, tvb,
1328 "Link Address Length: %u",
1331 source_route_length = tvb_get_guint8(tvb, offset);
1332 proto_tree_add_text(vines_rtp_tree, tvb,
1334 "Source Route Length: %u",
1335 source_route_length);
1337 proto_tree_add_text(vines_rtp_tree, tvb,
1338 offset, VINES_ADDR_LEN,
1340 vines_addr_to_str(tvb_get_ptr(tvb, offset, VINES_ADDR_LEN)));
1341 offset += VINES_ADDR_LEN;
1342 metric = tvb_get_ntohs(tvb, offset);
1343 proto_tree_add_text(vines_rtp_tree, tvb,
1345 "Metric to Destination: %u ticks (%g seconds)",
1348 node_type = tvb_get_guint8(tvb, offset);
1349 proto_tree_add_text(vines_rtp_tree, tvb,
1351 "Destination Node Type: %s (0x%02x)",
1352 val_to_str(node_type,
1353 vines_rtp_node_type_vals,
1357 rtp_show_flags(vines_rtp_tree, tvb,
1358 offset, "Destination");
1360 proto_tree_add_text(vines_rtp_tree, tvb,
1362 "Destination Sequence Number: %u",
1363 tvb_get_ntohl(tvb, offset));
1365 proto_tree_add_text(vines_rtp_tree, tvb,
1366 offset, VINES_ADDR_LEN,
1367 "Preferred Gateway: %s",
1368 vines_addr_to_str(tvb_get_ptr(tvb, offset, VINES_ADDR_LEN)));
1369 offset += VINES_ADDR_LEN;
1370 metric = tvb_get_ntohs(tvb, offset);
1371 proto_tree_add_text(vines_rtp_tree, tvb,
1373 "Metric to Preferred Gateway: %u ticks (%g seconds)",
1376 node_type = tvb_get_guint8(tvb, offset);
1377 proto_tree_add_text(vines_rtp_tree, tvb,
1379 "Preferred Gateway Node Type: %s (0x%02x)",
1380 val_to_str(node_type,
1381 vines_rtp_node_type_vals,
1385 rtp_show_flags(vines_rtp_tree, tvb,
1386 offset, "Preferred Gateway");
1388 proto_tree_add_text(vines_rtp_tree, tvb,
1390 "Preferred Gateway Sequence Number: %u",
1391 tvb_get_ntohl(tvb, offset));
1393 offset = rtp_show_gateway_info(vines_rtp_tree,
1394 tvb,offset, link_addr_length,
1395 source_route_length);
1398 case VRTP_OP_REINITIALIZE:
1407 rtp_show_machine_type(proto_tree *tree, tvbuff_t *tvb, int offset, const char *tag)
1409 guint8 machine_type;
1411 proto_tree *subtree;
1413 machine_type = tvb_get_guint8(tvb, offset);
1414 ti = proto_tree_add_text(tree, tvb, offset, 1,
1415 "%s%sMachine Type: 0x%02x",
1416 tag == NULL ? "" : tag,
1417 tag == NULL ? "" : " ",
1419 subtree = proto_item_add_subtree(ti, ett_vines_rtp_mtype);
1420 proto_tree_add_text(subtree, tvb, offset, 1,
1421 decode_boolean_bitfield(machine_type, 0x04, 1*8,
1422 "Sequenced RTP supported",
1423 "Sequenced RTP not supported"));
1424 proto_tree_add_text(subtree, tvb, offset, 1,
1425 decode_boolean_bitfield(machine_type, 0x02, 1*8,
1427 "TCP/IP not supported"));
1428 proto_tree_add_text(subtree, tvb, offset, 1,
1429 decode_boolean_bitfield(machine_type, 0x01, 1*8,
1435 rtp_show_flags(proto_tree *tree, tvbuff_t *tvb, int offset, const char *tag)
1439 proto_tree *flags_tree;
1441 flags = tvb_get_guint8(tvb, offset);
1442 ti = proto_tree_add_text(tree, tvb, offset, 1, "%s Flags: 0x%02x",
1444 flags_tree = proto_item_add_subtree(ti, ett_vines_rtp_flags);
1445 proto_tree_add_text(flags_tree, tvb, offset, 1,
1446 decode_boolean_bitfield(flags, 0x08, 1*8,
1447 "Network doesn't support Sequenced RTP",
1448 "Network supports Sequenced RTP"));
1449 proto_tree_add_text(flags_tree, tvb, offset, 1,
1450 decode_boolean_bitfield(flags, 0x04, 1*8,
1451 "Network accessed point-to-point on non-Vines network",
1452 "Network not accessed point-to-point on non-Vines network"));
1453 proto_tree_add_text(flags_tree, tvb, offset, 1,
1454 decode_boolean_bitfield(flags, 0x02, 1*8,
1455 "Data link to network uses point-to-point connection",
1456 "Data link to network doesn't use point-to-point connection"));
1457 proto_tree_add_text(flags_tree, tvb, offset, 1,
1458 decode_boolean_bitfield(flags, 0x01, 1*8,
1459 "Network accessed across broadcast medium",
1460 "Network not accessed across broadcast medium"));
1464 srtp_show_machine_info(proto_tree *tree, tvbuff_t *tvb, int offset, const char *tag)
1468 guint8 controller_type;
1470 proto_tree_add_text(tree, tvb, offset, VINES_ADDR_LEN,
1472 vines_addr_to_str(tvb_get_ptr(tvb, offset, VINES_ADDR_LEN)));
1473 offset += VINES_ADDR_LEN;
1474 metric = tvb_get_ntohs(tvb, offset);
1475 proto_tree_add_text(tree, tvb, offset, 2,
1476 "Metric to %s: %u ticks (%g seconds)", tag, metric, metric*.2);
1478 node_type = tvb_get_guint8(tvb, offset);
1479 proto_tree_add_text(tree, tvb, offset, 1,
1480 "%s Node Type: %s (0x%02x)", tag,
1481 val_to_str(node_type, vines_rtp_node_type_vals, "Unknown"),
1484 rtp_show_machine_type(tree, tvb, offset, tag);
1486 controller_type = tvb_get_guint8(tvb, offset);
1487 proto_tree_add_text(tree, tvb, offset, 1,
1488 "%s Controller Type: %s (0x%02x)", tag,
1489 val_to_str(controller_type, vines_rtp_controller_type_vals, "Unknown"),
1496 rtp_show_gateway_info(proto_tree *tree, tvbuff_t *tvb, int offset,
1497 guint8 link_addr_length, guint8 source_route_length)
1499 if (link_addr_length != 0) {
1500 proto_tree_add_text(tree, tvb, offset, link_addr_length,
1501 "Preferred Gateway Data Link Address: %s",
1502 link_addr_length == 6 ?
1503 ether_to_str(tvb_get_ptr(tvb, offset, link_addr_length)) :
1504 tvb_bytes_to_str(tvb, offset, link_addr_length));
1505 offset += link_addr_length;
1507 if (source_route_length != 0) {
1508 proto_tree_add_text(tree, tvb, offset, source_route_length,
1509 "Preferred Gateway Source Route: %s",
1510 tvb_bytes_to_str(tvb, offset, source_route_length));
1511 offset += source_route_length;
1517 proto_register_vines_rtp(void)
1519 static gint *ett[] = {
1521 &ett_vines_rtp_compatibility_flags,
1522 &ett_vines_rtp_req_info,
1523 &ett_vines_rtp_control_flags,
1524 &ett_vines_rtp_mtype,
1525 &ett_vines_rtp_flags,
1528 proto_vines_rtp = proto_register_protocol(
1529 "Banyan Vines RTP", "Vines RTP", "vines_rtp");
1530 proto_register_subtree_array(ett, array_length(ett));
1534 proto_reg_handoff_vines_rtp(void)
1536 dissector_handle_t vines_rtp_handle;
1538 vines_rtp_handle = create_dissector_handle(dissect_vines_rtp,
1540 dissector_add("vines_ip.protocol", VIP_PROTO_RTP, vines_rtp_handle);
1543 #define VICP_EXCEPTION_NOTIFICATION 0x0000
1544 #define VICP_METRIC_NOTIFICATION 0x0001
1546 static const value_string vines_icp_packet_type_vals[] = {
1547 { VICP_EXCEPTION_NOTIFICATION, "Exception notification" },
1548 { VICP_METRIC_NOTIFICATION, "Metric notification" },
1553 dissect_vines_icp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1556 proto_tree *vines_icp_tree = NULL;
1558 guint16 packet_type;
1559 guint16 exception_code;
1561 gboolean save_in_error_pkt;
1564 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1565 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines ICP");
1566 if (check_col(pinfo->cinfo, COL_INFO))
1567 col_clear(pinfo->cinfo, COL_INFO);
1570 ti = proto_tree_add_item(tree, proto_vines_icp, tvb, 0, -1,
1572 vines_icp_tree = proto_item_add_subtree(ti, ett_vines_icp);
1575 packet_type = tvb_get_ntohs(tvb, offset);
1576 if (check_col(pinfo->cinfo, COL_INFO)) {
1577 col_add_str(pinfo->cinfo, COL_INFO,
1578 val_to_str(packet_type, vines_icp_packet_type_vals,
1579 "Unknown (0x%02x)"));
1582 proto_tree_add_text(vines_icp_tree, tvb, offset, 2,
1583 "Packet Type: %s (0x%04x)",
1584 val_to_str(packet_type,
1585 vines_icp_packet_type_vals,
1591 switch (packet_type) {
1593 case VICP_EXCEPTION_NOTIFICATION:
1594 exception_code = tvb_get_ntohs(tvb, offset);
1595 if (check_col(pinfo->cinfo, COL_INFO)) {
1596 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
1597 val_to_str(exception_code, vipc_err_vals,
1598 "Unknown exception code (%u)"));
1601 proto_tree_add_text(vines_icp_tree, tvb, offset, 2,
1602 "Exception Code: %s (%u)",
1603 val_to_str(exception_code,
1610 case VICP_METRIC_NOTIFICATION:
1611 metric = tvb_get_ntohs(tvb, offset);
1612 if (check_col(pinfo->cinfo, COL_INFO)) {
1613 col_append_fstr(pinfo->cinfo, COL_INFO, ", metric %u",
1617 proto_tree_add_text(vines_icp_tree, tvb, offset, 2,
1618 "Metric: %u", metric);
1625 * Save the current value of the "we're inside an error packet"
1626 * flag, and set that flag; subdissectors may treat packets
1627 * that are the payload of error packets differently from
1630 save_in_error_pkt = pinfo->in_error_pkt;
1631 pinfo->in_error_pkt = TRUE;
1633 /* Decode the first 40 bytes of the original VIP datagram. */
1634 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
1635 call_dissector(vines_ip_handle, next_tvb, pinfo, vines_icp_tree);
1637 /* Restore the "we're inside an error packet" flag. */
1638 pinfo->in_error_pkt = save_in_error_pkt;
1642 proto_register_vines_icp(void)
1644 static gint *ett[] = {
1648 proto_vines_icp = proto_register_protocol(
1649 "Banyan Vines ICP", "Vines ICP", "vines_icp");
1650 proto_register_subtree_array(ett, array_length(ett));
1654 proto_reg_handoff_vines_icp(void)
1656 dissector_handle_t vines_icp_handle;
1658 vines_icp_handle = create_dissector_handle(dissect_vines_icp,
1660 dissector_add("vines_ip.protocol", VIP_PROTO_ICP, vines_icp_handle);