summaryrefslogtreecommitdiffstats
path: root/print-bcm-li.c
diff options
context:
space:
mode:
Diffstat (limited to 'print-bcm-li.c')
-rw-r--r--print-bcm-li.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/print-bcm-li.c b/print-bcm-li.c
new file mode 100644
index 0000000..12b1ebb
--- /dev/null
+++ b/print-bcm-li.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* \summary: Broadcom LI Printer */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "netdissect-stdinc.h"
+
+#define ND_LONGJMP_FROM_TCHECK
+#include "netdissect.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#define BCM_LI_SHIM_LEN 4
+
+static const struct tok bcm_li_direction_values[] = {
+ { 1, "unused" },
+ { 2, "egress" },
+ { 3, "ingress" },
+ { 0, NULL}
+};
+
+#define BCM_LI_PKT_TYPE_UNDECIDED 4
+#define BCM_LI_PKT_TYPE_IPV4 5
+#define BCM_LI_PKT_TYPE_IPV6 6
+#define BCM_LI_PKT_TYPE_ETHERNET 7
+
+static const struct tok bcm_li_pkt_type_values[] = {
+ { BCM_LI_PKT_TYPE_UNDECIDED, "undecided" },
+ { BCM_LI_PKT_TYPE_IPV4, "ipv4" },
+ { BCM_LI_PKT_TYPE_IPV6, "ipv6" },
+ { BCM_LI_PKT_TYPE_ETHERNET, "ethernet" },
+ { 0, NULL}
+};
+
+static const struct tok bcm_li_pkt_subtype_values[] = {
+ { 1, "single VLAN tag" },
+ { 2, "double VLAN tag" },
+ { 3, "untagged" },
+ { 0, NULL}
+};
+
+void
+bcm_li_print(netdissect_options *ndo,
+ const u_char *bp, u_int length)
+{
+ u_int shim, direction, pkt_type, pkt_subtype, li_id;
+
+ ndo->ndo_protocol = "bcm_li";
+ if (length < BCM_LI_SHIM_LEN) {
+ ND_PRINT(" (length %u < %u)", length, BCM_LI_SHIM_LEN);
+ goto invalid;
+ }
+ shim = GET_BE_U_4(bp);
+
+ direction = (shim >> 29) & 0x7;
+ pkt_type = (shim >> 25) & 0xf;
+ pkt_subtype = (shim >> 22) & 0x7;
+ li_id = shim & 0x3fffff;
+
+ length -= BCM_LI_SHIM_LEN;
+ bp += BCM_LI_SHIM_LEN;
+
+ ND_PRINT("%sBCM-LI-SHIM: direction %s, pkt-type %s, pkt-subtype %s, li-id %u%s",
+ ndo->ndo_vflag ? "\n " : "",
+ tok2str(bcm_li_direction_values, "unknown", direction),
+ tok2str(bcm_li_pkt_type_values, "unknown", pkt_type),
+ tok2str(bcm_li_pkt_subtype_values, "unknown", pkt_subtype),
+ li_id,
+ ndo->ndo_vflag ? "\n ": "");
+
+ if (!ndo->ndo_vflag) {
+ ND_TCHECK_LEN(bp, length);
+ return;
+ }
+
+ switch (pkt_type) {
+ case BCM_LI_PKT_TYPE_ETHERNET:
+ ether_print(ndo, bp, length, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL);
+ break;
+ case BCM_LI_PKT_TYPE_IPV4:
+ ip_print(ndo, bp, length);
+ break;
+ case BCM_LI_PKT_TYPE_IPV6:
+ ip6_print(ndo, bp, length);
+ break;
+ case BCM_LI_PKT_TYPE_UNDECIDED:
+
+ /*
+ * Guess IP version from first nibble.
+ */
+ if ((GET_U_1(bp) >> 4) == 4) {
+ ip_print(ndo, bp, length);
+ } else if ((GET_U_1(bp) >> 4) == 6) {
+ ip6_print(ndo, bp, length);
+ } else {
+ ND_PRINT("unknown payload");
+ }
+ break;
+
+ default:
+ goto invalid;
+ }
+
+ return;
+invalid:
+ nd_print_invalid(ndo);
+}
+