Coverage Report

Created: 2026-09-28 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-vines.c
Line
Count
Source
1
/* packet-vines.c
2
 * Routines for Banyan VINES protocol packet disassembly
3
 *
4
 * Don Lafontaine <lafont02@cn.ca>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 * Joerg Mayer (see AUTHORS file)
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
14
/* Information about VINES can be found in
15
 *
16
 * VINES Protocol Definition
17
 * Order Number: DA254-00
18
 * Banyan Systems incorporated
19
 * February 1990
20
 * Part Number: 092093-000
21
 *
22
 * Banyan Systems are no longer in business, so that document cannot be
23
 * ordered from them.  An online copy appears to be available at
24
 *
25
 *  http://banyan-vines.bamertal.com/Banyan-supplier-help/ProtoDef/ProtoDefMain.htm
26
 *
27
 * along with the VINES Architecture Definition at
28
 *
29
 *  http://banyan-vines.bamertal.com/Banyan-supplier-help/ArchDef/ArchDefMain.htm
30
 *
31
 * and other VINES documentation linked to from
32
 *
33
 *  http://banyan-vines.bamertal.com/Banyan-supplier-help/banyan.htm
34
 *
35
 * Some information can also be found in
36
 *
37
 *  http://docwiki.cisco.com/wiki/Banyan_VINES
38
 *
39
 * and at
40
 *
41
 *  http://www.banalyzer.de/ban/HTML/P_VINES/Eng/P_vines.html
42
 *
43
 * The document at
44
 *
45
 *  http://www.watersprings.org/pub/id/draft-ietf-rmonmib-rmonprot-v2-00.txt
46
 *
47
 * lists a bunch of values of protocol identifier fields for various
48
 * protocols.  It speaks of the Vines Fragmentation Protocol,
49
 * the "Vines Token Ring Protocol" which appears to be the same as the
50
 * "Vines LLC" protocol here, the Vines echo protocol, Vines IP, and
51
 * protocols running atop Vines IP.
52
 *
53
 * The LLC values it describes are:
54
 *
55
 *  0xbc  (SAP_VINES2) Vines Token Ring a/k/a Vines LLC
56
 *
57
 * It doesn't mention 0xba (SAP_VINES1).
58
 *
59
 * The Vines Token Ring/Vines LLC protocol identifier values it
60
 * describes are:
61
 *
62
 *  0xba  Vines IP
63
 *  0xbb  Vines Echo
64
 *
65
 * The Ethernet type values it describes are:
66
 *
67
 *  0x0bad  (ETHERTYPE_VINES) Vines IP
68
 *  0x0baf  Vines Echo
69
 */
70
71
#include "config.h"
72
73
#include <epan/packet.h>
74
#include <epan/capture_dissectors.h>
75
#include <epan/etypes.h>
76
#include <epan/to_str.h>
77
#include <epan/tfs.h>
78
#include <epan/iana-info.h>
79
#include <wsutil/array.h>
80
#include "packet-ppp.h"
81
#include "packet-llc.h"
82
#include "packet-arcnet.h"
83
84
85
void proto_register_vines_frp(void);
86
void proto_reg_handoff_vines_frp(void);
87
void proto_register_vines_llc(void);
88
void proto_reg_handoff_vines_llc(void);
89
void proto_register_vines_ip(void);
90
void proto_reg_handoff_vines_ip(void);
91
void proto_register_vines_echo(void);
92
void proto_reg_handoff_vines_echo(void);
93
void proto_register_vines_ipc(void);
94
void proto_reg_handoff_vines_ipc(void);
95
void proto_register_vines_spp(void);
96
void proto_reg_handoff_vines_spp(void);
97
void proto_register_vines_arp(void);
98
void proto_reg_handoff_vines_arp(void);
99
void proto_register_vines_rtp(void);
100
void proto_reg_handoff_vines_rtp(void);
101
void proto_register_vines_icp(void);
102
void proto_reg_handoff_vines_icp(void);
103
104
105
16
#define UDP_PORT_VINES  573
106
107
static int proto_vines_frp;
108
static int hf_vines_frp_flags;
109
static int hf_vines_frp_flags_first_fragment;
110
static int hf_vines_frp_flags_last_fragment;
111
static int hf_vines_frp_sequence_number;
112
113
static int ett_vines_frp;
114
static int ett_vines_frp_flags;
115
116
static dissector_handle_t vines_frp_handle, vines_frp_new_handle;
117
118
static int proto_vines_llc;
119
static int hf_vines_llc_packet_type;
120
121
static int ett_vines_llc;
122
123
static dissector_handle_t vines_llc_handle;
124
125
static int proto_vines_ip;
126
static int hf_vines_ip_protocol;
127
static int hf_vines_ip_checksum;
128
static int hf_vines_ip_length;
129
static int hf_vines_ip_source;
130
static int hf_vines_ip_destination;
131
static int hf_vines_tctl;
132
static int hf_vines_tctl_node;
133
static int hf_vines_tctl_class;
134
static int hf_vines_tctl_forward_router;
135
static int hf_vines_tctl_metric;
136
static int hf_vines_tctl_notif_packet;
137
static int hf_vines_tctl_hop_count;
138
139
static int ett_vines_ip;
140
static int ett_vines_ip_tctl;
141
142
static dissector_handle_t vines_ip_handle;
143
144
static int proto_vines_echo;
145
146
static int hf_vines_echo_data;
147
148
static int ett_vines_echo;
149
150
static dissector_handle_t vines_echo_handle;
151
152
static int proto_vines_ipc;
153
static int hf_vines_ipc_src_port;
154
static int hf_vines_ipc_dest_port;
155
static int hf_vines_ipc_packet_type;
156
static int hf_vines_ipc_control;
157
static int hf_vines_ipc_control_ack;
158
static int hf_vines_ipc_control_end_msg;
159
static int hf_vines_ipc_control_beg_msg;
160
static int hf_vines_ipc_control_abort_msg;
161
static int hf_vines_ipc_local_connection_id;
162
static int hf_vines_ipc_sequence_number;
163
static int hf_vines_ipc_length;
164
static int hf_vines_ipc_remote_connection_id;
165
static int hf_vines_ipc_ack_number;
166
static int hf_vines_ipc_error;
167
168
static int ett_vines_ipc;
169
static int ett_vines_ipc_control;
170
171
static dissector_handle_t vines_ipc_handle;
172
173
static int proto_vines_spp;
174
static int hf_vines_spp_src_port;
175
static int hf_vines_spp_dest_port;
176
static int hf_vines_spp_packet_type;
177
static int hf_vines_spp_control;
178
static int hf_vines_spp_control_ack;
179
static int hf_vines_spp_control_end_msg;
180
static int hf_vines_spp_control_beg_msg;
181
static int hf_vines_spp_control_abort_msg;
182
static int hf_vines_spp_local_id;
183
static int hf_vines_spp_remote_id;
184
static int hf_vines_spp_seq_num;
185
static int hf_vines_spp_ack_num;
186
static int hf_vines_spp_window;
187
188
static int ett_vines_spp;
189
static int ett_vines_spp_control;
190
191
static dissector_handle_t vines_spp_handle;
192
193
static int proto_vines_arp;
194
static int hf_vines_arp_address;
195
static int hf_vines_arp_version;
196
static int hf_vines_arp_packet_type;
197
static int hf_vines_arp_interface_metric;
198
static int hf_vines_arp_sequence_number;
199
200
static int ett_vines_arp;
201
202
static dissector_handle_t vines_arp_handle;
203
204
static int proto_vines_rtp;
205
static int hf_vines_rtp_comp_flag;
206
static int hf_vines_rtp_comp_flag_neighbor_router;
207
static int hf_vines_rtp_comp_flag_sequence_rtp;
208
static int hf_vines_rtp_comp_flag_sequence_rtp_version;
209
static int hf_vines_rtp_control;
210
static int hf_vines_rtp_control_sync_broadcast;
211
static int hf_vines_rtp_control_topology_update;
212
static int hf_vines_rtp_control_specific_request;
213
static int hf_vines_rtp_control_end_msg;
214
static int hf_vines_rtp_control_beg_msg;
215
static int hf_vines_rtp_machine_rtp;
216
static int hf_vines_rtp_machine_tcpip;
217
static int hf_vines_rtp_machine_bus;
218
static int hf_vines_rtp_flag_sequence_rtp;
219
static int hf_vines_rtp_flag_network_p2p;
220
static int hf_vines_rtp_flag_data_link_p2p;
221
static int hf_vines_rtp_flag_broadcast_medium;
222
static int hf_vines_rtp_metric_to_preferred_gateway;
223
static int hf_vines_rtp_requested_info;
224
static int hf_vines_rtp_metric_to_destination;
225
static int hf_vines_rtp_source_route_length;
226
static int hf_vines_rtp_router_sequence_number;
227
static int hf_vines_rtp_sequence_number;
228
static int hf_vines_rtp_data_offset;
229
static int hf_vines_rtp_preferred_gateway_sequence_number;
230
static int hf_vines_rtp_preferred_gateway_node_type;
231
static int hf_vines_rtp_metric;
232
static int hf_vines_rtp_destination_sequence_number;
233
static int hf_vines_rtp_link_address_length;
234
static int hf_vines_rtp_controller_type;
235
static int hf_vines_rtp_destination_node_type;
236
static int hf_vines_rtp_information_type;
237
static int hf_vines_rtp_version;
238
static int hf_vines_rtp_preferred_gateway;
239
static int hf_vines_rtp_neighbor_metric;
240
static int hf_vines_rtp_destination;
241
static int hf_vines_rtp_node_type;
242
static int hf_vines_rtp_operation_type;
243
static int hf_vines_rtp_packet_id;
244
static int hf_vines_rtp_network_number;
245
static int hf_vines_rtp_machine_type;
246
static int hf_vines_rtp_destination_controller_type;
247
static int hf_vines_rtp_destination_machine;
248
static int hf_vines_rtp_pref_gateway_controller_type;
249
static int hf_vines_rtp_pref_gateway_machine;
250
static int hf_vines_rtp_network_flags;
251
static int hf_vines_rtp_destination_flags;
252
static int hf_vines_rtp_preferred_gateway_flags;
253
static int hf_vines_rtp_preferred_gateway_data_link_address_ether;
254
static int hf_vines_rtp_preferred_gateway_data_link_address_bytes;
255
static int hf_vines_rtp_preferred_gateway_source_route;
256
257
static int ett_vines_rtp;
258
static int ett_vines_rtp_compatibility_flags;
259
static int ett_vines_rtp_req_info;
260
static int ett_vines_rtp_control_flags;
261
static int ett_vines_rtp_mtype;
262
static int ett_vines_rtp_flags;
263
264
static dissector_handle_t vines_rtp_handle;
265
266
static int proto_vines;
267
static int proto_vines_icp;
268
static int hf_vines_icp_exception_code;
269
static int hf_vines_icp_metric;
270
static int hf_vines_icp_packet_type;
271
272
static int ett_vines_icp;
273
274
static dissector_handle_t vines_icp_handle;
275
static capture_dissector_handle_t vines_echo_cap_handle;
276
static capture_dissector_handle_t vines_ip_cap_handle;
277
278
/* VINES IP structs and definitions */
279
280
enum {
281
  VIP_PROTO_IPC = 1,   /* Interprocess Communications Protocol (IPC) */
282
  VIP_PROTO_SPP = 2,  /* Sequenced Packet Protocol (SPP) */
283
  VIP_PROTO_ARP = 4,  /* Address Resolution Protocol (ARP) */
284
  VIP_PROTO_RTP = 5,  /* Routing Update Protocol (RTP) / SRTP (Sequenced RTP) */
285
  VIP_PROTO_ICP = 6 /* Internet Control Protocol (ICP) */
286
};
287
288
/* VINES SPP and IPC structs and definitions */
289
290
enum {
291
  PKTTYPE_DGRAM = 0,  /* Unreliable datagram */
292
  PKTTYPE_DATA = 1, /* User Data */
293
  PKTTYPE_ERR = 2,  /* Error */
294
  PKTTYPE_DISC = 3, /* Disconnect Request */
295
  PKTTYPE_PROBE = 4,  /* Probe (retransmit) */
296
  PKTTYPE_ACK = 5 /* Acknowledgement */
297
};
298
299
typedef struct _e_vspp {
300
  uint16_t vspp_sport;
301
  uint16_t vspp_dport;
302
  uint8_t vspp_pkttype;
303
  uint8_t vspp_control;
304
  uint16_t vspp_lclid;  /* Local Connection ID */
305
  uint16_t vspp_rmtid;  /* Remote Connection ID */
306
  uint16_t vspp_seqno;  /* Sequence Number */
307
  uint16_t vspp_ack;  /* Acknowledgement Number */
308
  uint16_t vspp_win;
309
} e_vspp;
310
311
typedef struct _e_vipc {
312
  uint16_t vipc_sport;
313
  uint16_t vipc_dport;
314
  uint8_t vipc_pkttype;
315
  uint8_t vipc_control;
316
  uint16_t vipc_lclid;  /* Local Connection ID */
317
  uint16_t vipc_rmtid;  /* Remote Connection ID */
318
  uint16_t vipc_seqno;  /* Sequence Number */
319
  uint16_t vipc_ack;  /* Acknowledgement Number */
320
  uint16_t vipc_err_len;
321
} e_vipc;
322
323
static bool
324
capture_vines(const unsigned char *pd _U_, int offset _U_, int len _U_, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_)
325
0
{
326
0
  capture_dissector_increment_count(cpinfo, proto_vines);
327
0
  return true;
328
0
}
329
330
/* Control flags */
331
16
#define VINES_FRP_FIRST_FRAGMENT  0x01
332
16
#define VINES_FRP_LAST_FRAGMENT   0x02
333
334
/* AFAIK Vines FRP (Fragmentation Protocol) is used on all media except
335
 * Ethernet and TR (and probably FDDI) - Fragmentation on these media types
336
 * is not possible
337
 * FIXME: Do we need to use this header with PPP too?
338
 */
339
static int
340
dissect_vines_frp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
341
56
{
342
56
  proto_tree *vines_frp_tree;
343
56
  proto_item *ti;
344
56
  proto_tree *flags_tree;
345
56
  tvbuff_t *next_tvb;
346
347
56
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines FRP");
348
56
  col_clear(pinfo->cinfo, COL_INFO);
349
350
56
  if (tree) {
351
56
    ti = proto_tree_add_item(tree, proto_vines_frp, tvb, 0, 2, ENC_NA);
352
56
    vines_frp_tree = proto_item_add_subtree(ti, ett_vines_frp);
353
354
56
    ti = proto_tree_add_item(vines_frp_tree, hf_vines_frp_flags, tvb, 0, 1, ENC_NA);
355
56
    flags_tree = proto_item_add_subtree(ti, ett_vines_frp_flags);
356
56
    proto_tree_add_item(flags_tree, hf_vines_frp_flags_first_fragment, tvb, 0, 1, ENC_NA);
357
56
    proto_tree_add_item(flags_tree, hf_vines_frp_flags_last_fragment, tvb, 0, 1, ENC_NA);
358
359
56
    proto_tree_add_item(vines_frp_tree, hf_vines_frp_sequence_number, tvb, 1, 1, ENC_LITTLE_ENDIAN);
360
56
  }
361
362
  /* Decode the "real" Vines now */
363
56
  next_tvb = tvb_new_subset_remaining(tvb, 2);
364
56
  call_dissector(vines_ip_handle, next_tvb, pinfo, tree);
365
56
  return tvb_captured_length(tvb);
366
56
}
367
368
static int
369
dissect_vines_frp_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
370
          void *params _U_)
371
5
{
372
5
  if (pinfo->srcport != pinfo->destport) {
373
    /* Require that the source and destination ports be the
374
     * port for Vines FRP. */
375
5
    return 0;
376
5
  }
377
0
  if (!tvb_bytes_exist(tvb, 0, 1)) {
378
    /* Too short to check the flags value. */
379
0
    return 0;
380
0
  }
381
382
0
  if ((tvb_get_uint8(tvb, 0) & ~(VINES_FRP_FIRST_FRAGMENT|VINES_FRP_LAST_FRAGMENT)) != 0) {
383
    /* Those are the only flags; if anything else is set, this
384
     * is presumably not Vines FRP. */
385
0
    return 0;
386
0
  }
387
0
  dissect_vines_frp(tvb, pinfo, tree, params);
388
0
  return tvb_captured_length(tvb);
389
0
}
390
391
void
392
proto_register_vines_frp(void)
393
16
{
394
16
  static hf_register_info hf[] = {
395
16
    { &hf_vines_frp_flags,
396
16
      { "Control Flags", "vines_frp.flags",
397
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
398
16
        NULL, HFILL }},
399
400
16
    { &hf_vines_frp_flags_first_fragment,
401
16
      { "First fragment", "vines_frp.flags.first_fragment",
402
16
        FT_BOOLEAN, 8, NULL, VINES_FRP_FIRST_FRAGMENT,
403
16
        NULL, HFILL }},
404
405
16
    { &hf_vines_frp_flags_last_fragment,
406
16
      { "Last fragment", "vines_frp.flags.last_fragment",
407
16
        FT_BOOLEAN, 8, NULL, VINES_FRP_LAST_FRAGMENT,
408
16
        NULL, HFILL }},
409
410
16
    { &hf_vines_frp_sequence_number,
411
16
      { "Sequence Number", "vines_frp.sequence_number",
412
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
413
16
        NULL, HFILL }},
414
16
  };
415
16
  static int *ett[] = {
416
16
    &ett_vines_frp,
417
16
    &ett_vines_frp_flags
418
16
  };
419
420
16
  proto_vines_frp = proto_register_protocol("Banyan Vines Fragmentation Protocol", "Vines FRP", "vines_frp");
421
16
  proto_register_field_array(proto_vines_frp, hf, array_length(hf));
422
16
  proto_register_subtree_array(ett, array_length(ett));
423
16
  vines_frp_handle = register_dissector("vines_frp", dissect_vines_frp, proto_vines_frp);
424
16
  vines_frp_new_handle = register_dissector("vines_frp.udp", dissect_vines_frp_new, proto_vines_frp);
425
16
}
426
427
void
428
proto_reg_handoff_vines_frp(void)
429
16
{
430
16
  dissector_add_uint("ip.proto", IP_PROTO_VINES, vines_frp_handle);
431
16
  dissector_add_uint_with_preference("udp.port", UDP_PORT_VINES, vines_frp_new_handle);
432
16
}
433
434
static dissector_table_t vines_llc_dissector_table;
435
436
16
#define VINES_LLC_IP  0xba
437
16
#define VINES_LLC_ECHO  0xbb
438
439
static const value_string vines_llc_ptype_vals[] = {
440
  { VINES_LLC_IP,   "Vines IP" },
441
  { VINES_LLC_ECHO, "Vines Echo" },
442
  { 0,              NULL }
443
};
444
445
static int
446
dissect_vines_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
447
6
{
448
6
  uint32_t  ptype;
449
6
  proto_tree *vines_llc_tree;
450
6
  proto_item *ti;
451
6
  tvbuff_t *next_tvb;
452
453
6
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines LLC");
454
6
  col_clear(pinfo->cinfo, COL_INFO);
455
456
6
  ti = proto_tree_add_item(tree, proto_vines_llc, tvb, 0, 1, ENC_NA);
457
6
  vines_llc_tree = proto_item_add_subtree(ti, ett_vines_llc);
458
459
6
  proto_tree_add_item_ret_uint(vines_llc_tree, hf_vines_llc_packet_type, tvb, 0, 1, ENC_NA, &ptype);
460
6
  col_add_str(pinfo->cinfo, COL_INFO,
461
6
    val_to_str(pinfo->pool, ptype, vines_llc_ptype_vals,
462
6
      "Unknown protocol 0x%02x"));
463
464
6
  next_tvb = tvb_new_subset_remaining(tvb, 1);
465
6
  if (!dissector_try_uint(vines_llc_dissector_table, ptype,
466
6
      next_tvb, pinfo, tree))
467
6
    call_data_dissector(next_tvb, pinfo, tree);
468
469
6
  return tvb_captured_length(tvb);
470
6
}
471
472
void
473
proto_register_vines_llc(void)
474
16
{
475
16
  static hf_register_info hf[] = {
476
16
    { &hf_vines_llc_packet_type,
477
16
      { "Packet Type", "vines_llc.packet_type",
478
16
        FT_UINT8, BASE_HEX, VALS(vines_llc_ptype_vals), 0x0,
479
16
        NULL, HFILL }},
480
16
  };
481
482
16
  static int *ett[] = {
483
16
    &ett_vines_llc,
484
16
  };
485
486
16
  proto_vines_llc = proto_register_protocol("Banyan Vines LLC", "Vines LLC", "vines_llc");
487
16
  proto_register_field_array(proto_vines_llc, hf, array_length(hf));
488
16
  proto_register_subtree_array(ett, array_length(ett));
489
16
  vines_llc_handle = register_dissector("vines_llc", dissect_vines_llc, proto_vines_llc);
490
491
  /* subdissector code */
492
16
  vines_llc_dissector_table = register_dissector_table("vines_llc.ptype",
493
16
      "Vines LLC protocol", proto_vines_llc, FT_UINT8, BASE_HEX);
494
16
}
495
496
void
497
proto_reg_handoff_vines_llc(void)
498
16
{
499
16
  dissector_add_uint("llc.dsap", SAP_VINES2, vines_llc_handle);
500
16
}
501
502
static dissector_table_t vines_ip_dissector_table;
503
504
static const value_string class_vals[] = {
505
  { 0x00, "Regardless of cost" },
506
  { 0x10, "Without cost" },
507
  { 0x20, "With low cost (>= 4800 bps)" },
508
  { 0x30, "Via LAN" },
509
  { 0,    NULL }
510
};
511
512
static const value_string proto_vals[] = {
513
  { VIP_PROTO_IPC, "IPC" },
514
  { VIP_PROTO_SPP, "SPP" },
515
  { VIP_PROTO_ARP, "ARP" },
516
  { VIP_PROTO_RTP, "RTP" },
517
  { VIP_PROTO_ICP, "ICP" },
518
  { 0,             NULL }
519
};
520
521
static const uint8_t bcast_addr[VINES_ADDR_LEN] = {
522
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
523
};
524
525
static const true_false_string tfs_vine_tctl_router_all = { "Router nodes", "All nodes" };
526
static const true_false_string tfs_vine_tctl_forward_router = { "Can handle redirect packets", "Cannot handle redirect packets" };
527
static const true_false_string tfs_vine_tctl_return_not_return = { "Return", "Do not return" };
528
529
static int
530
dissect_vines_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
531
327
{
532
327
  int         offset = 0;
533
327
  uint16_t vip_pktlen;
534
327
  uint8_t vip_tctl; /* Transport Control */
535
327
  uint8_t vip_proto;
536
327
  proto_tree *vip_tree, *tctl_tree;
537
327
  proto_item *ti;
538
327
  bool is_broadcast = false;
539
327
  tvbuff_t *next_tvb;
540
541
327
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines IP");
542
327
  col_clear(pinfo->cinfo, COL_INFO);
543
544
  /* To do: check for runts, errs, etc. */
545
546
  /* capture the necessary parts of the header */
547
327
  vip_pktlen = tvb_get_ntohs(tvb, offset+2);
548
327
  vip_tctl = tvb_get_uint8(tvb, offset+3);
549
327
  vip_proto = tvb_get_uint8(tvb, offset+4);
550
551
327
  col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%02x)",
552
327
      val_to_str_const(vip_tctl, proto_vals, "Unknown VIP protocol"),
553
327
      vip_tctl);
554
555
327
  set_address_tvb(&pinfo->net_src, AT_VINES, VINES_ADDR_LEN, tvb, offset+12);
556
327
  copy_address_shallow(&pinfo->src, &pinfo->net_src);
557
327
  set_address_tvb(&pinfo->net_dst, AT_VINES, VINES_ADDR_LEN, tvb, offset+6);
558
327
  copy_address_shallow(&pinfo->dst, &pinfo->net_dst);
559
560
  /* helpers to transport control */
561
327
  if (tvb_memeql(tvb, offset+6, bcast_addr, VINES_ADDR_LEN) == 0)
562
10
    is_broadcast = true;
563
564
  /*
565
   * Adjust the length of this tvbuff to include only the Vines IP
566
   * datagram.
567
   */
568
327
  set_actual_length(tvb, vip_pktlen < 18 ? 18 : vip_pktlen);
569
570
327
  if (tree) {
571
208
    ti = proto_tree_add_item(tree, proto_vines_ip, tvb, offset, vip_pktlen, ENC_NA);
572
208
    vip_tree = proto_item_add_subtree(ti, ett_vines_ip);
573
208
    proto_tree_add_checksum(vip_tree, tvb, offset, hf_vines_ip_checksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
574
208
    offset += 2;
575
576
208
    proto_tree_add_item(vip_tree, hf_vines_ip_length, tvb, offset, 2, ENC_BIG_ENDIAN);
577
208
    offset += 2;
578
579
208
    ti = proto_tree_add_item(vip_tree, hf_vines_tctl, tvb, offset, 1, ENC_BIG_ENDIAN);
580
581
208
    tctl_tree = proto_item_add_subtree(ti, ett_vines_ip_tctl);
582
    /*
583
     * XXX - bit 0x80 is "Normal" if 0; what is it if 1?
584
     */
585
208
    if (is_broadcast) {
586
10
      proto_tree_add_item(tctl_tree, hf_vines_tctl_node, tvb, offset, 1, ENC_NA);
587
10
      proto_tree_add_item(tctl_tree, hf_vines_tctl_class, tvb, offset, 1, ENC_NA);
588
198
    } else {
589
198
      proto_tree_add_item(tctl_tree, hf_vines_tctl_forward_router, tvb, offset, 1, ENC_NA);
590
198
      proto_tree_add_item(tctl_tree, hf_vines_tctl_metric, tvb, offset, 1, ENC_NA);
591
198
      proto_tree_add_item(tctl_tree, hf_vines_tctl_notif_packet, tvb, offset, 1, ENC_NA);
592
198
    }
593
594
208
    proto_tree_add_item(tctl_tree, hf_vines_tctl_hop_count, tvb, offset, 1, ENC_NA);
595
208
    offset += 1;
596
597
208
    proto_tree_add_item(vip_tree, hf_vines_ip_protocol, tvb, offset, 1, ENC_NA);
598
208
    offset += 1;
599
600
208
    proto_tree_add_item(vip_tree, hf_vines_ip_destination, tvb, offset, VINES_ADDR_LEN, ENC_NA);
601
208
    offset += 6;
602
603
208
    proto_tree_add_item(vip_tree, hf_vines_ip_source, tvb, offset, VINES_ADDR_LEN, ENC_NA);
604
208
    offset += 6;
605
208
  } else {
606
119
    offset += 18;
607
119
  }
608
327
  next_tvb = tvb_new_subset_remaining(tvb, offset);
609
327
  if (!dissector_try_uint(vines_ip_dissector_table, vip_proto,
610
327
      next_tvb, pinfo, tree))
611
104
    call_data_dissector(next_tvb, pinfo, tree);
612
613
327
  return tvb_captured_length(tvb);
614
327
}
615
616
void
617
proto_register_vines_ip(void)
618
16
{
619
16
  static int *ett[] = {
620
16
    &ett_vines_ip,
621
16
    &ett_vines_ip_tctl,
622
16
  };
623
624
16
  static hf_register_info hf[] = {
625
16
    { &hf_vines_ip_protocol,
626
16
      { "Protocol", "vines_ip.protocol",
627
16
        FT_UINT8, BASE_HEX, VALS(proto_vals), 0x0,
628
16
        "Vines protocol", HFILL }},
629
630
16
    { &hf_vines_ip_checksum,
631
16
      { "Packet checksum", "vines_ip.checksum",
632
16
        FT_UINT16, BASE_HEX, NULL, 0x0,
633
16
        NULL, HFILL }},
634
635
16
    { &hf_vines_ip_length,
636
16
      { "Packet length", "vines_ip.length",
637
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
638
16
        NULL, HFILL }},
639
640
16
    { &hf_vines_tctl,
641
16
      { "Transport control", "vines_ip.tctl",
642
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
643
16
        NULL, HFILL }},
644
645
16
    { &hf_vines_tctl_node,
646
16
      { "Nodes", "vines_ip.tctl.node",
647
16
        FT_BOOLEAN, 8, TFS(&tfs_vine_tctl_router_all), 0x40,
648
16
        NULL, HFILL }},
649
650
16
    { &hf_vines_tctl_class,
651
16
      { "Reachable", "vines_ip.tctl.class",
652
16
        FT_UINT8, BASE_DEC, VALS(class_vals), 0x30,
653
16
        NULL, HFILL }},
654
655
16
    { &hf_vines_tctl_forward_router,
656
16
      { "Forwarding Router", "vines_ip.tctl.forward_router",
657
16
        FT_BOOLEAN, 8, TFS(&tfs_vine_tctl_forward_router), 0x40,
658
16
        NULL, HFILL }},
659
660
16
    { &hf_vines_tctl_metric,
661
16
      { "Metric notification packet", "vines_ip.tctl.metric",
662
16
        FT_BOOLEAN, 8, TFS(&tfs_vine_tctl_return_not_return), 0x20,
663
16
        NULL, HFILL }},
664
665
16
    { &hf_vines_tctl_notif_packet,
666
16
      { "Exception notification packet", "vines_ip.tctl.notif_packet",
667
16
        FT_BOOLEAN, 8, TFS(&tfs_vine_tctl_return_not_return), 0x10,
668
16
        NULL, HFILL }},
669
670
16
    { &hf_vines_tctl_hop_count,
671
16
      { "Hop count remaining", "vines_ip.tctl.hop_count",
672
16
        FT_UINT8, BASE_DEC, NULL, 0x0F,
673
16
        NULL, HFILL }},
674
675
16
    { &hf_vines_ip_destination,
676
16
       { "Destination", "vines_ip.destination",
677
16
         FT_VINES, BASE_NONE, NULL, 0x0,
678
16
         NULL, HFILL }},
679
680
16
    { &hf_vines_ip_source,
681
16
       { "Source", "vines_ip.source",
682
16
         FT_VINES, BASE_NONE, NULL, 0x0,
683
16
         NULL, HFILL }},
684
16
  };
685
686
16
  proto_vines_ip = proto_register_protocol("Banyan Vines IP", "Vines IP",
687
16
      "vines_ip");
688
16
  proto_register_field_array(proto_vines_ip, hf, array_length(hf));
689
16
  proto_register_subtree_array(ett, array_length(ett));
690
691
  /* subdissector code */
692
16
  vines_ip_dissector_table = register_dissector_table("vines_ip.protocol",
693
16
      "Vines protocol", proto_vines_ip, FT_UINT8, BASE_HEX);
694
695
16
  vines_ip_handle = register_dissector("vines_ip", dissect_vines_ip,
696
16
      proto_vines_ip);
697
16
}
698
699
void
700
proto_reg_handoff_vines_ip(void)
701
16
{
702
16
  dissector_add_uint("ethertype", ETHERTYPE_VINES_IP, vines_ip_handle);
703
16
  dissector_add_uint("ppp.protocol", PPP_VINES, vines_ip_handle);
704
16
  dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_BANYAN,
705
16
      vines_ip_handle);
706
16
  dissector_add_uint("vines_llc.ptype", VINES_LLC_IP, vines_ip_handle);
707
16
}
708
709
static int
710
dissect_vines_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
711
0
{
712
0
  proto_tree *vines_echo_tree = NULL;
713
0
  proto_item *ti;
714
715
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines Echo");
716
0
  col_clear(pinfo->cinfo, COL_INFO);
717
718
0
  if (tree) {
719
0
    ti = proto_tree_add_item(tree, proto_vines_echo, tvb, 0, -1, ENC_NA);
720
0
    vines_echo_tree = proto_item_add_subtree(ti, ett_vines_echo);
721
0
    proto_tree_add_item(vines_echo_tree, hf_vines_echo_data, tvb, 0, -1, ENC_NA);
722
0
  }
723
0
  return tvb_captured_length(tvb);
724
0
}
725
726
void
727
proto_register_vines_echo(void)
728
16
{
729
16
  static hf_register_info hf[] = {
730
16
    { &hf_vines_echo_data,
731
16
      { "Data", "vines_echo.data",
732
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
733
16
        NULL, HFILL }},
734
16
  };
735
736
16
  static int *ett[] = {
737
16
    &ett_vines_echo,
738
16
  };
739
740
16
  proto_vines_echo = proto_register_protocol("Banyan Vines Echo", "Vines Echo", "vines_echo");
741
16
  proto_register_field_array(proto_vines_echo, hf, array_length(hf));
742
16
  proto_register_subtree_array(ett, array_length(ett));
743
16
  vines_echo_handle = register_dissector("vines_echo", dissect_vines_echo,
744
16
      proto_vines_echo);
745
16
}
746
747
void
748
proto_reg_handoff_vines_echo(void)
749
16
{
750
16
  dissector_add_uint("vines_llc.ptype", VINES_LLC_ECHO, vines_echo_handle);
751
16
  dissector_add_uint("ethertype", ETHERTYPE_VINES_ECHO, vines_echo_handle);
752
16
}
753
754
static const value_string pkttype_vals[] = {
755
  { PKTTYPE_DGRAM, "Datagram" },
756
  { PKTTYPE_DATA,  "Data" },
757
  { PKTTYPE_ERR,   "Error" },
758
  { PKTTYPE_DISC,  "Disconnect" },
759
  { PKTTYPE_PROBE, "Probe" },
760
  { PKTTYPE_ACK,   "Ack" },
761
  { 0,             NULL }
762
};
763
764
static heur_dissector_list_t vines_ipc_heur_subdissector_list;
765
766
static const value_string vipc_err_vals[] = {
767
  { 151, "Bad socket descriptor" },
768
  { 152, "Address already in use" },
769
  { 153, "Invalid operation" },
770
  { 154, "User address parameter fault" },
771
  { 155, "Net/host unreachable" },
772
  { 156, "Message overflow error" },
773
  { 157, "Destination socket does not exist" },
774
  { 158, "Address family does not exist" },
775
  { 159, "Socket type does not exist" },
776
  { 160, "Protocol does not exist" },
777
  { 161, "No more sockets available" },
778
  { 162, "No buffer space available" },
779
  { 163, "Timeout event" },
780
  { 164, "Operation not supported" },
781
  { 165, "Resource not available" },
782
  { 166, "Internal communication service failure" },
783
  { 167, "Controller reset failure" },
784
  { 0,   NULL }
785
};
786
787
static const true_false_string tfs_vine_ipc_send_not_send = { "Send", "Do not Send" };
788
static const true_false_string tfs_vine_ipc_abort_not_abort = { "Abort", "Do not abort" };
789
790
static int
791
dissect_vines_ipc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
792
22
{
793
22
  int          offset = 0;
794
22
  e_vipc       viph;
795
22
  proto_tree *vipc_tree = NULL, *control_tree;
796
22
  proto_item *ti;
797
22
  tvbuff_t *next_tvb;
798
22
  heur_dtbl_entry_t *hdtbl_entry;
799
800
22
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "VIPC");
801
22
  col_clear(pinfo->cinfo, COL_INFO);
802
803
  /* To do: check for runts, errs, etc. */
804
805
  /* Avoids alignment problems on many architectures. */
806
22
  tvb_memcpy(tvb, (uint8_t *)&viph, offset, sizeof(e_vipc));
807
808
22
  viph.vipc_sport = g_ntohs(viph.vipc_sport);
809
22
  viph.vipc_dport = g_ntohs(viph.vipc_dport);
810
22
  viph.vipc_lclid = g_ntohs(viph.vipc_lclid);
811
22
  viph.vipc_rmtid = g_ntohs(viph.vipc_rmtid);
812
22
  viph.vipc_seqno = g_ntohs(viph.vipc_seqno);
813
22
  viph.vipc_ack = g_ntohs(viph.vipc_ack);
814
22
  viph.vipc_err_len = g_ntohs(viph.vipc_err_len);
815
816
22
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines IPC");
817
22
  switch (viph.vipc_pkttype) {
818
819
5
  case PKTTYPE_DGRAM:
820
5
    col_add_fstr(pinfo->cinfo, COL_INFO,
821
5
             "%s D=%04x S=%04x",
822
5
             val_to_str(pinfo->pool, viph.vipc_pkttype, pkttype_vals,
823
5
                 "Unknown packet type (0x%02x)"),
824
5
             viph.vipc_dport, viph.vipc_sport);
825
5
    break;
826
827
1
  case PKTTYPE_ERR:
828
1
    col_add_fstr(pinfo->cinfo, COL_INFO,
829
1
             "%s NS=%u NR=%u Err=%s RID=%04x LID=%04x D=%04x S=%04x",
830
1
             val_to_str(pinfo->pool, viph.vipc_pkttype, pkttype_vals,
831
1
                 "Unknown packet type (0x%02x)"),
832
1
             viph.vipc_seqno, viph.vipc_ack,
833
1
             val_to_str(pinfo->pool, viph.vipc_err_len,
834
1
                 vipc_err_vals, "Unknown (%u)"),
835
1
             viph.vipc_rmtid, viph.vipc_lclid,
836
1
             viph.vipc_dport, viph.vipc_sport);
837
1
    break;
838
839
16
  default:
840
16
    col_add_fstr(pinfo->cinfo, COL_INFO,
841
16
             "%s NS=%u NR=%u Len=%u RID=%04x LID=%04x D=%04x S=%04x",
842
16
             val_to_str(pinfo->pool, viph.vipc_pkttype, pkttype_vals,
843
16
                 "Unknown packet type (0x%02x)"),
844
16
             viph.vipc_seqno, viph.vipc_ack,
845
16
             viph.vipc_err_len, viph.vipc_rmtid,
846
16
             viph.vipc_lclid, viph.vipc_dport,
847
16
             viph.vipc_sport);
848
16
    break;
849
22
  }
850
851
22
  ti = proto_tree_add_item(tree, proto_vines_ipc, tvb, offset, sizeof(viph), ENC_NA);
852
22
  vipc_tree = proto_item_add_subtree(ti, ett_vines_ipc);
853
854
22
  proto_tree_add_item(vipc_tree, hf_vines_ipc_src_port, tvb, offset, 2, ENC_BIG_ENDIAN);
855
22
  offset += 2;
856
22
  proto_tree_add_item(vipc_tree, hf_vines_ipc_dest_port, tvb, offset, 2, ENC_BIG_ENDIAN);
857
22
  offset += 2;
858
22
  proto_tree_add_item(vipc_tree, hf_vines_ipc_packet_type, tvb, offset, 1, ENC_BIG_ENDIAN);
859
22
  offset += 1;
860
22
  if (viph.vipc_pkttype != PKTTYPE_DGRAM) {
861
17
    ti = proto_tree_add_item(vipc_tree, hf_vines_ipc_control, tvb, offset, 1, ENC_BIG_ENDIAN);
862
863
17
    control_tree = proto_item_add_subtree(ti, ett_vines_ipc_control);
864
    /*
865
     * XXX - do reassembly based on BOM/EOM bits.
866
     */
867
17
    proto_tree_add_item(control_tree, hf_vines_ipc_control_ack, tvb, offset, 1, ENC_BIG_ENDIAN);
868
17
    proto_tree_add_item(control_tree, hf_vines_ipc_control_end_msg, tvb, offset, 1, ENC_BIG_ENDIAN);
869
17
    proto_tree_add_item(control_tree, hf_vines_ipc_control_beg_msg, tvb, offset, 1, ENC_BIG_ENDIAN);
870
17
    proto_tree_add_item(control_tree, hf_vines_ipc_control_abort_msg, tvb, offset, 1, ENC_BIG_ENDIAN);
871
17
  }
872
22
  offset += 1;
873
22
  if (viph.vipc_pkttype != PKTTYPE_DGRAM) {
874
17
    proto_tree_add_item(vipc_tree, hf_vines_ipc_local_connection_id, tvb, offset, 2, ENC_BIG_ENDIAN);
875
17
    offset += 2;
876
17
    proto_tree_add_item(vipc_tree, hf_vines_ipc_remote_connection_id, tvb, offset, 2, ENC_BIG_ENDIAN);
877
17
    offset += 2;
878
17
    proto_tree_add_item(vipc_tree, hf_vines_ipc_sequence_number, tvb, offset, 2, ENC_BIG_ENDIAN);
879
17
    offset += 2;
880
17
    proto_tree_add_item(vipc_tree, hf_vines_ipc_ack_number, tvb, offset, 2, ENC_BIG_ENDIAN);
881
17
    offset += 2;
882
17
    if (viph.vipc_pkttype == PKTTYPE_ERR) {
883
1
      proto_tree_add_item(vipc_tree, hf_vines_ipc_error, tvb, offset, 2, ENC_BIG_ENDIAN);
884
16
    } else {
885
16
      proto_tree_add_item(vipc_tree, hf_vines_ipc_length, tvb, offset, 2, ENC_BIG_ENDIAN);
886
16
    }
887
17
    offset += 2;
888
17
  }
889
890
  /*
891
   * For data packets, try the heuristic dissectors for Vines SPP;
892
   * if none of them accept the packet, or if it's not a data packet,
893
   * dissect it as data.
894
   */
895
22
  next_tvb = tvb_new_subset_remaining(tvb, offset);
896
22
  if (viph.vipc_pkttype != PKTTYPE_DATA ||
897
9
      !dissector_try_heuristic(vines_ipc_heur_subdissector_list,
898
9
        next_tvb, pinfo, tree, &hdtbl_entry, NULL))
899
22
    call_data_dissector(next_tvb, pinfo, tree);
900
901
22
  return tvb_captured_length(tvb);
902
22
}
903
904
void
905
proto_register_vines_ipc(void)
906
16
{
907
16
  static hf_register_info hf[] = {
908
16
    { &hf_vines_ipc_src_port,
909
16
      { "Source port", "vines_ipc.src_port",
910
16
        FT_UINT16, BASE_HEX, NULL, 0x0,
911
16
        NULL, HFILL }},
912
913
16
    { &hf_vines_ipc_dest_port,
914
16
      { "Destination port", "vines_ipc.dest_port",
915
16
        FT_UINT16, BASE_HEX, NULL, 0x0,
916
16
        NULL, HFILL }},
917
918
16
    { &hf_vines_ipc_packet_type,
919
16
      { "Packet type", "vines_ipc.packet_type",
920
16
        FT_UINT8, BASE_HEX, VALS(pkttype_vals), 0x0,
921
16
        NULL, HFILL }},
922
923
16
    { &hf_vines_ipc_control,
924
16
      { "Control", "vines_ipc.control",
925
16
        FT_UINT8, BASE_HEX, VALS(pkttype_vals), 0x0,
926
16
        NULL, HFILL }},
927
928
16
    { &hf_vines_ipc_control_ack,
929
16
      { "Immediate acknowledgment", "vines_ipc.control.ack",
930
16
        FT_BOOLEAN, 8, TFS(&tfs_vine_ipc_send_not_send), 0x80,
931
16
        NULL, HFILL }},
932
933
16
    { &hf_vines_ipc_control_end_msg,
934
16
      { "End of message", "vines_ipc.control.end_msg",
935
16
        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
936
16
        NULL, HFILL }},
937
938
16
    { &hf_vines_ipc_control_beg_msg,
939
16
      { "Beginning of message", "vines_ipc.control.beg_msg",
940
16
        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
941
16
        NULL, HFILL }},
942
943
16
    { &hf_vines_ipc_control_abort_msg,
944
16
      { "Current message", "vines_ipc.control.abort_msg",
945
16
        FT_BOOLEAN, 8, TFS(&tfs_vine_ipc_abort_not_abort), 0x10,
946
16
        NULL, HFILL }},
947
948
16
    { &hf_vines_ipc_local_connection_id,
949
16
      { "Local Connection ID", "vines_ipc.local_connection_id",
950
16
        FT_UINT16, BASE_HEX, NULL, 0x0,
951
16
        NULL, HFILL }},
952
953
16
    { &hf_vines_ipc_remote_connection_id,
954
16
      { "Remote Connection ID", "vines_ipc.remote_connection_id",
955
16
        FT_UINT16, BASE_HEX, NULL, 0x0,
956
16
        NULL, HFILL }},
957
958
16
    { &hf_vines_ipc_sequence_number,
959
16
      { "Sequence number", "vines_ipc.sequence_number",
960
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
961
16
        NULL, HFILL }},
962
963
16
    { &hf_vines_ipc_ack_number,
964
16
      { "Ack number", "vines_ipc.ack_number",
965
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
966
16
        NULL, HFILL }},
967
968
16
    { &hf_vines_ipc_error,
969
16
      { "Error", "vines_ipc.error",
970
16
        FT_UINT16, BASE_DEC, VALS(vipc_err_vals), 0x0,
971
16
        NULL, HFILL }},
972
973
16
    { &hf_vines_ipc_length,
974
16
      { "Length", "vines_ipc.length",
975
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
976
16
        NULL, HFILL }},
977
16
  };
978
979
16
  static int *ett[] = {
980
16
    &ett_vines_ipc,
981
16
    &ett_vines_ipc_control,
982
16
  };
983
984
16
  proto_vines_ipc = proto_register_protocol("Banyan Vines IPC",
985
16
      "Vines IPC", "vines_ipc");
986
16
  proto_register_field_array(proto_vines_ipc, hf, array_length(hf));
987
16
  proto_register_subtree_array(ett, array_length(ett));
988
16
  vines_ipc_handle = register_dissector("vines_ipc", dissect_vines_ipc,
989
16
      proto_vines_ipc);
990
991
16
  vines_ipc_heur_subdissector_list = register_heur_dissector_list_with_description("vines_ipc", "Vines IPC Data payload", proto_vines_ipc);
992
16
}
993
994
void
995
proto_reg_handoff_vines_ipc(void)
996
16
{
997
16
  dissector_add_uint("vines_ip.protocol", VIP_PROTO_IPC, vines_ipc_handle);
998
16
}
999
1000
static heur_dissector_list_t vines_spp_heur_subdissector_list;
1001
1002
static int
1003
dissect_vines_spp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1004
16
{
1005
16
  int          offset = 0;
1006
16
  e_vspp       viph;
1007
16
  proto_tree  *vspp_tree, *control_tree;
1008
16
  proto_item  *ti;
1009
16
  tvbuff_t    *next_tvb;
1010
16
  heur_dtbl_entry_t *hdtbl_entry;
1011
1012
16
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSPP");
1013
16
  col_clear(pinfo->cinfo, COL_INFO);
1014
1015
  /* To do: check for runts, errs, etc. */
1016
1017
  /* Avoids alignment problems on many architectures. */
1018
16
  tvb_memcpy(tvb, (uint8_t *)&viph, offset, sizeof(e_vspp));
1019
1020
16
  viph.vspp_sport = g_ntohs(viph.vspp_sport);
1021
16
  viph.vspp_dport = g_ntohs(viph.vspp_dport);
1022
16
  viph.vspp_lclid = g_ntohs(viph.vspp_lclid);
1023
16
  viph.vspp_rmtid = g_ntohs(viph.vspp_rmtid);
1024
16
  viph.vspp_seqno = g_ntohs(viph.vspp_seqno);
1025
16
  viph.vspp_ack = g_ntohs(viph.vspp_ack);
1026
16
  viph.vspp_win = g_ntohs(viph.vspp_win);
1027
1028
16
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines SPP");
1029
16
  col_add_fstr(pinfo->cinfo, COL_INFO,
1030
16
           "%s NS=%u NR=%u Window=%u RID=%04x LID=%04x D=%04x S=%04x",
1031
16
           val_to_str(pinfo->pool, viph.vspp_pkttype, pkttype_vals,
1032
16
               "Unknown packet type (0x%02x)"),
1033
16
           viph.vspp_seqno, viph.vspp_ack, viph.vspp_win,
1034
16
           viph.vspp_rmtid, viph.vspp_lclid, viph.vspp_dport,
1035
16
           viph.vspp_sport);
1036
1037
16
  if (tree) {
1038
15
    ti = proto_tree_add_item(tree, proto_vines_spp, tvb, offset, sizeof(viph), ENC_NA);
1039
15
    vspp_tree = proto_item_add_subtree(ti, ett_vines_spp);
1040
15
    proto_tree_add_item(vspp_tree, hf_vines_spp_src_port, tvb, offset, 2, ENC_BIG_ENDIAN);
1041
15
    proto_tree_add_item(vspp_tree, hf_vines_spp_dest_port, tvb, offset+2, 2, ENC_BIG_ENDIAN);
1042
15
    proto_tree_add_item(vspp_tree, hf_vines_spp_packet_type, tvb, offset+4, 1, ENC_BIG_ENDIAN);
1043
1044
15
    ti = proto_tree_add_item(vspp_tree, hf_vines_spp_control, tvb, offset+5, 1, ENC_BIG_ENDIAN);
1045
15
    control_tree = proto_item_add_subtree(ti, ett_vines_spp_control);
1046
    /*
1047
     * XXX - do reassembly based on BOM/EOM bits.
1048
     */
1049
15
    proto_tree_add_item(control_tree, hf_vines_spp_control_ack, tvb, offset+5, 1, ENC_BIG_ENDIAN);
1050
15
    proto_tree_add_item(control_tree, hf_vines_spp_control_end_msg, tvb, offset+5, 1, ENC_BIG_ENDIAN);
1051
15
    proto_tree_add_item(control_tree, hf_vines_spp_control_beg_msg, tvb, offset+5, 1, ENC_BIG_ENDIAN);
1052
15
    proto_tree_add_item(control_tree, hf_vines_spp_control_abort_msg, tvb, offset+5, 1, ENC_BIG_ENDIAN);
1053
15
    proto_tree_add_item(vspp_tree, hf_vines_spp_local_id, tvb, offset+6, 2, ENC_BIG_ENDIAN);
1054
15
    proto_tree_add_item(vspp_tree, hf_vines_spp_remote_id, tvb, offset+8, 2, ENC_BIG_ENDIAN);
1055
15
    proto_tree_add_item(vspp_tree, hf_vines_spp_seq_num, tvb, offset+10, 2, ENC_BIG_ENDIAN);
1056
15
    proto_tree_add_item(vspp_tree, hf_vines_spp_ack_num, tvb, offset+12, 2, ENC_BIG_ENDIAN);
1057
15
    proto_tree_add_item(vspp_tree, hf_vines_spp_window, tvb, offset+14, 2, ENC_BIG_ENDIAN);
1058
15
  } else {
1059
1
    offset += 16; /* sizeof SPP */
1060
1
  }
1061
  /*
1062
   * For data packets, try the heuristic dissectors for Vines SPP;
1063
   * if none of them accept the packet, or if it's not a data packet,
1064
   * dissect it as data.
1065
   */
1066
16
  next_tvb = tvb_new_subset_remaining(tvb, offset);
1067
16
  if (viph.vspp_pkttype != PKTTYPE_DATA ||
1068
6
      !dissector_try_heuristic(vines_spp_heur_subdissector_list,
1069
6
        next_tvb, pinfo, tree, &hdtbl_entry, NULL))
1070
15
    call_data_dissector(next_tvb, pinfo, tree);
1071
1072
16
  return tvb_captured_length(tvb);
1073
16
}
1074
1075
void
1076
proto_register_vines_spp(void)
1077
16
{
1078
16
  static hf_register_info hf[] = {
1079
16
    { &hf_vines_spp_src_port,
1080
16
      { "Source port", "vines_spp.src_port",
1081
16
        FT_UINT16, BASE_HEX, NULL, 0x0,
1082
16
        NULL, HFILL }},
1083
1084
16
    { &hf_vines_spp_dest_port,
1085
16
      { "Destination port", "vines_spp.dest_port",
1086
16
        FT_UINT16, BASE_HEX, NULL, 0x0,
1087
16
        NULL, HFILL }},
1088
1089
16
    { &hf_vines_spp_packet_type,
1090
16
      { "Packet type", "vines_spp.packet_type",
1091
16
        FT_UINT8, BASE_HEX, VALS(pkttype_vals), 0x0,
1092
16
        NULL, HFILL }},
1093
1094
16
    { &hf_vines_spp_control,
1095
16
      { "Control", "vines_spp.control",
1096
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1097
16
        NULL, HFILL }},
1098
1099
16
    { &hf_vines_spp_control_ack,
1100
16
      { "Immediate acknowledgment", "vines_spp.control.ack",
1101
16
        FT_BOOLEAN, 8, TFS(&tfs_vine_ipc_send_not_send), 0x80,
1102
16
        NULL, HFILL }},
1103
1104
16
    { &hf_vines_spp_control_end_msg,
1105
16
      { "End of message", "vines_spp.control.end_msg",
1106
16
        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40,
1107
16
        NULL, HFILL }},
1108
1109
16
    { &hf_vines_spp_control_beg_msg,
1110
16
      { "Beginning of message", "vines_spp.control.beg_msg",
1111
16
        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x20,
1112
16
        NULL, HFILL }},
1113
1114
16
    { &hf_vines_spp_control_abort_msg,
1115
16
      { "Current message", "vines_spp.control.abort_msg",
1116
16
        FT_BOOLEAN, 8, TFS(&tfs_vine_ipc_abort_not_abort), 0x10,
1117
16
        NULL, HFILL }},
1118
1119
16
    { &hf_vines_spp_local_id,
1120
16
      { "Local Connection ID", "vines_spp.local_id",
1121
16
        FT_UINT16, BASE_HEX, NULL, 0x0,
1122
16
        NULL, HFILL }},
1123
1124
16
    { &hf_vines_spp_remote_id,
1125
16
      { "Remote Connection ID", "vines_spp.remote_id",
1126
16
        FT_UINT16, BASE_HEX, NULL, 0x0,
1127
16
        NULL, HFILL }},
1128
1129
16
    { &hf_vines_spp_seq_num,
1130
16
      { "Sequence number", "vines_spp.seq_num",
1131
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1132
16
        NULL, HFILL }},
1133
1134
16
    { &hf_vines_spp_ack_num,
1135
16
      { "Ack number", "vines_spp.ack_num",
1136
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1137
16
        NULL, HFILL }},
1138
1139
16
    { &hf_vines_spp_window,
1140
16
      { "Window", "vines_spp.window",
1141
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1142
16
        NULL, HFILL }}
1143
16
  };
1144
1145
16
  static int *ett[] = {
1146
16
    &ett_vines_spp,
1147
16
    &ett_vines_spp_control,
1148
16
  };
1149
1150
16
  proto_vines_spp = proto_register_protocol("Banyan Vines SPP",
1151
16
      "Vines SPP", "vines_spp");
1152
16
  proto_register_field_array(proto_vines_spp, hf, array_length(hf));
1153
16
  proto_register_subtree_array(ett, array_length(ett));
1154
16
  vines_spp_handle = register_dissector("vines_spp", dissect_vines_spp,
1155
16
      proto_vines_spp);
1156
1157
16
  vines_spp_heur_subdissector_list = register_heur_dissector_list_with_description("vines_spp", "Vines SPP Data payload", proto_vines_spp);
1158
16
}
1159
1160
void
1161
proto_reg_handoff_vines_spp(void)
1162
16
{
1163
16
  dissector_add_uint("vines_ip.protocol", VIP_PROTO_SPP, vines_spp_handle);
1164
16
}
1165
1166
#define VINES_VERS_PRE_5_5  0x00
1167
5
#define VINES_VERS_5_5    0x01
1168
1169
static const value_string vines_version_vals[] = {
1170
  { VINES_VERS_PRE_5_5, "Pre-5.50" },
1171
  { VINES_VERS_5_5,     "5.50" },
1172
  { 0,                  NULL }
1173
};
1174
1175
#define VARP_QUERY_REQ    0x00
1176
#define VARP_SERVICE_RESP 0x01
1177
#define VARP_ASSIGNMENT_REQ 0x02
1178
5
#define VARP_ASSIGNMENT_RESP  0x03
1179
1180
static const value_string vines_arp_packet_type_vals[] = {
1181
  { VARP_QUERY_REQ,       "Query request" },
1182
  { VARP_SERVICE_RESP,    "Service response" },
1183
  { VARP_ASSIGNMENT_REQ,  "Assignment request" },
1184
  { VARP_ASSIGNMENT_RESP, "Assignment response" },
1185
  { 0,                    NULL }
1186
};
1187
1188
static int
1189
dissect_vines_arp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1190
5
{
1191
5
  proto_tree *vines_arp_tree;
1192
5
  proto_item *ti;
1193
5
  uint8_t  version;
1194
5
  uint16_t packet_type;
1195
5
  uint16_t metric;
1196
1197
5
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines ARP");
1198
5
  col_clear(pinfo->cinfo, COL_INFO);
1199
1200
5
  ti = proto_tree_add_item(tree, proto_vines_arp, tvb, 0, -1, ENC_NA);
1201
5
  vines_arp_tree = proto_item_add_subtree(ti, ett_vines_arp);
1202
1203
5
  proto_tree_add_item_ret_uint8(vines_arp_tree, hf_vines_arp_version, tvb, 0, 1, ENC_NA, &version);
1204
1205
5
  if (version == VINES_VERS_5_5) {
1206
    /*
1207
     * Sequenced ARP.
1208
     */
1209
2
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines SARP");
1210
2
    packet_type = tvb_get_uint8(tvb, 1);
1211
2
    col_add_str(pinfo->cinfo, COL_INFO,
1212
2
          val_to_str(pinfo->pool, packet_type, vines_arp_packet_type_vals,
1213
2
            "Unknown (0x%02x)"));
1214
1215
2
    proto_tree_add_item(vines_arp_tree, hf_vines_arp_packet_type, tvb, 1, 1, ENC_BIG_ENDIAN);
1216
1217
2
    if (packet_type == VARP_ASSIGNMENT_RESP) {
1218
1
      col_append_fstr(pinfo->cinfo, COL_INFO,
1219
1
              ", Address = %s",
1220
1
              tvb_address_to_str(pinfo->pool, tvb, AT_VINES, 2));
1221
1
      proto_tree_add_item(vines_arp_tree, hf_vines_arp_address, tvb, 2, VINES_ADDR_LEN, ENC_NA);
1222
1
    }
1223
2
    proto_tree_add_item(vines_arp_tree, hf_vines_arp_sequence_number, tvb, 2+VINES_ADDR_LEN, 4, ENC_BIG_ENDIAN);
1224
2
    metric = tvb_get_ntohs(tvb, 2+VINES_ADDR_LEN+4);
1225
2
    proto_tree_add_uint_format_value(vines_arp_tree, hf_vines_arp_interface_metric, tvb,
1226
2
              2+VINES_ADDR_LEN+4, 2, metric,
1227
2
              "%u ticks (%g seconds)",
1228
2
              metric, metric*.2);
1229
3
  } else {
1230
    /*
1231
     * Non-sequenced ARP.
1232
     */
1233
3
    packet_type = (uint8_t) tvb_get_ntohs(tvb, 0);
1234
3
    col_add_str(pinfo->cinfo, COL_INFO,
1235
3
          val_to_str(pinfo->pool, packet_type, vines_arp_packet_type_vals,
1236
3
            "Unknown (0x%02x)"));
1237
3
    proto_tree_add_item(vines_arp_tree, hf_vines_arp_packet_type, tvb, 0, 2, ENC_BIG_ENDIAN);
1238
1239
3
    if (packet_type == VARP_ASSIGNMENT_RESP) {
1240
0
      col_append_fstr(pinfo->cinfo, COL_INFO,
1241
0
              ", Address = %s",
1242
0
              tvb_address_to_str(pinfo->pool, tvb, AT_VINES, 2));
1243
1244
0
      proto_tree_add_item(vines_arp_tree, hf_vines_arp_address, tvb, 2, VINES_ADDR_LEN, ENC_NA);
1245
0
    }
1246
3
  }
1247
5
  return tvb_captured_length(tvb);
1248
5
}
1249
1250
void
1251
proto_register_vines_arp(void)
1252
16
{
1253
16
  static hf_register_info hf[] = {
1254
16
    { &hf_vines_arp_version,
1255
16
      { "Version", "vines_arp.version",
1256
16
        FT_UINT8, BASE_HEX, VALS(vines_version_vals), 0x0,
1257
16
        NULL, HFILL }},
1258
1259
16
    { &hf_vines_arp_packet_type,
1260
16
      { "Packet Type", "vines_arp.packet_type",
1261
16
        FT_UINT16, BASE_HEX, VALS(vines_arp_packet_type_vals), 0x0,
1262
16
        NULL, HFILL }},
1263
1264
16
    { &hf_vines_arp_address,
1265
16
      { "Address", "vines_arp.address",
1266
16
        FT_VINES, BASE_NONE, NULL, 0x0,
1267
16
        NULL, HFILL }},
1268
1269
16
    { &hf_vines_arp_sequence_number,
1270
16
      { "Sequence Number", "vines_arp.sequence_number",
1271
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1272
16
        NULL, HFILL }},
1273
1274
16
    { &hf_vines_arp_interface_metric,
1275
16
      { "Interface Metric", "vines_arp.interface_metric",
1276
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1277
16
        NULL, HFILL }},
1278
16
  };
1279
1280
16
  static int *ett[] = {
1281
16
    &ett_vines_arp,
1282
16
  };
1283
1284
16
  proto_vines_arp = proto_register_protocol("Banyan Vines ARP", "Vines ARP", "vines_arp");
1285
16
  proto_register_field_array(proto_vines_arp, hf, array_length(hf));
1286
16
  proto_register_subtree_array(ett, array_length(ett));
1287
16
  vines_arp_handle = register_dissector("vines_arp", dissect_vines_arp,
1288
16
      proto_vines_arp);
1289
16
}
1290
1291
void
1292
proto_reg_handoff_vines_arp(void)
1293
16
{
1294
16
  dissector_add_uint("vines_ip.protocol", VIP_PROTO_ARP, vines_arp_handle);
1295
16
}
1296
1297
1
#define VRTP_OP_REQUEST   0x01
1298
10
#define VRTP_OP_UPDATE_RESPONSE 0x02
1299
2
#define VRTP_OP_REDIRECT  0x03
1300
0
#define VRTP_OP_REINITIALIZE  0x04
1301
4
#define VRTP_OP_REDIRECT2 0x06
1302
1303
static const value_string vines_rtp_operation_type_vals[] = {
1304
  { VRTP_OP_REQUEST,         "Request" },
1305
  { VRTP_OP_UPDATE_RESPONSE, "Update/response" },
1306
  { VRTP_OP_REDIRECT,        "Redirect" },
1307
  { VRTP_OP_REINITIALIZE,    "Reinitialize" },
1308
  { VRTP_OP_REDIRECT2,       "Redirect" },
1309
  { 0,                       NULL }
1310
};
1311
1312
static const value_string vines_rtp_node_type_vals[] = {
1313
  { 0x01, "Host" },
1314
  { 0x02, "Router" },
1315
  { 0,    NULL }
1316
};
1317
1318
static const value_string vines_rtp_controller_type_vals[] = {
1319
  { 0x00, "Default Card" },
1320
  { 0x01, "Multibuffer" },
1321
  { 0,    NULL }
1322
};
1323
1324
static const value_string vines_rtp_info_type_vals[] = {
1325
  { 0x00, "Update" },
1326
  { 0x01, "Update" },
1327
  { 0x02, "Response" },
1328
  { 0,    NULL }
1329
};
1330
1331
static const true_false_string tfs_vine_auto_config_not_auto_config = { "Auto-configured", "Not an auto-configured" };
1332
static const true_false_string tfs_vine_rtp_not_all_neighbor_all_neighbor = { "Not all neighbor routers support", "All neighbor routers support" };
1333
static const true_false_string tfs_vine_rtp_sequenced_not_sequenced = { "Sequenced", "Not Sequenced" };
1334
static const true_false_string tfs_part_not_part = { "Part of", "Not part of" };
1335
static const true_false_string tfs_fast_bus_slow_bus = { "Fast bus", "Slow bus" };
1336
1337
static void
1338
rtp_show_machine_type(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_machine)
1339
22
{
1340
22
  proto_item *ti;
1341
22
  proto_tree *subtree;
1342
1343
22
  ti = proto_tree_add_item(tree, hf_machine, tvb, offset, 1, ENC_NA);
1344
22
  subtree = proto_item_add_subtree(ti, ett_vines_rtp_mtype);
1345
22
  proto_tree_add_item(subtree, hf_vines_rtp_machine_rtp,
1346
22
            tvb, offset, 1, ENC_BIG_ENDIAN);
1347
22
  proto_tree_add_item(subtree, hf_vines_rtp_machine_tcpip,
1348
22
            tvb, offset, 1, ENC_BIG_ENDIAN);
1349
22
  proto_tree_add_item(subtree, hf_vines_rtp_machine_bus,
1350
22
            tvb, offset, 1, ENC_BIG_ENDIAN);
1351
22
}
1352
1353
static void
1354
rtp_show_flags(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_flag)
1355
60
{
1356
60
  proto_item *ti;
1357
60
  proto_tree *flags_tree;
1358
1359
60
  ti = proto_tree_add_item(tree, hf_flag, tvb, offset, 1, ENC_NA);
1360
60
  flags_tree = proto_item_add_subtree(ti, ett_vines_rtp_flags);
1361
60
  proto_tree_add_item(flags_tree, hf_vines_rtp_flag_sequence_rtp,
1362
60
            tvb, offset, 1, ENC_BIG_ENDIAN);
1363
60
  proto_tree_add_item(flags_tree, hf_vines_rtp_flag_network_p2p,
1364
60
            tvb, offset, 1, ENC_BIG_ENDIAN);
1365
60
  proto_tree_add_item(flags_tree, hf_vines_rtp_flag_data_link_p2p,
1366
60
            tvb, offset, 1, ENC_BIG_ENDIAN);
1367
60
  proto_tree_add_item(flags_tree, hf_vines_rtp_flag_broadcast_medium,
1368
60
            tvb, offset, 1, ENC_BIG_ENDIAN);
1369
60
}
1370
1371
static int
1372
srtp_show_machine_info(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_vines,
1373
            int hf_metric, int hf_nodetype, int hf_controller_type, int hf_machine)
1374
8
{
1375
8
  uint16_t metric;
1376
1377
8
  proto_tree_add_item(tree, hf_vines, tvb, offset, VINES_ADDR_LEN, ENC_NA);
1378
8
  offset += VINES_ADDR_LEN;
1379
8
  metric = tvb_get_ntohs(tvb, offset);
1380
8
  proto_tree_add_uint_format_value(tree, hf_metric, tvb,
1381
8
                offset, 2, metric,
1382
8
                "%u ticks (%g seconds)",
1383
8
                metric, metric*.2);
1384
8
  offset += 2;
1385
8
  proto_tree_add_item(tree, hf_nodetype, tvb, offset, 1, ENC_NA);
1386
8
  offset += 1;
1387
8
  rtp_show_machine_type(tree, tvb, offset, hf_machine);
1388
8
  offset += 1;
1389
8
  proto_tree_add_item(tree, hf_controller_type, tvb, offset, 1, ENC_NA);
1390
8
  offset += 1;
1391
8
  return offset;
1392
8
}
1393
1394
static int
1395
rtp_show_gateway_info(proto_tree *tree, tvbuff_t *tvb, int offset,
1396
          uint8_t link_addr_length, uint8_t source_route_length)
1397
2
{
1398
2
  if (link_addr_length != 0) {
1399
2
    proto_tree_add_item(
1400
2
      tree,
1401
2
      link_addr_length == 6 ? hf_vines_rtp_preferred_gateway_data_link_address_ether : hf_vines_rtp_preferred_gateway_data_link_address_bytes,
1402
2
      tvb, offset, link_addr_length, ENC_NA);
1403
2
    offset += link_addr_length;
1404
2
  }
1405
2
  if (source_route_length != 0) {
1406
1
    proto_tree_add_item(tree, hf_vines_rtp_preferred_gateway_source_route, tvb, offset, source_route_length, ENC_NA);
1407
1
    offset += source_route_length;
1408
1
  }
1409
2
  return offset;
1410
2
}
1411
1412
static int
1413
dissect_vines_rtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1414
31
{
1415
31
  unsigned offset = 0;
1416
31
  proto_tree *vines_rtp_tree = NULL;
1417
31
  proto_item *ti;
1418
31
  proto_tree *subtree;
1419
31
  uint8_t  operation_type;
1420
31
  uint8_t  link_addr_length;
1421
31
  uint8_t  source_route_length;
1422
31
  uint16_t metric;
1423
1424
31
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines RTP");
1425
31
  col_clear(pinfo->cinfo, COL_INFO);
1426
1427
31
  ti = proto_tree_add_item(tree, proto_vines_rtp, tvb, 0, -1, ENC_NA);
1428
31
  vines_rtp_tree = proto_item_add_subtree(ti, ett_vines_rtp);
1429
1430
31
  if (tvb_get_uint8(tvb, 0) != 0) {
1431
    /*
1432
     * Non-sequenced RTP.
1433
     */
1434
17
    operation_type = tvb_get_uint8(tvb, offset);
1435
17
    col_add_str(pinfo->cinfo, COL_INFO,
1436
17
          val_to_str(pinfo->pool, operation_type, vines_rtp_operation_type_vals,
1437
17
            "Unknown (0x%02x)"));
1438
1439
17
    if (tree) {
1440
17
      proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_operation_type, tvb, offset, 1, ENC_NA);
1441
17
      offset += 1;
1442
17
      proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_node_type, tvb, offset, 1, ENC_NA);
1443
17
      offset += 1;
1444
17
      proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_controller_type, tvb, offset, 1, ENC_NA);
1445
17
      offset += 1;
1446
17
      rtp_show_machine_type(vines_rtp_tree, tvb, offset, hf_vines_rtp_machine_type);
1447
17
      offset += 1;
1448
17
      switch (operation_type) {
1449
1450
2
      case VRTP_OP_REDIRECT:
1451
4
      case VRTP_OP_REDIRECT2:
1452
4
        proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_version, tvb, offset, 2, ENC_BIG_ENDIAN);
1453
4
        offset += 2;
1454
4
        proto_tree_add_item_ret_uint8(vines_rtp_tree, hf_vines_rtp_link_address_length, tvb, offset, 1, ENC_NA, &link_addr_length);
1455
4
        offset += 1;
1456
4
        proto_tree_add_item_ret_uint8(vines_rtp_tree, hf_vines_rtp_source_route_length, tvb, offset, 1, ENC_NA, &source_route_length);
1457
4
        offset += 1;
1458
4
        offset = srtp_show_machine_info(vines_rtp_tree, tvb, offset, hf_vines_rtp_destination,
1459
4
              hf_vines_rtp_metric_to_destination, hf_vines_rtp_destination_node_type,
1460
4
              hf_vines_rtp_destination_controller_type, hf_vines_rtp_destination_machine);
1461
4
        offset += 1;
1462
4
        offset = srtp_show_machine_info(vines_rtp_tree, tvb, offset, hf_vines_rtp_preferred_gateway,
1463
4
              hf_vines_rtp_metric_to_preferred_gateway, hf_vines_rtp_preferred_gateway_node_type,
1464
4
              hf_vines_rtp_pref_gateway_controller_type, hf_vines_rtp_pref_gateway_machine);
1465
4
        offset += 1;
1466
4
        rtp_show_gateway_info(vines_rtp_tree, tvb,offset, link_addr_length, source_route_length);
1467
4
        break;
1468
1469
12
      default:
1470
229
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
1471
217
          proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_network_number, tvb, offset, 4, ENC_BIG_ENDIAN);
1472
217
          offset += 4;
1473
217
          metric = tvb_get_ntohs(tvb, offset);
1474
217
          proto_tree_add_uint_format_value(vines_rtp_tree, hf_vines_rtp_neighbor_metric, tvb,
1475
217
                offset, 2, metric,
1476
217
                "%u ticks (%g seconds)",
1477
217
                metric,
1478
217
                metric*.2);
1479
217
          offset += 2;
1480
217
        }
1481
12
        break;
1482
17
      }
1483
17
    }
1484
17
  } else {
1485
14
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines SRTP");
1486
14
    proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_version, tvb, offset, 2, ENC_BIG_ENDIAN);
1487
14
    offset += 2;
1488
14
    operation_type = tvb_get_uint8(tvb, offset);
1489
14
    col_add_str(pinfo->cinfo, COL_INFO,
1490
14
          val_to_str(pinfo->pool, operation_type, vines_rtp_operation_type_vals,
1491
14
            "Unknown (0x%02x)"));
1492
1493
14
    if (tree) {
1494
13
      proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_operation_type, tvb, offset, 1, ENC_NA);
1495
13
      offset += 1;
1496
13
      proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_node_type, tvb, offset, 1, ENC_NA);
1497
13
      offset += 1;
1498
13
      ti = proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_comp_flag,
1499
13
          tvb, offset, 1, ENC_BIG_ENDIAN);
1500
13
      subtree = proto_item_add_subtree(ti, ett_vines_rtp_compatibility_flags);
1501
1502
13
      proto_tree_add_item(subtree, hf_vines_rtp_comp_flag_neighbor_router, tvb, offset, 1, ENC_BIG_ENDIAN);
1503
13
      proto_tree_add_item(subtree, hf_vines_rtp_comp_flag_sequence_rtp, tvb, offset, 1, ENC_BIG_ENDIAN);
1504
13
      proto_tree_add_item(subtree, hf_vines_rtp_comp_flag_sequence_rtp_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1505
13
      offset += 1;
1506
13
      offset += 1;  /* reserved */
1507
13
      switch (operation_type) {
1508
1509
1
      case VRTP_OP_REQUEST:
1510
1
        proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_requested_info, tvb, offset, 1, ENC_NA);
1511
1
        break;
1512
1513
10
      case VRTP_OP_UPDATE_RESPONSE:
1514
10
        proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_information_type, tvb, offset, 1, ENC_NA);
1515
10
        offset += 1;
1516
10
        ti = proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_control, tvb, offset, 1, ENC_BIG_ENDIAN);
1517
10
        subtree = proto_item_add_subtree(ti, ett_vines_rtp_control_flags);
1518
10
        proto_tree_add_item(subtree, hf_vines_rtp_control_sync_broadcast, tvb, offset, 1, ENC_BIG_ENDIAN);
1519
10
        proto_tree_add_item(subtree, hf_vines_rtp_control_topology_update, tvb, offset, 1, ENC_BIG_ENDIAN);
1520
10
        proto_tree_add_item(subtree, hf_vines_rtp_control_specific_request, tvb, offset, 1, ENC_BIG_ENDIAN);
1521
        /* XXX - need reassembly? */
1522
10
        proto_tree_add_item(subtree, hf_vines_rtp_control_end_msg, tvb, offset, 1, ENC_BIG_ENDIAN);
1523
10
        proto_tree_add_item(subtree, hf_vines_rtp_control_beg_msg, tvb, offset, 1, ENC_BIG_ENDIAN);
1524
10
        offset += 1;
1525
10
        proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_packet_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1526
10
        offset += 2;
1527
10
        proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_data_offset, tvb, offset, 2, ENC_BIG_ENDIAN);
1528
10
        offset += 2;
1529
10
        proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_router_sequence_number, tvb, offset, 4, ENC_BIG_ENDIAN);
1530
10
        offset += 4;
1531
10
        metric = tvb_get_ntohs(tvb, offset);
1532
10
        proto_tree_add_uint_format_value(vines_rtp_tree, hf_vines_rtp_metric, tvb,
1533
10
              offset, 2, metric,
1534
10
              "%u ticks (%g seconds)",
1535
10
              metric, metric*.2);
1536
10
        offset += 2;
1537
77
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
1538
67
          proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_network_number, tvb, offset, 4, ENC_BIG_ENDIAN);
1539
67
          offset += 4;
1540
67
          metric = tvb_get_ntohs(tvb, offset);
1541
67
          if (metric == 0xffff) {
1542
20
            proto_tree_add_uint_format_value(vines_rtp_tree, hf_vines_rtp_neighbor_metric, tvb,
1543
20
                  offset, 2, 0xffff, "Unreachable");
1544
47
          } else {
1545
47
            proto_tree_add_uint_format_value(vines_rtp_tree, hf_vines_rtp_neighbor_metric, tvb,
1546
47
                  offset, 2, metric,
1547
47
                  "%u ticks (%g seconds)",
1548
47
                  metric, metric*.2);
1549
47
          }
1550
67
          offset += 2;
1551
67
          proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_sequence_number, tvb, offset, 4, ENC_BIG_ENDIAN);
1552
67
          offset += 4;
1553
67
          rtp_show_flags(vines_rtp_tree, tvb, offset, hf_vines_rtp_network_flags);
1554
67
          offset += 1;
1555
67
          offset += 1;  /* reserved */
1556
67
        }
1557
10
        break;
1558
1559
0
      case VRTP_OP_REDIRECT:
1560
0
        proto_tree_add_item_ret_uint8(vines_rtp_tree, hf_vines_rtp_link_address_length, tvb, offset, 1, ENC_NA, &link_addr_length);
1561
0
        offset += 1;
1562
0
        proto_tree_add_item_ret_uint8(vines_rtp_tree, hf_vines_rtp_source_route_length, tvb, offset, 1, ENC_NA, &source_route_length);
1563
0
        offset += 1;
1564
0
        proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_destination, tvb, offset, VINES_ADDR_LEN, ENC_NA);
1565
0
        offset += VINES_ADDR_LEN;
1566
0
        metric = tvb_get_ntohs(tvb, offset);
1567
0
        proto_tree_add_uint_format_value(vines_rtp_tree, hf_vines_rtp_metric_to_destination, tvb,
1568
0
                offset, 2, metric,
1569
0
                "%u ticks (%g seconds)",
1570
0
                metric, metric*.2);
1571
0
        offset += 2;
1572
0
        proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_destination_node_type, tvb, offset, 1, ENC_NA);
1573
0
        offset += 1;
1574
0
        rtp_show_flags(vines_rtp_tree, tvb, offset, hf_vines_rtp_destination_flags);
1575
0
        offset += 1;
1576
0
        proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_destination_sequence_number, tvb, ENC_BIG_ENDIAN, 4, ENC_BIG_ENDIAN);
1577
0
        offset += 4;
1578
0
        proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_preferred_gateway, tvb, offset, VINES_ADDR_LEN, ENC_NA);
1579
0
        offset += VINES_ADDR_LEN;
1580
0
        metric = tvb_get_ntohs(tvb, offset);
1581
0
        proto_tree_add_uint_format_value(vines_rtp_tree, hf_vines_rtp_metric_to_preferred_gateway, tvb,
1582
0
                offset, 2, metric,
1583
0
                "%u ticks (%g seconds)",
1584
0
                metric, metric*.2);
1585
0
        offset += 2;
1586
0
        proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_preferred_gateway_node_type, tvb, offset, 1, ENC_NA);
1587
0
        offset += 1;
1588
0
        rtp_show_flags(vines_rtp_tree, tvb, offset, hf_vines_rtp_preferred_gateway_flags);
1589
0
        offset += 1;
1590
0
        proto_tree_add_item(vines_rtp_tree, hf_vines_rtp_preferred_gateway_sequence_number, tvb, offset, 4, ENC_BIG_ENDIAN);
1591
0
        offset += 4;
1592
0
        rtp_show_gateway_info(vines_rtp_tree, tvb,offset, link_addr_length, source_route_length);
1593
0
        break;
1594
1595
0
      case VRTP_OP_REINITIALIZE:
1596
0
        break;
1597
13
      }
1598
1599
13
    }
1600
14
  }
1601
11
  return tvb_captured_length(tvb);
1602
31
}
1603
1604
void
1605
proto_register_vines_rtp(void)
1606
16
{
1607
16
  static hf_register_info hf[] = {
1608
16
    { &hf_vines_rtp_comp_flag,
1609
16
      { "Compatibility Flags", "vines_rtp.comp_flag",
1610
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1611
16
        NULL, HFILL }},
1612
1613
16
    { &hf_vines_rtp_comp_flag_neighbor_router,
1614
16
      { "non-Vines-reachable neighbor router", "vines_rtp.comp_flag.neighbor_router",
1615
16
        FT_BOOLEAN, 8, TFS(&tfs_vine_auto_config_not_auto_config), 0x04,
1616
16
        NULL, HFILL }},
1617
1618
16
    { &hf_vines_rtp_comp_flag_sequence_rtp,
1619
16
      { "Sequenced RTP", "vines_rtp.comp_flag.sequence_rtp",
1620
16
        FT_BOOLEAN, 8, TFS(&tfs_vine_rtp_not_all_neighbor_all_neighbor), 0x02,
1621
16
              NULL, HFILL }},
1622
1623
16
    { &hf_vines_rtp_comp_flag_sequence_rtp_version,
1624
16
      { "RTP version mismatch", "vines_rtp.comp_flag.rtp_version",
1625
16
        FT_BOOLEAN, 8, TFS(&tfs_vine_rtp_sequenced_not_sequenced), 0x01,
1626
16
        NULL, HFILL }},
1627
1628
16
    { &hf_vines_rtp_control,
1629
16
      { "Control Flags", "vines_rtp.control",
1630
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1631
16
        NULL, HFILL }},
1632
1633
16
    { &hf_vines_rtp_control_sync_broadcast,
1634
16
      { "Routing table synchronization broadcast", "vines_rtp.control.sync_broadcast",
1635
16
        FT_BOOLEAN, 8, TFS(&tfs_part_not_part), 0x10,
1636
16
        NULL, HFILL }},
1637
1638
16
    { &hf_vines_rtp_control_topology_update,
1639
16
      { "Full topology update", "vines_rtp.control.topology_update",
1640
16
        FT_BOOLEAN, 8, TFS(&tfs_part_not_part), 0x08,
1641
16
        NULL, HFILL }},
1642
1643
16
    { &hf_vines_rtp_control_specific_request,
1644
16
      { "Contains info specifically requested", "vines_rtp.control.specific_request",
1645
16
              FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
1646
16
        NULL, HFILL }},
1647
1648
16
    { &hf_vines_rtp_control_end_msg,
1649
16
      { "End of message", "vines_rtp.control.end_msg",
1650
16
        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
1651
16
        NULL, HFILL }},
1652
1653
16
    { &hf_vines_rtp_control_beg_msg,
1654
16
      { "Beginning of message", "vines_rtp.control.beg_msg",
1655
16
        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
1656
16
        NULL, HFILL }},
1657
1658
16
    { &hf_vines_rtp_machine_rtp,
1659
16
      { "Sequenced RTP", "vines_rtp.machine.rtp",
1660
16
        FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x04,
1661
16
        NULL, HFILL }},
1662
1663
16
    { &hf_vines_rtp_machine_tcpip,
1664
16
      { "TCP/IP", "vines_rtp.machine.tcpip",
1665
16
        FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), 0x02,
1666
16
        NULL, HFILL }},
1667
1668
16
    { &hf_vines_rtp_machine_bus,
1669
16
      { "Bus", "vines_rtp.machine.bus",
1670
16
        FT_BOOLEAN, 8, TFS(&tfs_fast_bus_slow_bus), 0x01,
1671
16
        NULL, HFILL }},
1672
1673
16
    { &hf_vines_rtp_flag_sequence_rtp,
1674
16
      { "Network supports Sequenced RTP", "vines_rtp.flag.sequence_rtp",
1675
16
      FT_BOOLEAN, 8, TFS(&tfs_no_yes), 0x08,
1676
16
        NULL, HFILL }},
1677
1678
16
    { &hf_vines_rtp_flag_network_p2p,
1679
16
      { "Network accessed point-to-point on non-Vines network", "vines_rtp.flag.network_p2p",
1680
16
        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04,
1681
16
        NULL, HFILL }},
1682
1683
16
    { &hf_vines_rtp_flag_data_link_p2p,
1684
16
      { "Data link to network uses point-to-point connection", "vines_rtp.flag.data_link_p2p",
1685
16
        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
1686
16
        NULL, HFILL }},
1687
1688
16
    { &hf_vines_rtp_flag_broadcast_medium,
1689
16
      { "Network accessed across broadcast medium", "vines_rtp.flag.broadcast_medium",
1690
16
        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
1691
16
        NULL, HFILL }},
1692
1693
16
    { &hf_vines_rtp_operation_type,
1694
16
      { "Operation Type", "vines_rtp.operation_type",
1695
16
        FT_UINT8, BASE_HEX, VALS(vines_rtp_operation_type_vals), 0x0,
1696
16
        NULL, HFILL }},
1697
1698
16
    { &hf_vines_rtp_node_type,
1699
16
      { "Node Type", "vines_rtp.node_type",
1700
16
        FT_UINT8, BASE_HEX, VALS(vines_rtp_node_type_vals), 0x0,
1701
16
        NULL, HFILL }},
1702
1703
16
    { &hf_vines_rtp_controller_type,
1704
16
      { "Controller Type", "vines_rtp.controller_type",
1705
16
        FT_UINT8, BASE_HEX, VALS(vines_rtp_controller_type_vals), 0x0,
1706
16
        NULL, HFILL }},
1707
1708
16
    { &hf_vines_rtp_version,
1709
16
      { "Version", "vines_rtp.version",
1710
16
        FT_UINT16, BASE_HEX, NULL, 0x0,
1711
16
        NULL, HFILL }},
1712
1713
16
    { &hf_vines_rtp_link_address_length,
1714
16
      { "Link Address Length", "vines_rtp.link_address_length",
1715
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
1716
16
        NULL, HFILL }},
1717
1718
16
    { &hf_vines_rtp_source_route_length,
1719
16
      { "Source Route Length", "vines_rtp.source_route_length",
1720
16
        FT_UINT8, BASE_DEC, NULL, 0x0,
1721
16
        NULL, HFILL }},
1722
1723
16
    { &hf_vines_rtp_network_number,
1724
16
      { "Network Number", "vines_rtp.network_number",
1725
16
        FT_UINT32, BASE_HEX, NULL, 0x0,
1726
16
        NULL, HFILL }},
1727
1728
16
    { &hf_vines_rtp_neighbor_metric,
1729
16
      { "Neighbor Metric", "vines_rtp.neighbor_metric",
1730
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1731
16
        NULL, HFILL }},
1732
1733
16
    { &hf_vines_rtp_requested_info,
1734
16
      { "Requested Info", "vines_rtp.requested_info",
1735
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1736
16
        NULL, HFILL }},
1737
1738
16
    { &hf_vines_rtp_information_type,
1739
16
      { "Information Type", "vines_rtp.information_type",
1740
16
        FT_UINT8, BASE_HEX, VALS(vines_rtp_info_type_vals), 0x0,
1741
16
        NULL, HFILL }},
1742
1743
16
    { &hf_vines_rtp_packet_id,
1744
16
      { "Packet ID", "vines_rtp.packet_id",
1745
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1746
16
        NULL, HFILL }},
1747
1748
16
    { &hf_vines_rtp_data_offset,
1749
16
      { "Data Offset", "vines_rtp.data_offset",
1750
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1751
16
        NULL, HFILL }},
1752
1753
16
    { &hf_vines_rtp_router_sequence_number,
1754
16
      { "Router Sequence Number", "vines_rtp.router_sequence_number",
1755
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1756
16
        NULL, HFILL }},
1757
1758
16
    { &hf_vines_rtp_metric,
1759
16
      { "Metric", "vines_rtp.metric",
1760
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1761
16
        NULL, HFILL }},
1762
1763
16
    { &hf_vines_rtp_sequence_number,
1764
16
      { "Sequence Number", "vines_rtp.sequence_number",
1765
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1766
16
        NULL, HFILL }},
1767
1768
16
    { &hf_vines_rtp_destination,
1769
16
      { "Destination", "vines_rtp.destination",
1770
16
        FT_VINES, BASE_NONE, NULL, 0x0,
1771
16
        NULL, HFILL }},
1772
1773
16
    { &hf_vines_rtp_metric_to_destination,
1774
16
      { "Metric to Destination", "vines_rtp.metric_to_destination",
1775
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1776
16
        NULL, HFILL }},
1777
1778
16
    { &hf_vines_rtp_destination_node_type,
1779
16
      { "Destination Node Type", "vines_rtp.destination_node_type",
1780
16
        FT_UINT8, BASE_HEX, VALS(vines_rtp_node_type_vals), 0x0,
1781
16
        NULL, HFILL }},
1782
1783
16
    { &hf_vines_rtp_destination_sequence_number,
1784
16
      { "Destination Sequence Number", "vines_rtp.destination_sequence_number",
1785
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1786
16
        NULL, HFILL }},
1787
1788
16
    { &hf_vines_rtp_preferred_gateway,
1789
16
      { "Preferred Gateway", "vines_rtp.preferred_gateway",
1790
16
        FT_VINES, BASE_NONE, NULL, 0x0,
1791
16
        NULL, HFILL }},
1792
1793
16
    { &hf_vines_rtp_metric_to_preferred_gateway,
1794
16
      { "Metric to Preferred Gateway", "vines_rtp.metric_to_preferred_gateway",
1795
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1796
16
        NULL, HFILL }},
1797
1798
16
    { &hf_vines_rtp_preferred_gateway_node_type,
1799
16
      { "Preferred Gateway Node Type", "vines_rtp.preferred_gateway_node_type",
1800
16
        FT_UINT8, BASE_HEX, VALS(vines_rtp_node_type_vals), 0x0,
1801
16
        NULL, HFILL }},
1802
1803
16
    { &hf_vines_rtp_preferred_gateway_sequence_number,
1804
16
      { "Preferred Gateway Sequence Number", "vines_rtp.preferred_gateway_sequence_number",
1805
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1806
16
        NULL, HFILL }},
1807
1808
16
    { &hf_vines_rtp_machine_type,
1809
16
      { "Machine Type", "vines_rtp.machine_type",
1810
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1811
16
        NULL, HFILL }},
1812
1813
16
    { &hf_vines_rtp_destination_machine,
1814
16
      { "Destination Machine Type", "vines_rtp.destination_machine_type",
1815
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1816
16
        NULL, HFILL }},
1817
1818
16
    { &hf_vines_rtp_pref_gateway_machine,
1819
16
      { "Preferred Gateway Machine Type", "vines_rtp.preferred_gateway_machine_type",
1820
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1821
16
        NULL, HFILL }},
1822
1823
16
    { &hf_vines_rtp_destination_controller_type,
1824
16
      { "Destination Controller Type", "vines_rtp.destination_controller_type",
1825
16
        FT_UINT8, BASE_HEX, VALS(vines_rtp_controller_type_vals), 0x0,
1826
16
        NULL, HFILL }},
1827
1828
16
    { &hf_vines_rtp_pref_gateway_controller_type,
1829
16
      { "Preferred Gateway Controller Type", "vines_rtp.preferred_gateway_controller_type",
1830
16
        FT_UINT8, BASE_HEX, VALS(vines_rtp_controller_type_vals), 0x0,
1831
16
        NULL, HFILL }},
1832
1833
16
    { &hf_vines_rtp_network_flags,
1834
16
      { "Network Flags", "vines_rtp.network_flags",
1835
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1836
16
        NULL, HFILL }},
1837
1838
16
    { &hf_vines_rtp_destination_flags,
1839
16
      { "Destination Flags", "vines_rtp.destination_flags",
1840
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1841
16
        NULL, HFILL }},
1842
1843
16
    { &hf_vines_rtp_preferred_gateway_flags,
1844
16
      { "Preferred Gateway Flags", "vines_rtp.preferred_gateway_flags",
1845
16
        FT_UINT8, BASE_HEX, NULL, 0x0,
1846
16
        NULL, HFILL }},
1847
1848
16
    { &hf_vines_rtp_preferred_gateway_data_link_address_ether,
1849
16
      { "Preferred Gateway Data Link Address", "vines_rtp.preferred_gateway_data_link_address",
1850
16
        FT_ETHER, BASE_NONE, NULL, 0x0,
1851
16
        NULL, HFILL }},
1852
1853
16
    { &hf_vines_rtp_preferred_gateway_data_link_address_bytes,
1854
16
      { "Preferred Gateway Data Link Address", "vines_rtp.preferred_gateway_data_link_address",
1855
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
1856
16
        NULL, HFILL }},
1857
1858
16
    { &hf_vines_rtp_preferred_gateway_source_route,
1859
16
      { "Preferred Gateway Source Route", "vines_rtp.preferred_gateway_source_route",
1860
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
1861
16
        NULL, HFILL }},
1862
16
  };
1863
1864
16
  static int *ett[] = {
1865
16
    &ett_vines_rtp,
1866
16
    &ett_vines_rtp_compatibility_flags,
1867
16
    &ett_vines_rtp_req_info,
1868
16
    &ett_vines_rtp_control_flags,
1869
16
    &ett_vines_rtp_mtype,
1870
16
    &ett_vines_rtp_flags,
1871
16
  };
1872
1873
16
  proto_vines_rtp = proto_register_protocol("Banyan Vines RTP", "Vines RTP", "vines_rtp");
1874
16
  proto_register_field_array(proto_vines_rtp, hf, array_length(hf));
1875
16
  proto_register_subtree_array(ett, array_length(ett));
1876
16
  vines_rtp_handle = register_dissector("vines_rtp", dissect_vines_rtp,
1877
16
      proto_vines_rtp);
1878
16
}
1879
1880
void
1881
proto_reg_handoff_vines_rtp(void)
1882
16
{
1883
16
  dissector_add_uint("vines_ip.protocol", VIP_PROTO_RTP, vines_rtp_handle);
1884
16
}
1885
1886
15
#define VICP_EXCEPTION_NOTIFICATION 0x0000
1887
1
#define VICP_METRIC_NOTIFICATION  0x0001
1888
1889
static const value_string vines_icp_packet_type_vals[] = {
1890
  { VICP_EXCEPTION_NOTIFICATION, "Exception notification" },
1891
  { VICP_METRIC_NOTIFICATION,    "Metric notification" },
1892
  { 0,                           NULL }
1893
};
1894
1895
static int
1896
dissect_vines_icp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1897
30
{
1898
30
  unsigned offset = 0;
1899
30
  proto_tree *vines_icp_tree;
1900
30
  proto_item *ti;
1901
30
  uint16_t packet_type;
1902
30
  uint16_t exception_code;
1903
30
  uint16_t metric;
1904
30
  bool save_in_error_pkt;
1905
30
  tvbuff_t *next_tvb;
1906
1907
30
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines ICP");
1908
30
  col_clear(pinfo->cinfo, COL_INFO);
1909
1910
30
  ti = proto_tree_add_item(tree, proto_vines_icp, tvb, 0, -1, ENC_NA);
1911
30
  vines_icp_tree = proto_item_add_subtree(ti, ett_vines_icp);
1912
1913
30
  packet_type = tvb_get_ntohs(tvb, offset);
1914
30
  col_add_str(pinfo->cinfo, COL_INFO,
1915
30
        val_to_str(pinfo->pool, packet_type, vines_icp_packet_type_vals,
1916
30
          "Unknown (0x%02x)"));
1917
1918
30
  proto_tree_add_item(vines_icp_tree, hf_vines_icp_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1919
30
  offset += 2;
1920
1921
30
  switch (packet_type) {
1922
1923
15
  case VICP_EXCEPTION_NOTIFICATION:
1924
15
    exception_code = tvb_get_ntohs(tvb, offset);
1925
15
    col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
1926
15
          val_to_str(pinfo->pool, exception_code, vipc_err_vals,
1927
15
              "Unknown exception code (%u)"));
1928
15
    proto_tree_add_item(vines_icp_tree, hf_vines_icp_exception_code, tvb, offset, 2, ENC_BIG_ENDIAN);
1929
15
    break;
1930
1931
1
  case VICP_METRIC_NOTIFICATION:
1932
1
    metric = tvb_get_ntohs(tvb, offset);
1933
1
    col_append_fstr(pinfo->cinfo, COL_INFO, ", metric %u", metric);
1934
1
    proto_tree_add_item(vines_icp_tree, hf_vines_icp_metric, tvb, offset, 2, ENC_BIG_ENDIAN);
1935
1
    break;
1936
30
  }
1937
29
  offset += 2;
1938
1939
  /*
1940
   * Save the current value of the "we're inside an error packet"
1941
   * flag, and set that flag; subdissectors may treat packets
1942
   * that are the payload of error packets differently from
1943
   * "real" packets.
1944
   */
1945
29
  save_in_error_pkt = pinfo->flags.in_error_pkt;
1946
29
  pinfo->flags.in_error_pkt = true;
1947
1948
  /* Decode the first 40 bytes of the original VIP datagram. */
1949
29
  next_tvb = tvb_new_subset_remaining(tvb, offset);
1950
29
  call_dissector(vines_ip_handle, next_tvb, pinfo, vines_icp_tree);
1951
1952
  /* Restore the "we're inside an error packet" flag. */
1953
29
  pinfo->flags.in_error_pkt = save_in_error_pkt;
1954
29
  return tvb_captured_length(tvb);
1955
30
}
1956
1957
void
1958
proto_register_vines_icp(void)
1959
16
{
1960
16
  static hf_register_info hf[] = {
1961
16
    { &hf_vines_icp_packet_type,
1962
16
      { "Packet Type", "vines_icp.packet_type",
1963
16
        FT_UINT16, BASE_HEX, VALS(vines_icp_packet_type_vals), 0x0,
1964
16
        NULL, HFILL }},
1965
1966
16
    { &hf_vines_icp_exception_code,
1967
16
      { "Exception Code", "vines_icp.exception_code",
1968
16
        FT_UINT16, BASE_DEC, VALS(vipc_err_vals), 0x0,
1969
16
        NULL, HFILL }},
1970
1971
16
    { &hf_vines_icp_metric,
1972
16
      { "Metric", "vines_icp.metric",
1973
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1974
16
        NULL, HFILL }},
1975
16
  };
1976
1977
16
  static int *ett[] = {
1978
16
    &ett_vines_icp,
1979
16
  };
1980
1981
16
  proto_vines_icp = proto_register_protocol("Banyan Vines ICP", "Vines ICP", "vines_icp");
1982
  /* Placeholder for capture statistics */
1983
16
  proto_vines = proto_register_protocol("VINES", "VINES", "vines");
1984
16
  proto_register_field_array(proto_vines_icp, hf, array_length(hf));
1985
16
  proto_register_subtree_array(ett, array_length(ett));
1986
1987
16
  vines_icp_handle = register_dissector("vines_icp", dissect_vines_icp, proto_vines_icp);
1988
16
  vines_ip_cap_handle = register_capture_dissector("vines.ip", capture_vines, proto_vines_ip);
1989
16
  vines_echo_cap_handle = register_capture_dissector("vines.echo", capture_vines, proto_vines_echo);
1990
16
}
1991
1992
void
1993
proto_reg_handoff_vines_icp(void)
1994
16
{
1995
16
  dissector_add_uint("vines_ip.protocol", VIP_PROTO_ICP, vines_icp_handle);
1996
1997
16
  capture_dissector_add_uint("ethertype", ETHERTYPE_VINES_IP, vines_ip_cap_handle);
1998
16
  capture_dissector_add_uint("ethertype", ETHERTYPE_VINES_ECHO, vines_echo_cap_handle);
1999
16
  capture_dissector_add_uint("ppp_hdlc", PPP_VINES, vines_echo_cap_handle);
2000
16
  capture_dissector_add_uint("ip.proto", PPP_VINES, vines_echo_cap_handle);
2001
16
  capture_dissector_add_uint("llc.dsap", SAP_VINES1, vines_echo_cap_handle);
2002
16
  capture_dissector_add_uint("llc.dsap", SAP_VINES2, vines_echo_cap_handle);
2003
16
}
2004
2005
/*
2006
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2007
 *
2008
 * Local variables:
2009
 * c-basic-offset: 8
2010
 * tab-width: 8
2011
 * indent-tabs-mode: t
2012
 * End:
2013
 *
2014
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2015
 * :indentSize=8:tabSize=8:noTabs=false:
2016
 */