+ /*
+ * Destination address and PAN ID, if present.
+ */
+ switch (FC_DEST_ADDRESSING_MODE(fc)) {
+ case FC_ADDRESSING_MODE_NONE:
+ if (fc & FC_PAN_ID_COMPRESSION) {
+ /*
+ * PAN ID compression; this requires that both
+ * the source and destination addresses be present,
+ * but the destination address is missing.
+ */
+ nd_print_trunc(ndo);
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
+ ND_PRINT("none ");
+ break;
+ case FC_ADDRESSING_MODE_RESERVED:
+ if (ndo->ndo_vflag)
+ ND_PRINT("reserved destination addressing mode");
+ return hdrlen;
+ case FC_ADDRESSING_MODE_SHORT:
+ if (caplen < 2) {
+ nd_print_trunc(ndo);
+ return hdrlen;
+ }
+ panid = EXTRACT_LE_U_2(p);
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ if (caplen < 2) {
+ nd_print_trunc(ndo);
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
+ ND_PRINT("%04x:%04x ", panid, EXTRACT_LE_U_2(p));
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ break;
+ case FC_ADDRESSING_MODE_LONG:
+ if (caplen < 2) {
+ nd_print_trunc(ndo);
+ return hdrlen;
+ }
+ panid = EXTRACT_LE_U_2(p);
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ if (caplen < 8) {
+ nd_print_trunc(ndo);
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
+ ND_PRINT("%04x:%s ", panid, le64addr_string(ndo, p));
+ p += 8;
+ caplen -= 8;
+ hdrlen += 8;
+ break;
+ }
+ if (ndo->ndo_vflag)
+ ND_PRINT("< ");
+
+ /*
+ * Source address and PAN ID, if present.
+ */
+ switch (FC_SRC_ADDRESSING_MODE(fc)) {
+ case FC_ADDRESSING_MODE_NONE:
+ if (ndo->ndo_vflag)
+ ND_PRINT("none ");
+ break;
+ case FC_ADDRESSING_MODE_RESERVED:
+ if (ndo->ndo_vflag)
+ ND_PRINT("reserved source addressing mode");
+ return 0;
+ case FC_ADDRESSING_MODE_SHORT:
+ if (!(fc & FC_PAN_ID_COMPRESSION)) {
+ /*
+ * The source PAN ID is not compressed out, so
+ * fetch it. (Otherwise, we'll use the destination
+ * PAN ID, fetched above.)
+ */
+ if (caplen < 2) {
+ nd_print_trunc(ndo);
+ return hdrlen;
+ }
+ panid = EXTRACT_LE_U_2(p);
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ }
+ if (caplen < 2) {
+ nd_print_trunc(ndo);
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
+ ND_PRINT("%04x:%04x ", panid, EXTRACT_LE_U_2(p));
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ break;
+ case FC_ADDRESSING_MODE_LONG:
+ if (!(fc & FC_PAN_ID_COMPRESSION)) {
+ /*
+ * The source PAN ID is not compressed out, so
+ * fetch it. (Otherwise, we'll use the destination
+ * PAN ID, fetched above.)
+ */
+ if (caplen < 2) {
+ nd_print_trunc(ndo);
+ return hdrlen;
+ }
+ panid = EXTRACT_LE_U_2(p);
+ p += 2;
+ caplen -= 2;
+ hdrlen += 2;
+ }
+ if (caplen < 8) {
+ nd_print_trunc(ndo);
+ return hdrlen;
+ }
+ if (ndo->ndo_vflag)
+ ND_PRINT("%04x:%s ", panid, le64addr_string(ndo, p));
+ p += 8;
+ caplen -= 8;
+ hdrlen += 8;
+ break;
+ }
+
+ if (!ndo->ndo_suppress_default_print)
+ ND_DEFAULTPRINT(p, caplen);
+
+ return hdrlen;
+}