xref: /openbsd/usr.sbin/tcpdump/print-llc.c (revision 17df1aa7)
1 /*	$OpenBSD: print-llc.c,v 1.18 2009/10/27 23:59:55 deraadt Exp $	*/
2 
3 /*
4  * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that: (1) source code distributions
9  * retain the above copyright notice and this paragraph in its entirety, (2)
10  * distributions including binary code include the above copyright notice and
11  * this paragraph in its entirety in the documentation or other materials
12  * provided with the distribution, and (3) all advertising materials mentioning
13  * features or use of this software display the following acknowledgement:
14  * ``This product includes software developed by the University of California,
15  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16  * the University nor the names of its contributors may be used to endorse
17  * or promote products derived from this software without specific prior
18  * written permission.
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22  *
23  * Code by Matt Thomas, Digital Equipment Corporation
24  *	with an awful lot of hacking by Jeffrey Mogul, DECWRL
25  */
26 
27 #include <sys/param.h>
28 #include <sys/time.h>
29 
30 #include <netinet/in.h>
31 
32 #include <ctype.h>
33 #include <netdb.h>
34 #include <signal.h>
35 #include <stdio.h>
36 #include <string.h>
37 
38 #include "interface.h"
39 #include "addrtoname.h"
40 #include "extract.h"			/* must come after interface.h */
41 #include "ethertype.h"
42 
43 #include "llc.h"
44 
45 static struct tok cmd2str[] = {
46 	{ LLC_UI,	"ui" },
47 	{ LLC_TEST,	"test" },
48 	{ LLC_XID,	"xid" },
49 	{ LLC_UA,	"ua" },
50 	{ LLC_DISC,	"disc" },
51 	{ LLC_DM,	"dm" },
52 	{ LLC_SABME,	"sabme" },
53 	{ LLC_FRMR,	"frmr" },
54 	{ 0,		NULL }
55 };
56 
57 /*
58  * Returns non-zero IFF it succeeds in printing the header
59  */
60 int
61 llc_print(const u_char *p, u_int length, u_int caplen,
62 	  const u_char *esrc, const u_char *edst)
63 {
64 	struct llc llc;
65 	register u_short et;
66 #if 0
67 	u_short control;
68 #endif
69 	register int ret;
70 
71 	if (caplen < 3) {
72 		(void)printf("[|llc]");
73 		default_print((u_char *)p, caplen);
74 		return(0);
75 	}
76 
77 	/* Watch out for possible alignment problems */
78 	memcpy((char *)&llc, (char *)p, min(caplen, sizeof(llc)));
79 
80 	if (llc.ssap == LLCSAP_GLOBAL && llc.dsap == LLCSAP_GLOBAL) {
81 		ipx_print(p, length);
82 		return (1);
83 	}
84 #ifdef notyet
85 	else if (p[0] == 0xf0 && p[1] == 0xf0)
86 		netbios_print(p, length);
87 #endif
88 	if (llc.ssap == LLCSAP_ISONS && llc.dsap == LLCSAP_ISONS
89 	    && llc.llcui == LLC_UI) {
90 		isoclns_print(p + 3, length - 3, caplen - 3, esrc, edst);
91 		return (1);
92 	}
93 
94 	if (llc.ssap == LLCSAP_SNAP && llc.dsap == LLCSAP_SNAP
95 	    && llc.llcui == LLC_UI) {
96 		if (caplen < sizeof(llc)) {
97 		    (void)printf("[|llc-snap]");
98 		    default_print((u_char *)p, caplen);
99 		    return (0);
100 		}
101 
102 		/* Cisco Discovery Protocol  - SNAP & ether type 0x2000 */
103 		if (llc.ethertype[0] == 0x20 && llc.ethertype[1] == 0x00) {
104 			cdp_print(p, length, caplen, esrc, edst);
105 			return (1);
106 		}
107 		/* Shared Spanning Tree Protocol - SNAP & ether type 0x010b */
108 		if (llc.ethertype[0] == 0x01 && llc.ethertype[1] == 0x0b) {
109 			stp_print(p, length);
110 			return (1);
111 		}
112 
113 		if (vflag)
114 			(void)printf("snap %s ", protoid_string(llc.llcpi));
115 
116 		caplen -= sizeof(llc);
117 		length -= sizeof(llc);
118 		p += sizeof(llc);
119 
120 		/* This is an encapsulated Ethernet packet */
121 		et = EXTRACT_16BITS(&llc.ethertype[0]);
122 
123 		/*
124 		 * Some protocols have special handling if they are 802.3
125 		 * SNAP encapsulated vs vers II encapsulated. Handle
126 		 * those special protocols here, and hand the rest to
127 		 * print-ether.c so we don't have to duplicate
128 		 * all that code here.
129 		 */
130 		switch (et) {
131 		case ETHERTYPE_ATALK:
132 			atalk_print(p, length);
133 			ret = 1;
134 			break;
135 		default:
136 			ret = ether_encap_print(et, p, length, caplen);
137 			break;
138 		}
139 
140 		if (ret)
141 			return (ret);
142 	}
143 
144 	if (llc.ssap == LLCSAP_8021D && llc.dsap == LLCSAP_8021D) {
145 		stp_print(p, length);
146 		return (1);
147 	}
148 
149 #if 0
150 	if (llc.ssap == 0xf0 && llc.dsap == 0xf0) {
151 		/*
152 		 * we don't actually have a full netbeui parser yet, but the
153 		 * smb parser can handle many smb-in-netbeui packets, which
154 		 * is very useful, so we call that
155 		 */
156 
157 		/*
158 		 * Skip the DSAP and LSAP.
159 		 */
160 		p += 2;
161 		length -= 2;
162 		caplen -= 2;
163 
164 		/*
165 		 * OK, what type of LLC frame is this?  The length
166 		 * of the control field depends on that - S or I
167 		 * frames have a two-byte control field, and U frames
168 		 * have a one-byte control field.
169 		 */
170 		if ((llc.llcu & LLC_U_FMT) == LLC_U_FMT) {
171 			control = llc.llcu;
172 			p += 1;
173 			length -= 1;
174 			caplen -= 1;
175 		} else {
176 			control = llc.llcis;
177 			p += 2;
178 			length -= 2;
179 			caplen -= 2;
180 		}
181 
182 		netbeui_print(control, p, p + min(caplen, length));
183 		return (1);
184 	}
185 #endif
186 
187 	if ((llc.ssap & ~LLC_GSAP) == llc.dsap) {
188 		if (eflag)
189 			(void)printf("%s ", llcsap_string(llc.dsap));
190 		else
191 			(void)printf("%s > %s %s ",
192 					etheraddr_string(esrc),
193 					etheraddr_string(edst),
194 					llcsap_string(llc.dsap));
195 	} else {
196 		if (eflag)
197 			(void)printf("%s > %s ",
198 				llcsap_string(llc.ssap & ~LLC_GSAP),
199 				llcsap_string(llc.dsap));
200 		else
201 			(void)printf("%s %s > %s %s ",
202 				etheraddr_string(esrc),
203 				llcsap_string(llc.ssap & ~LLC_GSAP),
204 				etheraddr_string(edst),
205 				llcsap_string(llc.dsap));
206 	}
207 
208 	if ((llc.llcu & LLC_U_FMT) == LLC_U_FMT) {
209 		const char *m;
210 		char f;
211 		m = tok2str(cmd2str, "%02x", LLC_U_CMD(llc.llcu));
212 		switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
213 		    case 0:			f = 'C'; break;
214 		    case LLC_GSAP:		f = 'R'; break;
215 		    case LLC_U_POLL:		f = 'P'; break;
216 		    case LLC_GSAP|LLC_U_POLL:	f = 'F'; break;
217 		    default:			f = '?'; break;
218 		}
219 
220 		printf("%s/%c", m, f);
221 
222 		if (caplen < 6) {
223 			default_print_unaligned(p, caplen);
224 			return (0);
225 		}
226 		p += 3;
227 		length -= 3;
228 		caplen -= 3;
229 
230 		if ((llc.llcu & ~LLC_U_POLL) == LLC_XID) {
231 		    if (*p == LLC_XID_FI) {
232 			printf(": %02x %02x", p[1], p[2]);
233 			p += 3;
234 			length -= 3;
235 			caplen -= 3;
236 		    }
237 		}
238 
239 #if 0
240 		if (!strcmp(m,"ui") && f=='C') {
241 			/*
242 			 * we don't have a proper ipx decoder yet, but there
243 			 * is a partial one in the smb code
244 			 */
245 			ipx_netbios_print(p,p+min(caplen,length));
246 		}
247 #endif
248 
249 	} else {
250 		char f;
251 		if (caplen < 4) {
252 			default_print_unaligned(p, caplen);
253 			return (0);
254 		}
255 		llc.llcis = ntohs(llc.llcis);
256 		switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
257 		    case 0:			f = 'C'; break;
258 		    case LLC_GSAP:		f = 'R'; break;
259 		    case LLC_U_POLL:		f = 'P'; break;
260 		    case LLC_GSAP|LLC_U_POLL:	f = 'F'; break;
261 		    default:			f = '?'; break;
262 		}
263 
264 		if ((llc.llcu & LLC_S_FMT) == LLC_S_FMT) {
265 			static char *llc_s[] = { "rr", "rej", "rnr", "03" };
266 			(void)printf("%s (r=%d,%c)",
267 				llc_s[LLC_S_CMD(llc.llcis)],
268 				LLC_IS_NR(llc.llcis),
269 				f);
270 		} else {
271 			(void)printf("I (s=%d,r=%d,%c)",
272 				LLC_I_NS(llc.llcis),
273 				LLC_IS_NR(llc.llcis),
274 				f);
275 		}
276 		p += 4;
277 		length -= 4;
278 		caplen -= 4;
279 	}
280 	(void)printf(" len=%d", length);
281 	return(1);
282 }
283