summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--llc.h16
-rw-r--r--print-llc.c56
2 files changed, 44 insertions, 28 deletions
diff --git a/llc.h b/llc.h
index b58324b5..d993a6a0 100644
--- a/llc.h
+++ b/llc.h
@@ -18,7 +18,7 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * @(#) $Header: /tcpdump/master/tcpdump/llc.h,v 1.7 2000-10-03 02:54:57 itojun Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/llc.h,v 1.8 2000-12-18 07:55:36 guy Exp $ (LBL)
*/
/*
@@ -61,7 +61,7 @@ struct llc {
#define LLC_S_FMT 1
#define LLC_U_POLL 0x10
-#define LLC_IS_POLL 0x0001
+#define LLC_IS_POLL 0x0100
#define LLC_XID_FI 0x81
#define LLC_U_CMD(u) ((u) & 0xef)
@@ -74,13 +74,13 @@ struct llc {
#define LLC_XID 0xaf
#define LLC_FRMR 0x87
-#define LLC_S_CMD(is) (((is) >> 10) & 0x03)
-#define LLC_RR 0x0100
-#define LLC_RNR 0x0500
-#define LLC_REJ 0x0900
+#define LLC_S_CMD(is) (((is) >> 1) & 0x03)
+#define LLC_RR 0x0001
+#define LLC_RNR 0x0005
+#define LLC_REJ 0x0009
-#define LLC_IS_NR(is) (((is) >> 1) & 0x7f)
-#define LLC_I_NS(is) (((is) >> 9) & 0x7f)
+#define LLC_IS_NR(is) (((is) >> 9) & 0x7f)
+#define LLC_I_NS(is) (((is) >> 1) & 0x7f)
#ifndef LLCSAP_NULL
#define LLCSAP_NULL 0x00
diff --git a/print-llc.c b/print-llc.c
index 6e757714..2e30d8b4 100644
--- a/print-llc.c
+++ b/print-llc.c
@@ -24,7 +24,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-llc.c,v 1.31 2000-12-18 05:42:00 guy Exp $";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-llc.c,v 1.32 2000-12-18 07:55:36 guy Exp $";
#endif
#ifdef HAVE_CONFIG_H
@@ -68,7 +68,7 @@ llc_print(const u_char *p, u_int length, u_int caplen,
{
struct llc llc;
register u_short et;
- u_short control;
+ u_int16_t control;
register int ret;
if (caplen < 3) {
@@ -97,11 +97,17 @@ llc_print(const u_char *p, u_int length, u_int caplen,
stp_print(p, length);
return (1);
}
- if (llc.ssap == 0xf0 && llc.dsap == 0xf0) {
+ if (llc.ssap == 0xf0 && llc.dsap == 0xf0
+ && (!(llc.llcu & LLC_S_FMT) || llc.llcu == LLC_U_FMT)) {
/*
* we don't actually have a full netbeui parser yet, but the
* smb parser can handle many smb-in-netbeui packets, which
* is very useful, so we call that
+ *
+ * We don't call it for S frames, however, just I frames
+ * (which are frames that don't have the low-order bit,
+ * LLC_S_FMT, set in the first byte of the control field)
+ * and UI frames (whose control field is just 3, LLC_U_FMT).
*/
/*
@@ -113,17 +119,21 @@ llc_print(const u_char *p, u_int length, u_int caplen,
/*
* OK, what type of LLC frame is this? The length
- * of the control field depends on that - S or I
- * frames have a two-byte control field, and U frames
- * have a one-byte control field.
+ * of the control field depends on that - I frames
+ * have a two-byte control field, and U frames have
+ * a one-byte control field.
*/
- if ((llc.llcu & LLC_U_FMT) == LLC_U_FMT) {
+ if (llc.llcu == LLC_U_FMT) {
control = llc.llcu;
p += 1;
length -= 1;
caplen -= 1;
} else {
- control = llc.llcis;
+ /*
+ * The control field in I and S frames is
+ * little-endian.
+ */
+ control = EXTRACT_LE_16BITS(&llc.llcu);
p += 2;
length -= 2;
caplen -= 2;
@@ -181,9 +191,12 @@ llc_print(const u_char *p, u_int length, u_int caplen,
}
if ((llc.llcu & LLC_U_FMT) == LLC_U_FMT) {
+ u_int16_t cmd;
const char *m;
char f;
- m = tok2str(cmd2str, "%02x", LLC_U_CMD(llc.llcu));
+
+ cmd = LLC_U_CMD(llc.llcu);
+ m = tok2str(cmd2str, "%02x", cmd);
switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
case 0: f = 'C'; break;
case LLC_GSAP: f = 'R'; break;
@@ -207,35 +220,38 @@ llc_print(const u_char *p, u_int length, u_int caplen,
}
}
- if (!strcmp(m,"ui") && f=='C') {
+ if (cmd == LLC_UI && f == 'C') {
/*
* we don't have a proper ipx decoder yet, but there
* is a partial one in the smb code
*/
ipx_netbios_print(p,p+min(caplen,length));
}
-
} else {
char f;
- llc.llcis = ntohs(llc.llcis);
- switch ((llc.ssap & LLC_GSAP) | (llc.llcu & LLC_U_POLL)) {
+
+ /*
+ * The control field in I and S frames is little-endian.
+ */
+ control = EXTRACT_LE_16BITS(&llc.llcu);
+ switch ((llc.ssap & LLC_GSAP) | (control & LLC_IS_POLL)) {
case 0: f = 'C'; break;
case LLC_GSAP: f = 'R'; break;
- case LLC_U_POLL: f = 'P'; break;
- case LLC_GSAP|LLC_U_POLL: f = 'F'; break;
+ case LLC_IS_POLL: f = 'P'; break;
+ case LLC_GSAP|LLC_IS_POLL: f = 'F'; break;
default: f = '?'; break;
}
- if ((llc.llcu & LLC_S_FMT) == LLC_S_FMT) {
+ if ((control & LLC_S_FMT) == LLC_S_FMT) {
static char *llc_s[] = { "rr", "rej", "rnr", "03" };
(void)printf("%s (r=%d,%c)",
- llc_s[LLC_S_CMD(llc.llcis)],
- LLC_IS_NR(llc.llcis),
+ llc_s[LLC_S_CMD(control)],
+ LLC_IS_NR(control),
f);
} else {
(void)printf("I (s=%d,r=%d,%c)",
- LLC_I_NS(llc.llcis),
- LLC_IS_NR(llc.llcis),
+ LLC_I_NS(control),
+ LLC_IS_NR(control),
f);
}
p += 4;