+ } else {
+ ND_PRINT("ethertype %s (0x%04x)",
+ tok2str(ethertype_values, "Unknown", ether_type),
+ ether_type);
+ }
+ ND_PRINT(", length %u: ", length);
+ }
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points to the
+ * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ *
+ * On Linux, we attempt to look up the interface index and print the
+ * name of the interface on which the packet arrived or was sent.
+ *
+ * This look up is only likely to work well if done on the same machine
+ * as the one on which the capture was done, as the interface with a
+ * given index on the latter machine is unlikely to have the same
+ * name as the interface with that index on the former machine.
+ *
+ * As DLT_LINUX_SLL2 live captures are supported only on Linux, this
+ * means that if the machine on which we're reading the file isn't
+ * running Linux, it's probably not the machine that captured the file,
+ * so we don't bother trying to do the lookup on non-Linux machines.
+ */
+void
+sll2_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int caplen = h->caplen;
+ u_int length = h->len;
+ const struct sll2_header *sllp;
+ u_short hatype;
+ u_short ether_type;
+ int llc_hdrlen;
+ u_int hdrlen;
+#ifdef __linux__
+ uint32_t if_index;
+ char ifname[IF_NAMESIZE];
+#endif
+
+ ndo->ndo_protocol = "sll2";
+ ND_TCHECK_LEN(p, SLL2_HDR_LEN);
+
+ sllp = (const struct sll2_header *)p;
+#ifdef __linux__
+ if_index = GET_BE_U_4(sllp->sll2_if_index);
+ if (!if_indextoname(if_index, ifname))
+ strncpy(ifname, "?", 2);
+ ND_PRINT("%-5s ", ifname);
+#endif
+
+ ND_PRINT("%-3s ",
+ tok2str(sll_pkttype_values, "?", GET_U_1(sllp->sll2_pkttype)));
+
+ if (ndo->ndo_eflag)
+ sll2_print(ndo, sllp, length);
+
+ /*
+ * Go past the cooked-mode header.
+ */
+ length -= SLL2_HDR_LEN;
+ caplen -= SLL2_HDR_LEN;
+ p += SLL2_HDR_LEN;
+ hdrlen = SLL2_HDR_LEN;
+
+ hatype = GET_BE_U_2(sllp->sll2_hatype);
+ switch (hatype) {
+
+ case 803:
+ /*
+ * This is an packet with a radiotap header;
+ * just dissect the payload as such.
+ */
+ ndo->ndo_ll_hdr_len += SLL2_HDR_LEN;
+ ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen);
+ return;
+ }
+ ether_type = GET_BE_U_2(sllp->sll2_protocol);
+
+recurse:
+ /*
+ * Is it (gag) an 802.3 encapsulation, or some non-Ethernet
+ * packet type?
+ */
+ if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
+ /*
+ * Yes - what type is it?
+ */
+ switch (ether_type) {
+
+ case LINUX_SLL_P_802_3:
+ /*
+ * Ethernet_802.3 IPX frame.
+ */
+ ipx_print(ndo, p, length);
+ break;
+
+ case LINUX_SLL_P_802_2:
+ /*
+ * 802.2.
+ * Try to print the LLC-layer header & higher layers.
+ */
+ llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
+ if (llc_hdrlen < 0)
+ goto unknown; /* unknown LLC type */
+ hdrlen += llc_hdrlen;
+ break;
+
+ default:
+ /*FALLTHROUGH*/
+
+ unknown:
+ /* packet type not known, print raw packet */
+ if (!ndo->ndo_suppress_default_print)
+ ND_DEFAULTPRINT(p, caplen);