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