- struct mp_capable *mpc = (struct mp_capable *) opt;
-
- if (mpc->c)
- printf(" csum");
- printf(" {0x%" PRIx64, mpc->sender_key);
- if (opt_len == 20)
- printf(",0x%" PRIx64, mpc->receiver_key);
- printf("}");
+ const struct mp_capable *mpc = (const struct mp_capable *) opt;
+ uint8_t version, csum_enabled;
+
+ if (!((opt_len == 12 || opt_len == 4) && flags & TH_SYN) &&
+ !((opt_len == 20 || opt_len == 22 || opt_len == 24) && (flags & (TH_SYN | TH_ACK)) ==
+ TH_ACK))
+ return 0;
+
+ version = MP_CAPABLE_OPT_VERSION(GET_U_1(mpc->sub_ver));
+ switch (version) {
+ case 0: /* fall through */
+ case 1:
+ ND_PRINT(" v%u", version);
+ break;
+ default:
+ ND_PRINT(" Unknown Version (%u)", version);
+ return 1;
+ }
+
+ ND_PRINT(" flags [%s]", bittok2str_nosep(mp_capable_flags, "none",
+ GET_U_1(mpc->flags)));
+
+ csum_enabled = GET_U_1(mpc->flags) & MP_CAPABLE_A;
+ if (csum_enabled)
+ ND_PRINT(" csum");
+ if (opt_len == 12 || opt_len >= 20) {
+ ND_PRINT(" {0x%" PRIx64, GET_BE_U_8(mpc->sender_key));
+ if (opt_len >= 20)
+ ND_PRINT(",0x%" PRIx64, GET_BE_U_8(mpc->receiver_key));
+
+ /* RFC 8684 Section 3.1 */
+ if ((opt_len == 22 && !csum_enabled) || opt_len == 24)
+ ND_PRINT(",data_len=%u", GET_BE_U_2(mpc->data_len));
+ ND_PRINT("}");
+ }