The Sniffer-reading code in wiretap now decodes the time field for each
[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.7 1998/11/12 00:06:39 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
36 #include <gtk/gtk.h>
37
38 #include <stdio.h>
39
40 #ifdef HAVE_SYS_TYPES_H
41 # include <sys/types.h>
42 #endif
43
44 #ifdef HAVE_NETINET_IN_H
45 # include <netinet/in.h>
46 #endif
47
48 #include "ethereal.h"
49 #include "packet.h"
50 #include "etypes.h"
51
52 /* Major Vector */
53 static value_string major_vectors[] = {
54                 { 0x00, "Response" },
55                 { 0x02, "Beacon" },
56                 { 0x03, "Claim Token" },
57                 { 0x04, "Ring Purge" },
58                 { 0x05, "Active Monitor Present" },
59                 { 0x06, "Standby Monitor Present" },
60                 { 0x07, "Duplicate Address Test" },
61                 { 0x09, "Transmit Forward" },
62                 { 0x0B, "Remove Ring Station" },
63                 { 0x0C, "Change Parameters" },
64                 { 0x0D, "Initialize Ring Station" },
65                 { 0x0E, "Request Ring Station Address" },
66                 { 0x0F, "Request Ring Station Address" },
67                 { 0x10, "Request Ring Station Attachments" },
68                 { 0x20, "Request Initialization" },
69                 { 0x22, "Report Ring Station Address" },
70                 { 0x23, "Report Ring Station State" },
71                 { 0x24, "Report Ring Station Attachments" },
72                 { 0x25, "Report New Active Monitor" },
73                 { 0x26, "Report NAUN Change" },
74                 { 0x27, "Report Poll Error" },
75                 { 0x28, "Report Monitor Errors" },
76                 { 0x29, "Report Error" },
77                 { 0x2A, "Report Transmit Forward" },
78                 { 0x00, NULL }
79 };
80
81
82 /* Sub-vectors */
83 static int
84 sv_text(const u_char *pd, int pkt_offset, GtkWidget *tree)
85 {
86         int     sv_length = pd[0];
87
88         char *beacon[] = {"Recovery mode set", "Signal loss error",
89                 "Streaming signal not Claim Token MAC frame",
90                 "Streaming signal, Claim Token MAC frame"};
91
92         GtkWidget       *sv_tree, *ti;
93
94         u_char          errors[6];      /* isolating or non-isolating */
95
96         /* this just adds to the clutter on the screen...
97         add_item_to_tree(tree, pkt_offset, 1,
98                 "Subvector Length: %d bytes", sv_length);*/
99
100         switch(pd[1]) {
101                 case 0x01: /* Beacon Type */
102                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
103                                 "Beacon Type: %s", beacon[ pntohs( &pd[2] ) ] );
104                         break;
105
106                 case 0x02: /* NAUN */
107                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
108                                 "NAUN: %s", ether_to_str((guint8*)&pd[2]));
109                         break;
110
111                 case 0x03: /* Local Ring Number */
112                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
113                                 "Local Ring Number: 0x%04X (%d)",
114                                 pntohs( &pd[2] ), pntohs( &pd[2] ));
115                         break;
116
117                 case 0x04: /* Assign Physical Location */
118                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
119                                 "Assign Physical Location: 0x%08X", pntohl( &pd[2] ) );
120                         break;
121
122                 case 0x05: /* Soft Error Report Value */
123                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
124                                 "Soft Error Report Value: %d ms", 10 * pntohs( &pd[2] ) );
125                         break;
126
127                 case 0x06: /* Enabled Function Classes */
128                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
129                                 "Enabled Function Classes: %04X",  pntohs( &pd[2] ) );
130                         break;
131
132                 case 0x07: /* Allowed Access Priority */
133                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
134                                 "Allowed Access Priority: %04X",  pntohs( &pd[2] ) );
135                         break;
136
137                 case 0x09: /* Correlator */
138                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
139                                 "Correlator: %04X",  pntohs( &pd[2] ) );
140                         break;
141
142                 case 0x0A: /* Address of last neighbor notification */
143                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
144                                 "Address of Last Neighbor Notification: %s",
145                                 ether_to_str((guint8*)&pd[2]));
146                         break;
147
148                 case 0x0B: /* Physical Location */
149                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
150                                 "Physical Location: 0x%08X", pntohl( &pd[2] ) );
151                         break;
152
153                 case 0x20: /* Response Code */
154                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
155                                 "Response Code: 0x%04X 0x%04X", pntohl( &pd[2] ),
156                                 pntohl( &pd[4] ) );
157                         break;
158
159                 case 0x21: /* Reserved */
160                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
161                                 "Reserved: 0x%04X", pntohs( &pd[2] ) );
162                         break;
163
164                 case 0x22: /* Product Instance ID */
165                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
166                                 "Product Instance ID: ...");
167                         break;
168
169                 case 0x23: /* Ring Station Microcode Level */
170                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
171                                 "Ring Station Microcode Level: ...");
172                         break;
173
174                 case 0x26: /* Wrap data */
175                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
176                                 "Wrap Data: ... (%d bytes)", sv_length - 2);
177                         break;
178
179                 case 0x27: /* Frame Forward */
180                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
181                                 "Frame Forward: ... (%d bytes)", sv_length - 2);
182                         break;
183
184                 case 0x29: /* Ring Station Status Subvector */
185                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
186                                 "Ring Station Status Subvector: ...");
187                         break;
188
189                 case 0x2A: /* Transmit Status Code */
190                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
191                                 "Transmit Status Code: %04X", pntohs( &pd[2] ) );
192                         break;
193
194                 case 0x2B: /* Group Address */
195                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
196                                 "Group Address: %08X", pntohl( &pd[2] ) );
197                         break;
198
199                 case 0x2C: /* Functional Address */
200                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
201                                 "Functional Address: %08X", pntohl( &pd[2] ) );
202                         break;
203
204                 case 0x2D: /* Isolating Error Counts */
205                         memcpy(errors, &pd[2], 6);
206                         ti = add_item_to_tree(GTK_WIDGET(tree), pkt_offset+1, sv_length-1,
207                                 "Isolating Error Counts (%d total)",
208                                 errors[0] + errors[1] + errors[2] + errors[3] + errors[4]);
209                         sv_tree = gtk_tree_new();
210                         add_subtree(ti, sv_tree, ETT_TR_IERR_CNT);
211
212                         add_item_to_tree(sv_tree, pkt_offset+2, 1,
213                                 "Line Errors: %d", errors[0]);
214                         add_item_to_tree(sv_tree, pkt_offset+3, 1,
215                                 "Internal Errors: %d", errors[1]);
216                         add_item_to_tree(sv_tree, pkt_offset+4, 1,
217                                 "Burst Errors: %d", errors[2]);
218                         add_item_to_tree(sv_tree, pkt_offset+5, 1,
219                                 "A/C Errors: %d", errors[3]);
220                         add_item_to_tree(sv_tree, pkt_offset+6, 1,
221                                 "Abort delimiter transmitted: %d", errors[4]);
222
223                         break;
224
225                 case 0x2E: /* Non-Isolating Error Counts */
226                         memcpy(errors, &pd[2], 6);
227                         ti = add_item_to_tree(GTK_WIDGET(tree), pkt_offset+1, sv_length-1,
228                                 "Non-Isolating Error Counts (%d total)",
229                                 errors[0] + errors[1] + errors[2] + errors[3] + errors[4]);
230                         sv_tree = gtk_tree_new();
231                         add_subtree(ti, sv_tree, ETT_TR_NERR_CNT);
232
233                         add_item_to_tree(sv_tree, pkt_offset+2, 1,
234                                 "Lost Frame Errors: %d", errors[0]);
235                         add_item_to_tree(sv_tree, pkt_offset+3, 1,
236                                 "Receiver Congestion: %d", errors[1]);
237                         add_item_to_tree(sv_tree, pkt_offset+4, 1,
238                                 "Frame-Copied Congestion: %d", errors[2]);
239                         add_item_to_tree(sv_tree, pkt_offset+5, 1,
240                                 "Frequency Errors: %d", errors[3]);
241                         add_item_to_tree(sv_tree, pkt_offset+6, 1,
242                                 "Token Errors: %d", errors[4]);
243                         break;
244
245                 case 0x30: /* Error Code */
246                         add_item_to_tree(tree, pkt_offset+1, sv_length-1,
247                                 "Error Code: %04X", pntohs( &pd[2] ) );
248                         break;
249
250                 default: /* Unknown */
251                         add_item_to_tree(tree, pkt_offset+1, 1,
252                                 "Unknown Sub-Vector: 0x%02X", pd[1]);
253         }
254         return sv_length;
255 }
256
257 void
258 dissect_trmac(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
259
260         GtkWidget       *mac_tree = NULL, *ti;
261         int                     mv_length, sv_length, sv_offset;
262         char            *class[] = { "Ring Station", "LLC Manager", "", "",
263                 "Configuration Report Server", "Ring Parameter Server",
264                 "Ring Error Monitor" };
265         char            *mv_text;
266
267         mv_length = ntohs(*((guint16*)&pd[offset]));
268
269         if (tree) {
270                 ti = add_item_to_tree(GTK_WIDGET(tree), offset, mv_length,
271                         "Media Access Control");
272                 mac_tree = gtk_tree_new();
273                 add_subtree(ti, mac_tree, ETT_TR_MAC);
274         }
275
276         /* Interpret the major vector */
277         mv_text = match_strval(pd[offset+3], major_vectors);
278
279         /* Summary information */
280         if (fd->win_info[COL_NUM]) {
281                 strcpy(fd->win_info[COL_PROTOCOL], "TR MAC");
282                 strcpy(fd->win_info[COL_INFO], mv_text);
283         }
284
285         if (tree) {
286                 if (mv_text)
287                         add_item_to_tree(mac_tree, offset+3, 1, "Major Vector Command: %s",
288                                                         mv_text);
289                 else
290                         add_item_to_tree(mac_tree, offset+3, 1, "Major Vector Command: %02X (Unknown)",
291                                                         pd[offset+3]);
292                 add_item_to_tree(mac_tree, offset, 2, "Total Length: %d bytes",
293                         mv_length);
294                 add_item_to_tree(mac_tree, offset+2, 1, "Source Class: %s",
295                         class[ pd[offset+2] & 0x0f ]);
296                 add_item_to_tree(mac_tree, offset+2, 1, "Destination Class: %s",
297                         class[ pd[offset+2] >> 4 ]);
298
299                 /* interpret the subvectors */
300                 sv_offset = 0;
301                 offset += 4;
302                 sv_length = mv_length - 4;
303                 while (sv_offset < sv_length) {
304                         sv_offset += sv_text(&pd[offset + sv_offset], offset + sv_offset,
305                                                                 mac_tree);
306                 }
307         }
308 }