Initial revision
[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  * Ethereal - Network traffic analyzer
6  * By Gerald Combs <gerald@unicom.net>
7  * Copyright 1998 Gerald Combs
8  *
9  * 
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  * 
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <pcap.h>
30
31 #include <gtk/gtk.h>
32
33 #include <stdio.h>
34
35 #include "packet.h"
36 #include "ethereal.h"
37 #include "etypes.h"
38
39 struct sap_info {
40         u_char  sap;
41         char    *text;
42 };
43
44 static char*
45 sap_text(u_char sap) {
46         int i=0;
47
48         static struct sap_info  saps[] = {
49                 { 0x00, "NULL LSAP" },
50                 { 0x02, "LLC Sub-Layer Management Individual" },
51                 { 0x03, "LLC Sub-Layer Management Group" },
52                 { 0x04, "SNA Path Control Individual" },
53                 { 0x05, "SNA Path Control Group" },
54                 { 0x06, "TCP/IP" },
55                 { 0x08, "SNA" },
56                 { 0x0C, "SNA" },
57                 { 0x42, "Spanning Tree BPDU" },
58                 { 0x7F, "ISO 802.2" },
59                 { 0x80, "XNS" },
60                 { 0xAA, "SNAP" },
61                 { 0xBA, "Banyan Vines" },
62                 { 0xBC, "Banyan Vines" },
63                 { 0xE0, "NetWare" },
64                 { 0xF0, "NetBIOS" },
65                 { 0xF4, "IBM Net Management Individual" },
66                 { 0xF5, "IBM Net Management Group" },
67                 { 0xF8, "Remote Program Load" },
68                 { 0xFC, "Remote Program Load" },
69                 { 0xFE, "ISO Network Layer" },
70                 { 0xFF, "Global LSAP" },
71                 { 0x00, NULL }
72         };
73
74         while (saps[i].text != NULL) {
75                 if (saps[i].sap == sap) {
76                         return saps[i].text;
77                 }
78                 i++;
79         }
80         return "Unknown";
81 }
82
83 static char*
84 llc_org(const u_char *ptr) {
85
86         unsigned long org = (ptr[0] << 16) | (ptr[1] << 8) | ptr[2];
87         char *llc_org[1] = {
88                 "Encapsulated Ethernet"};
89
90         if (org > 0) {
91                 return "Unknown";
92         }
93         else {
94                 return llc_org[org];
95         }
96 }
97
98 void
99 dissect_llc(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
100
101         GtkWidget       *llc_tree, *ti;
102         guint16         etype;
103         int                     is_snap;
104
105         /* LLC Strings */
106         char *llc_ctrl[4] = {
107                 "Information Transfer", "Supervisory",
108                 "", "Unnumbered Information" };
109
110         is_snap = (pd[offset] == 0xAA) && (pd[offset+1] == 0xAA);
111
112         if (fd->win_info[0]) {
113                 strcpy(fd->win_info[3], "LLC");
114         }
115   
116         if (tree) {
117                 ti = add_item_to_tree(GTK_WIDGET(tree), offset, (is_snap ? 8 : 3),
118                         "Logical-Link Control");
119                 llc_tree = gtk_tree_new();
120                 add_subtree(ti, llc_tree, ETT_LLC);
121                 add_item_to_tree(llc_tree, offset,      1, "DSAP: %s (0x%02X)",
122                         sap_text(pd[offset]), pd[offset]);
123                 add_item_to_tree(llc_tree, offset+1,    1, "SSAP: %s (0x%02X)",
124                         sap_text(pd[offset+1]), pd[offset+1]);
125                 add_item_to_tree(llc_tree, offset+2,    1, "Control: %s",
126                         llc_ctrl[pd[offset+2] & 3]);
127         }
128
129         if (is_snap) {
130                 if (fd->win_info[0]) {
131                         strcpy(fd->win_info[4], "802.2 LLC (SNAP)");
132                 }
133                 if (tree) {
134                         add_item_to_tree(llc_tree, offset+3,    3,
135                                 "Organization Code: %s (%02X-%02X-%02X)",
136                                 llc_org(&pd[offset+3]), 
137                                 pd[offset+3], pd[offset+4], pd[offset+5]);
138                 }
139                 etype  = (pd[offset+6] << 8) | pd[offset+7];
140                 offset += 8;
141                 ethertype(etype, offset, pd, fd, tree, llc_tree);
142         }               
143         else {
144                 if (fd->win_info[0]) {
145                         sprintf(fd->win_info[4], "802.2 LLC (%s)", sap_text(pd[offset]));
146                 }
147
148                 /* non-SNAP */
149                 offset += 3;
150
151                 switch (pd[offset-3]) {
152                         case 0x06:      /* TCP/IP */
153                                 dissect_ip(pd, offset, fd, tree);
154                                 break;
155                         case 0xe0:      /* NetWare (IPX) */
156                                 dissect_ipx(pd, offset, fd, tree);
157                                 break;
158                         default:
159                                 dissect_data(pd, offset, fd, tree);
160                                 break;
161                   }
162         }
163 }