print-llc.c revision 17680
1/*
2 * Copyright (c) 1992, 1993, 1994, 1995, 1996
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
22/*
23 * Code by Matt Thomas, Digital Equipment Corporation
24 *	with an awful lot of hacking by Jeffrey Mogul, DECWRL
25 */
26
27#ifndef lint
28static  char rcsid[] =
29	"@(#)$Header: print-llc.c,v 1.20 96/07/23 14:17:25 leres Exp $";
30#endif
31
32#include <sys/param.h>
33#include <sys/time.h>
34
35#include <netinet/in.h>
36
37#include <ctype.h>
38#include <netdb.h>
39#include <signal.h>
40#include <stdio.h>
41#include <string.h>
42
43#include "interface.h"
44#include "addrtoname.h"
45#include "extract.h"			/* must come after interface.h */
46
47#include "llc.h"
48
49static struct tok cmd2str[] = {
50	{ LLC_UI,	"ui" },
51	{ LLC_TEST,	"test" },
52	{ LLC_XID,	"xid" },
53	{ LLC_UA,	"ua" },
54	{ LLC_DISC,	"disc" },
55	{ LLC_DM,	"dm" },
56	{ LLC_SABME,	"sabme" },
57	{ LLC_FRMR,	"frmr" },
58	{ 0,		NULL }
59};
60
61/*
62 * Returns non-zero IFF it succeeds in printing the header
63 */
64int
65llc_print(const u_char *p, u_int length, u_int caplen,
66	  const u_char *esrc, const u_char *edst)
67{
68	struct llc llc;
69	register u_short et;
70	register int ret;
71
72	if (caplen < 3) {
73		(void)printf("[|llc]");
74		default_print((u_char *)p, caplen);
75		return(0);
76	}
77
78	/* Watch out for possible alignment problems */
79	memcpy((char *)&llc, (char *)p, min(caplen, sizeof(llc)));
80
81	if (llc.ssap == LLCSAP_GLOBAL && llc.dsap == LLCSAP_GLOBAL) {
82		ipx_print(p, length);
83		return (1);
84	}
85#ifdef notyet
86	else if (p[0] == 0xf0 && p[1] == 0xf0)
87		netbios_print(p, length);
88#endif
89	if (llc.ssap == LLCSAP_ISONS && llc.dsap == LLCSAP_ISONS
90	    && llc.llcui == LLC_UI) {
91		isoclns_print(p + 3, length - 3, caplen - 3, esrc, edst);
92		return (1);
93	}
94
95	if (llc.ssap == LLCSAP_SNAP && llc.dsap == LLCSAP_SNAP
96	    && llc.llcui == LLC_UI) {
97		if (caplen < sizeof(llc)) {
98		    (void)printf("[|llc-snap]");
99		    default_print((u_char *)p, caplen);
100		    return (0);
101		}
102		if (vflag)
103			(void)printf("snap %s ", protoid_string(llc.llcpi));
104
105		caplen -= sizeof(llc);
106		length -= sizeof(llc);
107		p += sizeof(llc);
108
109		/* This is an encapsulated Ethernet packet */
110		et = EXTRACT_16BITS(&llc.ethertype[0]);
111		ret = ether_encap_print(et, p, length, caplen);
112		if (ret)
113			return (ret);
114	}
115
116	if ((llc.ssap & ~LLC_GSAP) == llc.dsap) {
117		if (eflag)
118			(void)printf("%s ", llcsap_string(llc.dsap));
119		else
120			(void)printf("%s > %s %s ",
121					etheraddr_string(esrc),
122					etheraddr_string(edst),
123					llcsap_string(llc.dsap));
124	} else {
125		if (eflag)
126			(void)printf("%s > %s ",
127				llcsap_string(llc.ssap & ~LLC_GSAP),
128				llcsap_string(llc.dsap));
129		else
130			(void)printf("%s %s > %s %s ",
131				etheraddr_string(esrc),
132				llcsap_string(llc.ssap & ~LLC_GSAP),
133				etheraddr_string(edst),
134				llcsap_string(llc.dsap));
135	}
136
137	if ((llc.llcu & LLC_U_FMT) == LLC_U_FMT) {
138		const char *m;
139		char f;
140		m = tok2str(cmd2str, "%02x", LLC_U_CMD(llc.llcu));
141		switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
142		    case 0:			f = 'C'; break;
143		    case LLC_GSAP:		f = 'R'; break;
144		    case LLC_U_POLL:		f = 'P'; break;
145		    case LLC_GSAP|LLC_U_POLL:	f = 'F'; break;
146		    default:			f = '?'; break;
147		}
148
149		printf("%s/%c", m, f);
150
151		p += 3;
152		length -= 3;
153		caplen -= 3;
154
155		if ((llc.llcu & ~LLC_U_POLL) == LLC_XID) {
156		    if (*p == LLC_XID_FI) {
157			printf(": %02x %02x", p[1], p[2]);
158			p += 3;
159			length -= 3;
160			caplen -= 3;
161		    }
162		}
163	} else {
164		char f;
165		llc.llcis = ntohs(llc.llcis);
166		switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
167		    case 0:			f = 'C'; break;
168		    case LLC_GSAP:		f = 'R'; break;
169		    case LLC_U_POLL:		f = 'P'; break;
170		    case LLC_GSAP|LLC_U_POLL:	f = 'F'; break;
171		    default:			f = '?'; break;
172		}
173
174		if ((llc.llcu & LLC_S_FMT) == LLC_S_FMT) {
175			static char *llc_s[] = { "rr", "rej", "rnr", "03" };
176			(void)printf("%s (r=%d,%c)",
177				llc_s[LLC_S_CMD(llc.llcis)],
178				LLC_IS_NR(llc.llcis),
179				f);
180		} else {
181			(void)printf("I (s=%d,r=%d,%c)",
182				LLC_I_NS(llc.llcis),
183				LLC_IS_NR(llc.llcis),
184				f);
185		}
186		p += 4;
187		length -= 4;
188		caplen -= 4;
189	}
190	(void)printf(" len=%d", length);
191	if (caplen > 0) {
192		default_print_unaligned(p, caplen);
193	}
194	return(1);
195}
196