d6acf327a6f001826f205dba5e4a39b76947a864
[obnox/wireshark/wip.git] / packet-llc.c
1 /* packet-llc.c
2  * Routines for IEEE 802.2 LLC layer
3  * Gilbert Ramirez <gram@verdict.uthscsa.edu>
4  *
5  * $Id: packet-llc.c,v 1.4 1998/09/17 18:43:11 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 #include <pcap.h>
32
33 #include <gtk/gtk.h>
34
35 #include <stdio.h>
36
37 #include "packet.h"
38 #include "ethereal.h"
39 #include "etypes.h"
40
41 struct sap_info {
42         u_char  sap;
43         void    (*func) (const u_char *, int, frame_data *, GtkTree *);
44         char    *text;
45 };
46
47 static struct sap_info  saps[] = {
48         { 0x00, NULL,           "NULL LSAP" },
49         { 0x02, NULL,           "LLC Sub-Layer Management Individual" },
50         { 0x03, NULL,           "LLC Sub-Layer Management Group" },
51         { 0x04, NULL,           "SNA Path Control Individual" },
52         { 0x05, NULL,           "SNA Path Control Group" },
53         { 0x06, dissect_ip,     "TCP/IP" },
54         { 0x08, NULL,           "SNA" },
55         { 0x0C, NULL,           "SNA" },
56         { 0x42, NULL,           "Spanning Tree BPDU" },
57         { 0x7F, NULL,           "ISO 802.2" },
58         { 0x80, NULL,           "XNS" },
59         { 0xAA, NULL,           "SNAP" },
60         { 0xBA, dissect_vines,  "Banyan Vines" },
61         { 0xBC, dissect_vines,  "Banyan Vines" },
62         { 0xE0, dissect_ipx,    "NetWare" },
63         { 0xF0, NULL,           "NetBIOS" },
64         { 0xF4, NULL,           "IBM Net Management Individual" },
65         { 0xF5, NULL,           "IBM Net Management Group" },
66         { 0xF8, NULL,           "Remote Program Load" },
67         { 0xFC, NULL,           "Remote Program Load" },
68         { 0xFE, dissect_osi,    "ISO Network Layer" },
69         { 0xFF, NULL,           "Global LSAP" },
70         { 0x00, NULL,           NULL }
71 };
72
73
74 static char*
75 sap_text(u_char sap) {
76         int i=0;
77
78         while (saps[i].text != NULL) {
79                 if (saps[i].sap == sap) {
80                         return saps[i].text;
81                 }
82                 i++;
83         }
84         return "Unknown";
85 }
86
87 static void*
88 sap_func(u_char sap) {
89         int i=0;
90
91         while (saps[i].text != NULL) {
92                 if (saps[i].sap == sap) {
93                         return saps[i].func;
94                 }
95                 i++;
96         }
97         return dissect_data;
98 }
99
100 static char*
101 llc_org(const u_char *ptr) {
102
103         unsigned long org = (ptr[0] << 16) | (ptr[1] << 8) | ptr[2];
104         char *llc_org[1] = {
105                 "Encapsulated Ethernet"};
106
107         if (org > 0) {
108                 return "Unknown";
109         }
110         else {
111                 return llc_org[org];
112         }
113 }
114
115 void
116 dissect_llc(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
117
118         GtkWidget       *llc_tree, *ti;
119         guint16         etype;
120         int             is_snap;
121         void            (*dissect) (const u_char *, int, frame_data *, GtkTree *);
122
123         /* LLC Strings */
124         char *llc_ctrl[4] = {
125                 "Information Transfer", "Supervisory",
126                 "", "Unnumbered Information" };
127
128         is_snap = (pd[offset] == 0xAA) && (pd[offset+1] == 0xAA);
129
130         if (fd->win_info[0]) {
131                 strcpy(fd->win_info[3], "LLC");
132         }
133   
134         if (tree) {
135                 ti = add_item_to_tree(GTK_WIDGET(tree), offset, (is_snap ? 8 : 3),
136                         "Logical-Link Control");
137                 llc_tree = gtk_tree_new();
138                 add_subtree(ti, llc_tree, ETT_LLC);
139                 add_item_to_tree(llc_tree, offset,      1, "DSAP: %s (0x%02X)",
140                         sap_text(pd[offset]), pd[offset]);
141                 add_item_to_tree(llc_tree, offset+1,    1, "SSAP: %s (0x%02X)",
142                         sap_text(pd[offset+1]), pd[offset+1]);
143                 add_item_to_tree(llc_tree, offset+2,    1, "Control: %s",
144                         llc_ctrl[pd[offset+2] & 3]);
145         }
146
147         if (is_snap) {
148                 if (fd->win_info[0]) {
149                         strcpy(fd->win_info[4], "802.2 LLC (SNAP)");
150                 }
151                 if (tree) {
152                         add_item_to_tree(llc_tree, offset+3,    3,
153                                 "Organization Code: %s (%02X-%02X-%02X)",
154                                 llc_org(&pd[offset+3]), 
155                                 pd[offset+3], pd[offset+4], pd[offset+5]);
156                 }
157                 etype  = (pd[offset+6] << 8) | pd[offset+7];
158                 offset += 8;
159                 ethertype(etype, offset, pd, fd, tree, llc_tree);
160         }               
161         else {
162                 if (fd->win_info[0]) {
163                         sprintf(fd->win_info[4], "802.2 LLC (%s)", sap_text(pd[offset]));
164                 }
165
166                 dissect = sap_func(pd[offset]);
167
168                 /* non-SNAP */
169                 offset += 3;
170
171                 if (dissect) {
172                         dissect(pd, offset, fd, tree);
173                 }
174                 else {
175                         dissect_data(pd, offset, fd, tree);
176                 }
177
178         }
179 }