98cc8a8f9fbc46a4cd0177c2bfba489bfe0e97d4
[obnox/wireshark/wip.git] / packet-vines.c
1 /* packet-vines.c
2  * Routines for Banyan VINES protocol packet disassembly
3  *
4  * $Id: packet-vines.c,v 1.9 1999/10/22 08:51:04 guy Exp $
5  *
6  * Don Lafontaine <lafont02@cn.ca>
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@zing.org>
10  * Copyright 1998 Gerald Combs
11  * Joerg Mayer <jmayer@telemation.de>
12  *
13  * 
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.
18  * 
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.
23  * 
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.
27  */
28
29 #include "config.h"
30
31 #ifdef HAVE_SYS_TYPES_H
32 #include <sys/types.h>
33 #endif
34
35 #ifdef HAVE_NETINET_IN_H
36 #include <netinet/in.h>
37 #endif
38
39 #include <glib.h>
40 #include "packet.h"
41 #include "packet-vines.h"
42
43
44 /* AFAIK Vines FRP (Fragmentation Protocol) is used on all media except Ethernet
45  * and TR (and probably FDDI) - Fragmentation on these media types is not possible
46  * FIXME: Do we need to use this header with PPP too?
47  */
48
49 void
50 dissect_vines_frp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
51   guint8   vines_frp_ctrl, vines_frp_seqno; 
52   proto_tree *vines_frp_tree;
53   proto_item *ti;
54   gchar frp_flags_str[32];
55
56   /* To do: Check for {cap len,pkt len} < struct len */
57   /* Avoids alignment problems on many architectures. */
58   vines_frp_ctrl = pd[offset];
59   vines_frp_seqno = pd[offset+1];
60   
61   if (check_col(fd, COL_PROTOCOL))
62     col_add_str(fd, COL_PROTOCOL, "Vines FRP");
63   /*
64    * 1: first fragment of vines packet
65    * 2: last fragment of vines packet
66    * 4 ... 80: unused
67    */
68   switch (vines_frp_ctrl) {
69   case 0:
70     strcpy(frp_flags_str, "middle");
71     break;
72   case 1:
73     strcpy(frp_flags_str, "first");
74     break;
75   case 2:
76     strcpy(frp_flags_str, "last");
77     break;
78   case 3:
79     strcpy(frp_flags_str, "only");
80     break;
81   default:
82     strcpy(frp_flags_str, "please report: unknown");
83     break;
84   }
85   
86   if (tree) {
87     ti = proto_tree_add_text(tree, offset, 2, "Vines Fragmentation Protocol");
88     vines_frp_tree = proto_item_add_subtree(ti, ETT_VINES_FRP);
89     proto_tree_add_text(vines_frp_tree, offset,     1, "Control Flags: 0x%02x = %s fragment", vines_frp_ctrl, frp_flags_str);
90     proto_tree_add_text(vines_frp_tree, offset + 1, 1, "Sequence Number: 0x%02x", vines_frp_seqno);
91   }
92
93   /* Skip over header */
94   offset += 2;
95
96   /* Decode the "real" Vines now */
97   dissect_vines(pd, offset, fd, tree);
98 }
99
100 gchar *
101 vines_addr_to_str(const guint8 *addrp)
102 {
103   static gchar  str[3][214];
104   static gchar  *cur;
105
106   if (cur == &str[0][0]) {
107     cur = &str[1][0];
108   } else if (cur == &str[1][0]) {
109     cur = &str[2][0];
110   } else {
111     cur = &str[0][0];
112   }
113
114   sprintf(cur, "%08x.%04x", pntohl(&addrp[0]), pntohs(&addrp[4]));
115   return cur;
116 }
117
118 void
119 dissect_vines(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) 
120         {
121         e_vip       viph;
122         proto_tree *vip_tree;
123         proto_item *ti;
124 /*      gchar      tos_str[32]; */
125         int  is_broadcast = 0;
126         int  hops = 0;
127
128   /* To do: check for runts, errs, etc. */
129   /* Avoids alignment problems on many architectures. */
130         memcpy(&viph, &pd[offset], sizeof(e_vip));
131
132         viph.vip_chksum = pntohs(&pd[offset]);
133         viph.vip_pktlen = pntohs(&pd[offset+2]);
134         viph.vip_dnet = pntohl(&pd[offset+6]);
135         viph.vip_dsub = pntohs(&pd[offset+10]);
136         viph.vip_snet = pntohl(&pd[offset+12]);
137         viph.vip_ssub = pntohs(&pd[offset+16]);
138
139         switch (viph.vip_proto) {
140         case VIP_PROTO_IPC:
141                 if (check_col(fd, COL_PROTOCOL))
142                         col_add_str(fd, COL_PROTOCOL, "Vines IPC");
143                 if (check_col(fd, COL_INFO))
144                         col_add_fstr(fd, COL_INFO, "IPC (%02x)", viph.vip_proto);
145                 break;
146         case VIP_PROTO_SPP:      
147                 if (check_col(fd, COL_PROTOCOL))
148                         col_add_str(fd, COL_PROTOCOL, "Vines SPP");
149                 if (check_col(fd, COL_INFO))
150                         col_add_fstr(fd, COL_INFO, "SPP (%02x)", viph.vip_proto);
151                 break;
152         case VIP_PROTO_ARP:
153                 if (check_col(fd, COL_PROTOCOL))
154                         col_add_str(fd, COL_PROTOCOL, "Vines ARP");
155                 if (check_col(fd, COL_INFO))
156                         col_add_fstr(fd, COL_INFO, "ARP (%02x)", viph.vip_proto);
157                 break;
158         case VIP_PROTO_RTP:
159                 if (check_col(fd, COL_PROTOCOL))
160                         col_add_str(fd, COL_PROTOCOL, "Vines RTP");
161                 if (check_col(fd, COL_INFO))
162                         col_add_fstr(fd, COL_INFO, "RTP (%02x)", viph.vip_proto);
163                 break;
164         case VIP_PROTO_ICP:
165                 if (check_col(fd, COL_PROTOCOL))
166                         col_add_str(fd, COL_PROTOCOL, "Vines ICP");
167                 if (check_col(fd, COL_INFO))
168                         col_add_fstr(fd, COL_INFO, "ICP (%02x)", viph.vip_proto);
169                 break;
170         default:
171                 if (check_col(fd, COL_PROTOCOL))
172                         col_add_str(fd, COL_PROTOCOL, "Vines IP");
173                 if (check_col(fd, COL_INFO))
174                         col_add_fstr(fd, COL_INFO, "Unknown VIP protocol (%02x)", viph.vip_proto);
175         }
176
177         SET_ADDRESS(&pi.net_src, AT_VINES, 6, &pd[offset+12]);
178         SET_ADDRESS(&pi.src, AT_VINES, 6, &pd[offset+12]);
179         SET_ADDRESS(&pi.net_dst, AT_VINES, 6, &pd[offset+6]);
180         SET_ADDRESS(&pi.dst, AT_VINES, 6, &pd[offset+6]);
181
182         /* helpers to decode flags */
183         /* FIXME: Not used yet */
184         if ((viph.vip_dnet == 0xffffffff) && (viph.vip_dsub == 0xffff)) {
185                 is_broadcast = 1;
186         }
187         hops = viph.vip_tctl & 0xf; 
188  
189   /*
190         viph.ip_tos = IPTOS_TOS(viph.ip_tos);
191         switch (viph.ip_tos) 
192                 {
193         case IPTOS_NONE:
194                 strcpy(tos_str, "None");
195                 break;
196         case IPTOS_LOWDELAY:
197                 strcpy(tos_str, "Minimize delay");
198                 break;
199         case IPTOS_THROUGHPUT:
200                 strcpy(tos_str, "Maximize throughput");
201                 break;
202         case IPTOS_RELIABILITY:
203                 strcpy(tos_str, "Maximize reliability");
204                 break;
205         case IPTOS_LOWCOST:
206                 strcpy(tos_str, "Minimize cost");
207                 break;
208         default:
209                 strcpy(tos_str, "Unknon.  Malformed?");
210                 break;
211                 }
212   */
213         if (tree) 
214                 {
215         ti = proto_tree_add_text(tree, offset, (viph.vip_pktlen), "Vines IP");
216         vip_tree = proto_item_add_subtree(ti, ETT_VINES);
217         proto_tree_add_text(vip_tree, offset,      2, "Packet checksum: 0x%04x", viph.vip_chksum);
218         proto_tree_add_text(vip_tree, offset +  2, 2, "Packet length: 0x%04x (%d)", viph.vip_pktlen, viph.vip_pktlen); 
219         proto_tree_add_text(vip_tree, offset +  4, 1, "Transport control: 0x%02x",
220                 viph.vip_tctl);
221         proto_tree_add_text(vip_tree, offset +  5, 1, "Protocol: 0x%02x", viph.vip_proto);
222                 }
223
224
225         offset += 18;
226         switch (viph.vip_proto) 
227                 {
228         case VIP_PROTO_SPP:
229                 dissect_vines_spp(pd, offset, fd, tree);
230                 break;
231                 }
232         }
233 #define VINES_VSPP_DATA 1
234 #define VINES_VSPP_ACK 5
235 void dissect_vines_spp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) 
236         {
237         e_vspp       viph;
238         proto_tree *vspp_tree;
239         proto_item *ti;
240
241   /* To do: check for runts, errs, etc. */
242   /* Avoids alignment problems on many architectures. */
243         memcpy(&viph, &pd[offset], sizeof(e_vspp));
244
245         viph.vspp_sport = ntohs(viph.vspp_sport);
246         viph.vspp_dport = ntohs(viph.vspp_dport);
247         viph.vspp_lclid = ntohs(viph.vspp_lclid);
248         viph.vspp_rmtid = ntohs(viph.vspp_rmtid);
249
250     switch (viph.vspp_pkttype) 
251         {
252         case VSPP_PKTTYPE_DATA:      
253                                         if (check_col(fd, COL_PROTOCOL))
254                         col_add_str(fd, COL_PROTOCOL, "VSPP Data");
255                 break;
256         case VSPP_PKTTYPE_DISC:      
257                                         if (check_col(fd, COL_PROTOCOL))
258                         col_add_str(fd, COL_PROTOCOL, "VSPP Disconnect");
259                 break;
260         case VSPP_PKTTYPE_PROBE:      
261                                         if (check_col(fd, COL_PROTOCOL))
262                         col_add_str(fd, COL_PROTOCOL, "VSPP Probe");
263                 break;
264         case VSPP_PKTTYPE_ACK:
265                                         if (check_col(fd, COL_PROTOCOL))
266                         col_add_str(fd, COL_PROTOCOL, "VSPP Ack");
267                 break;
268         default:
269                                         if (check_col(fd, COL_PROTOCOL))
270                         col_add_str(fd, COL_PROTOCOL, "VSPP Unknown");
271         }
272         if (check_col(fd, COL_INFO))
273                 col_add_fstr(fd, COL_INFO, "NS=%04x NR=%04x Window=%04x RID=%04x LID=%04x D=%04x S=%04x", 
274                         viph.vspp_seqno, viph.vspp_ack, viph.vspp_win, viph.vspp_rmtid,
275                         viph.vspp_lclid, viph.vspp_dport, viph.vspp_sport);
276   /*
277         iph.ip_tos = IPTOS_TOS(iph.ip_tos);
278         switch (iph.ip_tos)
279                 {
280         case IPTOS_NONE:
281                 strcpy(tos_str, "None");
282                 break;
283         case IPTOS_LOWDELAY:
284                 strcpy(tos_str, "Minimize delay");
285                 break;
286         case IPTOS_THROUGHPUT:
287                 strcpy(tos_str, "Maximize throughput");
288                 break;
289         case IPTOS_RELIABILITY:
290                 strcpy(tos_str, "Maximize reliability");
291                 break;
292         case IPTOS_LOWCOST:
293                 strcpy(tos_str, "Minimize cost");
294                 break;
295         default:
296                 strcpy(tos_str, "Unknon.  Malformed?");
297                 break;
298                 }
299 */ 
300         if (tree) 
301                 {
302         ti = proto_tree_add_text(tree, offset, sizeof(viph), "Vines SPP");
303         vspp_tree = proto_item_add_subtree(ti, ETT_VINES_SPP);
304         proto_tree_add_text(vspp_tree, offset,      2, "Source port: 0x%04x", viph.vspp_sport);
305         proto_tree_add_text(vspp_tree, offset+2,    2, "Destination port: 0x%04x", viph.vspp_dport); 
306         proto_tree_add_text(vspp_tree, offset+4,    1, "Packet type: 0x%02x", viph.vspp_pkttype);
307         proto_tree_add_text(vspp_tree, offset+5,    1, "Control: 0x%02x", viph.vspp_control);
308         proto_tree_add_text(vspp_tree, offset+6,    2, "Local Connection ID: 0x%04x", viph.vspp_lclid);
309         proto_tree_add_text(vspp_tree, offset+8,    2, "Remote Connection ID: 0x%04x", viph.vspp_rmtid);
310         proto_tree_add_text(vspp_tree, offset+10,   2, "Sequence number: 0x%04x", viph.vspp_seqno);
311         proto_tree_add_text(vspp_tree, offset+12,   2, "Ack number: 0x%04x", viph.vspp_ack);
312         proto_tree_add_text(vspp_tree, offset+14,   2, "Window: 0x%04x", viph.vspp_win);
313                 }
314
315         }