2 * Routines for Banyan VINES protocol packet disassembly
4 * $Id: packet-vines.c,v 1.15 2000/04/16 22:46:24 guy Exp $
6 * Don Lafontaine <lafont02@cn.ca>
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@zing.org>
10 * Copyright 1998 Gerald Combs
11 * Joerg Mayer <jmayer@telemation.de>
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #ifdef HAVE_SYS_TYPES_H
32 #include <sys/types.h>
35 #ifdef HAVE_NETINET_IN_H
36 #include <netinet/in.h>
43 #include "packet-vines.h"
44 #include "packet-ip.h"
46 static gint ett_vines = -1;
47 static gint ett_vines_frp = -1;
48 static gint ett_vines_spp = -1;
51 static void dissect_vines_arp(const u_char *, int, frame_data *, proto_tree *);
52 static void dissect_vines_icp(const u_char *, int, frame_data *, proto_tree *);
53 static void dissect_vines_ipc(const u_char *, int, frame_data *, proto_tree *);
54 static void dissect_vines_rtp(const u_char *, int, frame_data *, proto_tree *);
56 static void dissect_vines_spp(const u_char *, int, frame_data *, proto_tree *);
57 static void dissect_vines(const u_char *, int, frame_data *, proto_tree *);
60 capture_vines(const u_char *pd, int offset, packet_counts *ld)
65 /* AFAIK Vines FRP (Fragmentation Protocol) is used on all media except Ethernet
66 * and TR (and probably FDDI) - Fragmentation on these media types is not possible
67 * FIXME: Do we need to use this header with PPP too?
70 dissect_vines_frp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
71 guint8 vines_frp_ctrl, vines_frp_seqno;
72 proto_tree *vines_frp_tree;
74 gchar frp_flags_str[32];
76 /* To do: Check for {cap len,pkt len} < struct len */
77 /* Avoids alignment problems on many architectures. */
78 vines_frp_ctrl = pd[offset];
79 vines_frp_seqno = pd[offset+1];
81 if (check_col(fd, COL_PROTOCOL))
82 col_add_str(fd, COL_PROTOCOL, "Vines FRP");
84 * 1: first fragment of vines packet
85 * 2: last fragment of vines packet
88 switch (vines_frp_ctrl) {
90 strcpy(frp_flags_str, "middle");
93 strcpy(frp_flags_str, "first");
96 strcpy(frp_flags_str, "last");
99 strcpy(frp_flags_str, "only");
102 strcpy(frp_flags_str, "please report: unknown");
107 ti = proto_tree_add_text(tree, offset, 2, "Vines Fragmentation Protocol");
108 vines_frp_tree = proto_item_add_subtree(ti, ett_vines_frp);
109 proto_tree_add_text(vines_frp_tree, offset, 1, "Control Flags: 0x%02x = %s fragment", vines_frp_ctrl, frp_flags_str);
110 proto_tree_add_text(vines_frp_tree, offset + 1, 1, "Sequence Number: 0x%02x", vines_frp_seqno);
113 /* Skip over header */
116 /* Decode the "real" Vines now */
117 dissect_vines(pd, offset, fd, tree);
121 vines_addr_to_str(const guint8 *addrp)
123 static gchar str[3][214];
126 if (cur == &str[0][0]) {
128 } else if (cur == &str[1][0]) {
134 sprintf(cur, "%08x.%04x", pntohl(&addrp[0]), pntohs(&addrp[4]));
139 dissect_vines(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
142 proto_tree *vip_tree;
144 /* gchar tos_str[32]; */
145 int is_broadcast = 0;
148 /* To do: check for runts, errs, etc. */
149 /* Avoids alignment problems on many architectures. */
150 memcpy(&viph, &pd[offset], sizeof(e_vip));
152 viph.vip_chksum = pntohs(&pd[offset]);
153 viph.vip_pktlen = pntohs(&pd[offset+2]);
154 viph.vip_dnet = pntohl(&pd[offset+6]);
155 viph.vip_dsub = pntohs(&pd[offset+10]);
156 viph.vip_snet = pntohl(&pd[offset+12]);
157 viph.vip_ssub = pntohs(&pd[offset+16]);
159 switch (viph.vip_proto) {
161 if (check_col(fd, COL_PROTOCOL))
162 col_add_str(fd, COL_PROTOCOL, "Vines IPC");
163 if (check_col(fd, COL_INFO))
164 col_add_fstr(fd, COL_INFO, "IPC (%02x)", viph.vip_proto);
167 if (check_col(fd, COL_PROTOCOL))
168 col_add_str(fd, COL_PROTOCOL, "Vines SPP");
169 if (check_col(fd, COL_INFO))
170 col_add_fstr(fd, COL_INFO, "SPP (%02x)", viph.vip_proto);
173 if (check_col(fd, COL_PROTOCOL))
174 col_add_str(fd, COL_PROTOCOL, "Vines ARP");
175 if (check_col(fd, COL_INFO))
176 col_add_fstr(fd, COL_INFO, "ARP (%02x)", viph.vip_proto);
179 if (check_col(fd, COL_PROTOCOL))
180 col_add_str(fd, COL_PROTOCOL, "Vines RTP");
181 if (check_col(fd, COL_INFO))
182 col_add_fstr(fd, COL_INFO, "RTP (%02x)", viph.vip_proto);
185 if (check_col(fd, COL_PROTOCOL))
186 col_add_str(fd, COL_PROTOCOL, "Vines ICP");
187 if (check_col(fd, COL_INFO))
188 col_add_fstr(fd, COL_INFO, "ICP (%02x)", viph.vip_proto);
191 if (check_col(fd, COL_PROTOCOL))
192 col_add_str(fd, COL_PROTOCOL, "Vines IP");
193 if (check_col(fd, COL_INFO))
194 col_add_fstr(fd, COL_INFO, "Unknown VIP protocol (%02x)", viph.vip_proto);
197 SET_ADDRESS(&pi.net_src, AT_VINES, 6, &pd[offset+12]);
198 SET_ADDRESS(&pi.src, AT_VINES, 6, &pd[offset+12]);
199 SET_ADDRESS(&pi.net_dst, AT_VINES, 6, &pd[offset+6]);
200 SET_ADDRESS(&pi.dst, AT_VINES, 6, &pd[offset+6]);
202 /* helpers to decode flags */
203 /* FIXME: Not used yet */
204 if ((viph.vip_dnet == 0xffffffff) && (viph.vip_dsub == 0xffff)) {
207 hops = viph.vip_tctl & 0xf;
210 viph.ip_tos = IPTOS_TOS(viph.ip_tos);
214 strcpy(tos_str, "None");
217 strcpy(tos_str, "Minimize delay");
219 case IPTOS_THROUGHPUT:
220 strcpy(tos_str, "Maximize throughput");
222 case IPTOS_RELIABILITY:
223 strcpy(tos_str, "Maximize reliability");
226 strcpy(tos_str, "Minimize cost");
229 strcpy(tos_str, "Unknon. Malformed?");
235 ti = proto_tree_add_text(tree, offset, (viph.vip_pktlen), "Vines IP");
236 vip_tree = proto_item_add_subtree(ti, ett_vines);
237 proto_tree_add_text(vip_tree, offset, 2, "Packet checksum: 0x%04x", viph.vip_chksum);
238 proto_tree_add_text(vip_tree, offset + 2, 2, "Packet length: 0x%04x (%d)", viph.vip_pktlen, viph.vip_pktlen);
239 proto_tree_add_text(vip_tree, offset + 4, 1, "Transport control: 0x%02x",
241 proto_tree_add_text(vip_tree, offset + 5, 1, "Protocol: 0x%02x", viph.vip_proto);
246 switch (viph.vip_proto)
249 dissect_vines_spp(pd, offset, fd, tree);
252 dissect_data(pd, offset, fd, tree);
256 #define VINES_VSPP_DATA 1
257 #define VINES_VSPP_ACK 5
258 void dissect_vines_spp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
261 proto_tree *vspp_tree;
264 /* To do: check for runts, errs, etc. */
265 /* Avoids alignment problems on many architectures. */
266 memcpy(&viph, &pd[offset], sizeof(e_vspp));
268 viph.vspp_sport = ntohs(viph.vspp_sport);
269 viph.vspp_dport = ntohs(viph.vspp_dport);
270 viph.vspp_lclid = ntohs(viph.vspp_lclid);
271 viph.vspp_rmtid = ntohs(viph.vspp_rmtid);
273 switch (viph.vspp_pkttype)
275 case VSPP_PKTTYPE_DATA:
276 if (check_col(fd, COL_PROTOCOL))
277 col_add_str(fd, COL_PROTOCOL, "VSPP Data");
279 case VSPP_PKTTYPE_DISC:
280 if (check_col(fd, COL_PROTOCOL))
281 col_add_str(fd, COL_PROTOCOL, "VSPP Disconnect");
283 case VSPP_PKTTYPE_PROBE:
284 if (check_col(fd, COL_PROTOCOL))
285 col_add_str(fd, COL_PROTOCOL, "VSPP Probe");
287 case VSPP_PKTTYPE_ACK:
288 if (check_col(fd, COL_PROTOCOL))
289 col_add_str(fd, COL_PROTOCOL, "VSPP Ack");
292 if (check_col(fd, COL_PROTOCOL))
293 col_add_str(fd, COL_PROTOCOL, "VSPP Unknown");
295 if (check_col(fd, COL_INFO))
296 col_add_fstr(fd, COL_INFO, "NS=%04x NR=%04x Window=%04x RID=%04x LID=%04x D=%04x S=%04x",
297 viph.vspp_seqno, viph.vspp_ack, viph.vspp_win, viph.vspp_rmtid,
298 viph.vspp_lclid, viph.vspp_dport, viph.vspp_sport);
300 iph.ip_tos = IPTOS_TOS(iph.ip_tos);
304 strcpy(tos_str, "None");
307 strcpy(tos_str, "Minimize delay");
309 case IPTOS_THROUGHPUT:
310 strcpy(tos_str, "Maximize throughput");
312 case IPTOS_RELIABILITY:
313 strcpy(tos_str, "Maximize reliability");
316 strcpy(tos_str, "Minimize cost");
319 strcpy(tos_str, "Unknon. Malformed?");
325 ti = proto_tree_add_text(tree, offset, sizeof(viph), "Vines SPP");
326 vspp_tree = proto_item_add_subtree(ti, ett_vines_spp);
327 proto_tree_add_text(vspp_tree, offset, 2, "Source port: 0x%04x", viph.vspp_sport);
328 proto_tree_add_text(vspp_tree, offset+2, 2, "Destination port: 0x%04x", viph.vspp_dport);
329 proto_tree_add_text(vspp_tree, offset+4, 1, "Packet type: 0x%02x", viph.vspp_pkttype);
330 proto_tree_add_text(vspp_tree, offset+5, 1, "Control: 0x%02x", viph.vspp_control);
331 proto_tree_add_text(vspp_tree, offset+6, 2, "Local Connection ID: 0x%04x", viph.vspp_lclid);
332 proto_tree_add_text(vspp_tree, offset+8, 2, "Remote Connection ID: 0x%04x", viph.vspp_rmtid);
333 proto_tree_add_text(vspp_tree, offset+10, 2, "Sequence number: 0x%04x", viph.vspp_seqno);
334 proto_tree_add_text(vspp_tree, offset+12, 2, "Ack number: 0x%04x", viph.vspp_ack);
335 proto_tree_add_text(vspp_tree, offset+14, 2, "Window: 0x%04x", viph.vspp_win);
337 offset += 16; /* sizeof SPP */
338 dissect_data(pd, offset, fd, tree);
342 proto_register_vines(void)
344 static gint *ett[] = {
350 proto_register_subtree_array(ett, array_length(ett));
354 proto_reg_handoff_vines(void)
356 dissector_add("ethertype", ETHERTYPE_VINES, dissect_vines);
357 dissector_add("ppp.protocol", PPP_VINES, dissect_vines);
358 dissector_add("ip.proto", IP_PROTO_VINES, dissect_vines_frp);