- } else if (ether_encap_print(ether_type, p, length, caplen,
- &extracted_ether_type) == 0) {
- /* ether_type not known, print raw packet */
- if (!eflag)
- ether_hdr_print((u_char *)ep, length + ETHER_HDRLEN);
-
- if (!xflag && !qflag)
- default_print(p, caplen);
- } else { /* handle the case where we know the ethertype but do not have a printer for it */
- printf("%s, length %u",
- tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ether_type),
- length);
- }
+ hdrlen += llc_hdrlen;
+ } else if (length_type == ETHERTYPE_8021Q ||
+ length_type == ETHERTYPE_8021Q9100 ||
+ length_type == ETHERTYPE_8021Q9200 ||
+ length_type == ETHERTYPE_8021QinQ) {
+ /*
+ * Print VLAN information, and then go back and process
+ * the enclosed type field.
+ */
+ if (caplen < 4) {
+ ndo->ndo_protocol = "vlan";
+ nd_print_trunc(ndo);
+ return (hdrlen + caplen);
+ }
+ if (length < 4) {
+ ndo->ndo_protocol = "vlan";
+ nd_print_trunc(ndo);
+ return (hdrlen + length);
+ }
+ if (ndo->ndo_eflag) {
+ uint16_t tag = EXTRACT_BE_U_2(p);
+
+ ND_PRINT("%s, ", ieee8021q_tci_string(tag));
+ }
+
+ length_type = EXTRACT_BE_U_2(p + 2);
+ if (ndo->ndo_eflag && length_type > MAX_ETHERNET_LENGTH_VAL)
+ ND_PRINT("ethertype %s, ", tok2str(ethertype_values,"0x%04x", length_type));
+ p += 4;
+ length -= 4;
+ caplen -= 4;
+ hdrlen += 4;
+ goto recurse;
+ } else if (length_type == ETHERTYPE_JUMBO) {
+ /*
+ * Alteon jumbo frames.
+ * See
+ *
+ * http://tools.ietf.org/html/draft-ietf-isis-ext-eth-01
+ *
+ * which indicates that, following the type field,
+ * there's an LLC header and payload.
+ */
+ /* Try to print the LLC-layer header & higher layers */
+ llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
+ if (llc_hdrlen < 0) {
+ /* packet type not known, print raw packet */
+ if (!ndo->ndo_suppress_default_print)
+ ND_DEFAULTPRINT(p, caplen);
+ llc_hdrlen = -llc_hdrlen;
+ }
+ hdrlen += llc_hdrlen;
+ } else {
+ if (ethertype_print(ndo, length_type, p, length, caplen, &src, &dst) == 0) {
+ /* type not known, print raw packet */
+ if (!ndo->ndo_eflag) {
+ if (print_encap_header != NULL)
+ (*print_encap_header)(ndo, encap_header_arg);
+ ether_hdr_print(ndo, (const u_char *)ehp, orig_length,
+ hdrlen);
+ }
+
+ if (!ndo->ndo_suppress_default_print)
+ ND_DEFAULTPRINT(p, caplen);
+ }
+ }
+ return (hdrlen);
+}
+
+/*
+ * Print an Ethernet frame.
+ * This might be encapsulated within another frame; we might be passed
+ * a pointer to a function that can print header information for that
+ * frame's protocol, and an argument to pass to that function.
+ *
+ * FIXME: caplen can and should be derived from ndo->ndo_snapend and p.
+ */
+u_int
+ether_print(netdissect_options *ndo,
+ const u_char *p, u_int length, u_int caplen,
+ void (*print_encap_header)(netdissect_options *ndo, const u_char *),
+ const u_char *encap_header_arg)
+{
+ return (ether_print_hdr_len(ndo, p, length, caplen,
+ print_encap_header, encap_header_arg,
+ ETHER_HDRLEN));