Silly mistake which caused if(tree) to fail.
[obnox/wireshark/wip.git] / packet-trmac.c
1 /* packet-trmac.c
2  * Routines for Token-Ring Media Access Control
3  * Gilbert Ramirez <gram@verdict.uthscsa.edu>
4  *
5  * $Id: packet-trmac.c,v 1.6 1998/10/22 04:03:40 gram Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@unicom.net>
9  * Copyright 1998 Gerald Combs
10  *
11  * 
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
33 #endif
34
35 #include <pcap.h>
36
37 #include <gtk/gtk.h>
38
39 #include <stdio.h>
40
41 #ifdef HAVE_SYS_TYPES_H
42 # include <sys/types.h>
43 #endif
44
45 #ifdef HAVE_NETINET_IN_H
46 # include <netinet/in.h>
47 #endif
48
49 #include "ethereal.h"
50 #include "packet.h"
51 #include "etypes.h"
52
53 /* Major Vector */
54 static value_string major_vectors[] = {
55                 { 0x00, "Response" },
56                 { 0x02, "Beacon" },
57                 { 0x03, "Claim Token" },
58                 { 0x04, "Ring Purge" },
59                 { 0x05, "Active Monitor Present" },
60                 { 0x06, "Standby Monitor Present" },
61                 { 0x07, "Duplicate Address Test" },
62                 { 0x09, "Transmit Forward" },
63                 { 0x0B, "Remove Ring Station" },
64                 { 0x0C, "Change Parameters" },
65                 { 0x0D, "Initialize Ring Station" },
66                 { 0x0E, "Request Ring Station Address" },
67                 { 0x0F, "Request Ring Station Address" },
68                 { 0x10, "Request Ring Station Attachments" },
69                 { 0x20, "Request Initialization" },
70                 { 0x22, "Report Ring Station Address" },
71                 { 0x23, "Report Ring Station State" },
72                 { 0x24, "Report Ring Station Attachments" },
73                 { 0x25, "Report New Active Monitor" },
74                 { 0x26, "Report NAUN Change" },
75                 { 0x27, "Report Poll Error" },
76                 { 0x28, "Report Monitor Errors" },
77                 { 0x29, "Report Error" },
78                 { 0x2A, "Report Transmit Forward" },
79                 { 0x00, NULL }
80 };
81
82
83 /* Sub-vectors */
84 static int
85 sv_text(const u_char *pd, int pkt_offset, GtkWidget *tree)
86 {
87         int     sv_length = pd[0];
88
89         char *beacon[] = {"Recovery mode set", "Signal loss error",
90                 "Streaming signal not Claim Token MAC frame",
91                 "Streaming signal, Claim Token MAC frame"};
92
93         GtkWidget       *sv_tree, *ti;
94
95         u_char          errors[6];      /* isolating or non-isolating */
96
97         /* this just adds to the clutter on the screen...
98         add_item_to_tree(tree, pkt_offset, 1,
99                 "Subvector Length: %d bytes", sv_length);*/
100
101         switch(pd[1]) {
102                 case 0x01: /* Beacon Type */
103                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
104                                 "Beacon Type: %s", beacon[ pntohs( &pd[2] ) ] );
105                         break;
106
107                 case 0x02: /* NAUN */
108                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
109                                 "NAUN: %s", ether_to_str((guint8*)&pd[2]));
110                         break;
111
112                 case 0x03: /* Local Ring Number */
113                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
114                                 "Local Ring Number: 0x%04X (%d)",
115                                 pntohs( &pd[2] ), pntohs( &pd[2] ));
116                         break;
117
118                 case 0x04: /* Assign Physical Location */
119                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
120                                 "Assign Physical Location: 0x%08X", pntohl( &pd[2] ) );
121                         break;
122
123                 case 0x05: /* Soft Error Report Value */
124                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
125                                 "Soft Error Report Value: %d ms", 10 * pntohs( &pd[2] ) );
126                         break;
127
128                 case 0x06: /* Enabled Function Classes */
129                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
130                                 "Enabled Function Classes: %04X",  pntohs( &pd[2] ) );
131                         break;
132
133                 case 0x07: /* Allowed Access Priority */
134                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
135                                 "Allowed Access Priority: %04X",  pntohs( &pd[2] ) );
136                         break;
137
138                 case 0x09: /* Correlator */
139                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
140                                 "Correlator: %04X",  pntohs( &pd[2] ) );
141                         break;
142
143                 case 0x0A: /* Address of last neighbor notification */
144                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
145                                 "Address of Last Neighbor Notification: %s",
146                                 ether_to_str((guint8*)&pd[2]));
147                         break;
148
149                 case 0x0B: /* Physical Location */
150                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
151                                 "Physical Location: 0x%08X", pntohl( &pd[2] ) );
152                         break;
153
154                 case 0x20: /* Response Code */
155                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
156                                 "Response Code: 0x%04X 0x%04X", pntohl( &pd[2] ),
157                                 pntohl( &pd[4] ) );
158                         break;
159
160                 case 0x21: /* Reserved */
161                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
162                                 "Reserved: 0x%04X", pntohs( &pd[2] ) );
163                         break;
164
165                 case 0x22: /* Product Instance ID */
166                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
167                                 "Product Instance ID: ...");
168                         break;
169
170                 case 0x23: /* Ring Station Microcode Level */
171                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
172                                 "Ring Station Microcode Level: ...");
173                         break;
174
175                 case 0x26: /* Wrap data */
176                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
177                                 "Wrap Data: ... (%d bytes)", sv_length - 2);
178                         break;
179
180                 case 0x27: /* Frame Forward */
181                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
182                                 "Frame Forward: ... (%d bytes)", sv_length - 2);
183                         break;
184
185                 case 0x29: /* Ring Station Status Subvector */
186                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
187                                 "Ring Station Status Subvector: ...");
188                         break;
189
190                 case 0x2A: /* Transmit Status Code */
191                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
192                                 "Transmit Status Code: %04X", pntohs( &pd[2] ) );
193                         break;
194
195                 case 0x2B: /* Group Address */
196                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
197                                 "Group Address: %08X", pntohl( &pd[2] ) );
198                         break;
199
200                 case 0x2C: /* Functional Address */
201                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
202                                 "Functional Address: %08X", pntohl( &pd[2] ) );
203                         break;
204
205                 case 0x2D: /* Isolating Error Counts */
206                         memcpy(errors, &pd[2], 6);
207                         ti = add_item_to_tree(GTK_WIDGET(tree), pkt_offset+1, sv_length-1,
208                                 "Isolating Error Counts (%d total)",
209                                 errors[0] + errors[1] + errors[2] + errors[3] + errors[4]);
210                         sv_tree = gtk_tree_new();
211                         add_subtree(ti, sv_tree, ETT_TR_IERR_CNT);
212
213                         add_item_to_tree(sv_tree, pkt_offset+2, 1,
214                                 "Line Errors: %d", errors[0]);
215                         add_item_to_tree(sv_tree, pkt_offset+3, 1,
216                                 "Internal Errors: %d", errors[1]);
217                         add_item_to_tree(sv_tree, pkt_offset+4, 1,
218                                 "Burst Errors: %d", errors[2]);
219                         add_item_to_tree(sv_tree, pkt_offset+5, 1,
220                                 "A/C Errors: %d", errors[3]);
221                         add_item_to_tree(sv_tree, pkt_offset+6, 1,
222                                 "Abort delimiter transmitted: %d", errors[4]);
223
224                         break;
225
226                 case 0x2E: /* Non-Isolating Error Counts */
227                         memcpy(errors, &pd[2], 6);
228                         ti = add_item_to_tree(GTK_WIDGET(tree), pkt_offset+1, sv_length-1,
229                                 "Non-Isolating Error Counts (%d total)",
230                                 errors[0] + errors[1] + errors[2] + errors[3] + errors[4]);
231                         sv_tree = gtk_tree_new();
232                         add_subtree(ti, sv_tree, ETT_TR_NERR_CNT);
233
234                         add_item_to_tree(sv_tree, pkt_offset+2, 1,
235                                 "Lost Frame Errors: %d", errors[0]);
236                         add_item_to_tree(sv_tree, pkt_offset+3, 1,
237                                 "Receiver Congestion: %d", errors[1]);
238                         add_item_to_tree(sv_tree, pkt_offset+4, 1,
239                                 "Frame-Copied Congestion: %d", errors[2]);
240                         add_item_to_tree(sv_tree, pkt_offset+5, 1,
241                                 "Frequency Errors: %d", errors[3]);
242                         add_item_to_tree(sv_tree, pkt_offset+6, 1,
243                                 "Token Errors: %d", errors[4]);
244                         break;
245
246                 case 0x30: /* Error Code */
247                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
248                                 "Error Code: %04X", pntohs( &pd[2] ) );
249                         break;
250
251                 default: /* Unknown */
252                         add_item_to_tree(tree, pkt_offset+1, 1,
253                                 "Unknown Sub-Vector: 0x%02X", pd[1]);
254         }
255         return sv_length;
256 }
257
258 void
259 dissect_trmac(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
260
261         GtkWidget       *mac_tree = NULL, *ti;
262         int                     mv_length, sv_length, sv_offset;
263         char            *class[] = { "Ring Station", "LLC Manager", "", "",
264                 "Configuration Report Server", "Ring Parameter Server",
265                 "Ring Error Monitor" };
266         char            *mv_text;
267
268         mv_length = ntohs(*((guint16*)&pd[offset]));
269
270         if (tree) {
271                 ti = add_item_to_tree(GTK_WIDGET(tree), offset, mv_length,
272                         "Media Access Control");
273                 mac_tree = gtk_tree_new();
274                 add_subtree(ti, mac_tree, ETT_TR_MAC);
275         }
276
277         /* Interpret the major vector */
278         mv_text = match_strval(pd[offset+3], major_vectors);
279
280         /* Summary information */
281         if (fd->win_info[COL_NUM]) {
282                 strcpy(fd->win_info[COL_PROTOCOL], "TR MAC");
283                 strcpy(fd->win_info[COL_INFO], mv_text);
284         }
285
286         if (tree) {
287                 if (mv_text)
288                         add_item_to_tree(mac_tree, offset+3, 1, "Major Vector Command: %s",
289                                                         mv_text);
290                 else
291                         add_item_to_tree(mac_tree, offset+3, 1, "Major Vector Command: %02X (Unknown)",
292                                                         pd[offset+3]);
293                 add_item_to_tree(mac_tree, offset, 2, "Total Length: %d bytes",
294                         mv_length);
295                 add_item_to_tree(mac_tree, offset+2, 1, "Source Class: %s",
296                         class[ pd[offset+2] & 0x0f ]);
297                 add_item_to_tree(mac_tree, offset+2, 1, "Destination Class: %s",
298                         class[ pd[offset+2] >> 4 ]);
299
300                 /* interpret the subvectors */
301                 sv_offset = 0;
302                 offset += 4;
303                 sv_length = mv_length - 4;
304                 while (sv_offset < sv_length) {
305                         sv_offset += sv_text(&pd[offset + sv_offset], offset + sv_offset,
306                                                                 mac_tree);
307                 }
308         }
309 }