2 * Routines for Token-Ring Media Access Control
3 * Gilbert Ramirez <gram@verdict.uthscsa.edu>
5 * $Id: packet-trmac.c,v 1.6 1998/10/22 04:03:40 gram Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@unicom.net>
9 * Copyright 1998 Gerald Combs
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.
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.
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.
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
41 #ifdef HAVE_SYS_TYPES_H
42 # include <sys/types.h>
45 #ifdef HAVE_NETINET_IN_H
46 # include <netinet/in.h>
54 static value_string major_vectors[] = {
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" },
85 sv_text(const u_char *pd, int pkt_offset, GtkWidget *tree)
87 int sv_length = pd[0];
89 char *beacon[] = {"Recovery mode set", "Signal loss error",
90 "Streaming signal not Claim Token MAC frame",
91 "Streaming signal, Claim Token MAC frame"};
93 GtkWidget *sv_tree, *ti;
95 u_char errors[6]; /* isolating or non-isolating */
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);*/
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] ) ] );
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]));
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] ));
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] ) );
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] ) );
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] ) );
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] ) );
138 case 0x09: /* Correlator */
139 add_item_to_tree(tree, pkt_offset+1, sv_length-1,
140 "Correlator: %04X", pntohs( &pd[2] ) );
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]));
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] ) );
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] ),
160 case 0x21: /* Reserved */
161 add_item_to_tree(tree, pkt_offset+1, sv_length-1,
162 "Reserved: 0x%04X", pntohs( &pd[2] ) );
165 case 0x22: /* Product Instance ID */
166 add_item_to_tree(tree, pkt_offset+1, sv_length-1,
167 "Product Instance ID: ...");
170 case 0x23: /* Ring Station Microcode Level */
171 add_item_to_tree(tree, pkt_offset+1, sv_length-1,
172 "Ring Station Microcode Level: ...");
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);
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);
185 case 0x29: /* Ring Station Status Subvector */
186 add_item_to_tree(tree, pkt_offset+1, sv_length-1,
187 "Ring Station Status Subvector: ...");
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] ) );
195 case 0x2B: /* Group Address */
196 add_item_to_tree(tree, pkt_offset+1, sv_length-1,
197 "Group Address: %08X", pntohl( &pd[2] ) );
200 case 0x2C: /* Functional Address */
201 add_item_to_tree(tree, pkt_offset+1, sv_length-1,
202 "Functional Address: %08X", pntohl( &pd[2] ) );
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);
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]);
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);
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]);
246 case 0x30: /* Error Code */
247 add_item_to_tree(tree, pkt_offset+1, sv_length-1,
248 "Error Code: %04X", pntohs( &pd[2] ) );
251 default: /* Unknown */
252 add_item_to_tree(tree, pkt_offset+1, 1,
253 "Unknown Sub-Vector: 0x%02X", pd[1]);
259 dissect_trmac(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
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" };
268 mv_length = ntohs(*((guint16*)&pd[offset]));
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);
277 /* Interpret the major vector */
278 mv_text = match_strval(pd[offset+3], major_vectors);
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);
288 add_item_to_tree(mac_tree, offset+3, 1, "Major Vector Command: %s",
291 add_item_to_tree(mac_tree, offset+3, 1, "Major Vector Command: %02X (Unknown)",
293 add_item_to_tree(mac_tree, offset, 2, "Total Length: %d bytes",
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 ]);
300 /* interpret the subvectors */
303 sv_length = mv_length - 4;
304 while (sv_offset < sv_length) {
305 sv_offset += sv_text(&pd[offset + sv_offset], offset + sv_offset,