+ /* Single-octet IE? */
+ if (IE_IS_SINGLE_OCTET(iecode)) {
+ /*
+ * Yes. Is it a shift?
+ */
+ if (IE_IS_SHIFT(iecode)) {
+ /*
+ * Yes. Is it locking?
+ */
+ if (IE_SHIFT_IS_LOCKING(iecode)) {
+ /*
+ * Yes.
+ */
+ non_locking_shift = 0;
+ } else {
+ /*
+ * No. Remember the current
+ * codeset, so we can revert
+ * to it after the next IE.
+ */
+ non_locking_shift = 1;
+ unshift_codeset = codeset;
+ }
+
+ /*
+ * Get the codeset.
+ */
+ codeset = IE_SHIFT_CODESET(iecode);
+ }
+ } else {
+ /*
+ * No. Get the IE length.
+ */
+ if (length == 0) {
+ if (ndo->ndo_vflag) {
+ ND_PRINT((ndo, "\n"));
+ } else {
+ ND_PRINT((ndo, ", length %u", olen));
+ }
+ goto trunc;
+ }
+ if (!ND_TTEST2(*p, 1)) {
+ if (ndo->ndo_vflag) {
+ ND_PRINT((ndo, "\n"));
+ } else {
+ ND_PRINT((ndo, ", length %u", olen));
+ }
+ goto trunc;
+ }
+ ielength = *p;
+ p++;
+ length--;
+
+ /* lets do the full IE parsing only in verbose mode
+ * however some IEs (DLCI Status, Link Verify)
+ * are also interesting in non-verbose mode */
+ if (ndo->ndo_vflag) {
+ ND_PRINT((ndo, "\n\t%s IE (0x%02x), length %u: ",
+ tok2str(fr_q933_ie_codesets[codeset],
+ "unknown", iecode),
+ iecode,
+ ielength));
+ }
+
+ /* sanity checks */
+ if (iecode == 0 || ielength == 0) {
+ return;
+ }
+ if (length < ielength) {
+ if (!ndo->ndo_vflag) {
+ ND_PRINT((ndo, ", length %u", olen));
+ }
+ goto trunc;
+ }
+ if (!ND_TTEST2(*p, ielength)) {
+ if (!ndo->ndo_vflag) {
+ ND_PRINT((ndo, ", length %u", olen));
+ }
+ goto trunc;
+ }
+
+ ie_is_known = 0;
+ if (fr_q933_print_ie_codeset[codeset] != NULL) {
+ ie_is_known = fr_q933_print_ie_codeset[codeset](ndo, iecode, ielength, p);
+ }
+
+ if (ie_is_known) {
+ /*
+ * Known IE; do we want to see a hexdump
+ * of it?
+ */
+ if (ndo->ndo_vflag > 1) {
+ /* Yes. */
+ print_unknown_data(ndo, p, "\n\t ", ielength);
+ }
+ } else {
+ /*
+ * Unknown IE; if we're printing verbosely,
+ * print its content in hex.
+ */
+ if (ndo->ndo_vflag >= 1) {
+ print_unknown_data(ndo, p, "\n\t", ielength);
+ }
+ }
+
+ length -= ielength;
+ p += ielength;