+ospf_decode_lls(netdissect_options *ndo,
+ register const struct ospfhdr *op, register u_int length)
+{
+ register const u_char *dptr;
+ register const u_char *dataend;
+ register u_int length2;
+ register uint16_t lls_type, lls_len;
+ register uint32_t lls_flags;
+
+ switch (op->ospf_type) {
+
+ case OSPF_TYPE_HELLO:
+ if (!(op->ospf_hello.hello_options & OSPF_OPTION_L))
+ return (0);
+ break;
+
+ case OSPF_TYPE_DD:
+ if (!(op->ospf_db.db_options & OSPF_OPTION_L))
+ return (0);
+ break;
+
+ default:
+ return (0);
+ }
+
+ /* dig deeper if LLS data is available; see RFC4813 */
+ length2 = EXTRACT_16BITS(&op->ospf_len);
+ dptr = (u_char *)op + length2;
+ dataend = (u_char *)op + length;
+
+ if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) {
+ dptr = dptr + op->ospf_authdata[3];
+ length2 += op->ospf_authdata[3];
+ }
+ if (length2 >= length) {
+ ND_PRINT((ndo, "\n\t[LLS truncated]"));
+ return (1);
+ }
+ ND_TCHECK2(*dptr, 2);
+ ND_PRINT((ndo, "\n\t LLS: checksum: 0x%04x", (u_int)EXTRACT_16BITS(dptr)));
+
+ dptr += 2;
+ ND_TCHECK2(*dptr, 2);
+ length2 = EXTRACT_16BITS(dptr);
+ ND_PRINT((ndo, ", length: %u", length2));
+
+ dptr += 2;
+ ND_TCHECK(*dptr);
+ while (dptr < dataend) {
+ ND_TCHECK2(*dptr, 2);
+ lls_type = EXTRACT_16BITS(dptr);
+ ND_PRINT((ndo, "\n\t %s (%u)",
+ tok2str(ospf_lls_tlv_values,"Unknown TLV",lls_type),
+ lls_type));
+ dptr += 2;
+ ND_TCHECK2(*dptr, 2);
+ lls_len = EXTRACT_16BITS(dptr);
+ ND_PRINT((ndo, ", length: %u", lls_len));
+ dptr += 2;
+ switch (lls_type) {
+
+ case OSPF_LLS_EO:
+ if (lls_len != 4) {
+ ND_PRINT((ndo, " [should be 4]"));
+ lls_len = 4;
+ }
+ ND_TCHECK2(*dptr, 4);
+ lls_flags = EXTRACT_32BITS(dptr);
+ ND_PRINT((ndo, "\n\t Options: 0x%08x [%s]", lls_flags,
+ bittok2str(ospf_lls_eo_options, "?", lls_flags)));
+
+ break;
+
+ case OSPF_LLS_MD5:
+ if (lls_len != 20) {
+ ND_PRINT((ndo, " [should be 20]"));
+ lls_len = 20;
+ }
+ ND_TCHECK2(*dptr, 4);
+ ND_PRINT((ndo, "\n\t Sequence number: 0x%08x", EXTRACT_32BITS(dptr)));
+ break;
+ }
+
+ dptr += lls_len;
+ }
+
+ return (0);
+trunc:
+ return (1);
+}
+
+static int
+ospf_decode_v2(netdissect_options *ndo,
+ register const struct ospfhdr *op, register const u_char *dataend)