/* specification: RFC 6824 */
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
#include "netdissect-stdinc.h"
nd_uint8_t sub_etc; /* subtype upper 4 bits, other stuff lower 4 bits */
};
-#define MPTCP_OPT_SUBTYPE(sub_etc) ((GET_U_1(sub_etc) >> 4) & 0xF)
+#define MPTCP_OPT_SUBTYPE(sub_etc) (((sub_etc) >> 4) & 0xF)
struct mp_capable {
nd_uint8_t kind;
nd_uint64_t receiver_key;
};
-#define MP_CAPABLE_OPT_VERSION(sub_ver) ((GET_U_1(sub_ver) >> 0) & 0xF)
+#define MP_CAPABLE_OPT_VERSION(sub_ver) (((sub_ver) >> 0) & 0xF)
#define MP_CAPABLE_C 0x80
#define MP_CAPABLE_S 0x01
#define MP_DSS_a 0x02
#define MP_DSS_A 0x01
+static const struct tok mptcp_addr_subecho_bits[] = {
+ { 0x6, "v0-ip6" },
+ { 0x4, "v0-ip4" },
+ { 0x1, "v1-echo" },
+ { 0x0, "v1" },
+ { 0, NULL }
+};
+
struct mp_add_addr {
nd_uint8_t kind;
nd_uint8_t len;
const u_char *opt, u_int opt_len, u_char flags)
{
const struct mp_capable *mpc = (const struct mp_capable *) opt;
+ uint8_t version;
if (!((opt_len == 12 || opt_len == 4) && flags & TH_SYN) &&
!((opt_len == 20 || opt_len == 22) && (flags & (TH_SYN | TH_ACK)) ==
TH_ACK))
return 0;
- switch (MP_CAPABLE_OPT_VERSION(mpc->sub_ver)) {
+ version = MP_CAPABLE_OPT_VERSION(GET_U_1(mpc->sub_ver));
+ switch (version) {
case 0: /* fall through */
case 1:
- ND_PRINT(" v%d", MP_CAPABLE_OPT_VERSION(mpc->sub_ver));
+ ND_PRINT(" v%u", version);
break;
default:
- ND_PRINT(" Unknown Version (%d)",
- MP_CAPABLE_OPT_VERSION(mpc->sub_ver));
+ ND_PRINT(" Unknown Version (%u)", version);
return 1;
}
* Data-Level Length present, and Checksum possibly present.
*/
ND_PRINT(" seq ");
- /*
+ /*
* If the m flag is set, we have an 8-byte NDS; if it's clear,
* we have a 4-byte DSN.
*/
opt_len == 20 || opt_len == 22 || opt_len == 28 || opt_len == 30))
return 0;
+ ND_PRINT(" %s",
+ tok2str(mptcp_addr_subecho_bits, "[bad version/echo]",
+ GET_U_1(add_addr->sub_echo) & 0xF));
ND_PRINT(" id %u", GET_U_1(add_addr->addr_id));
if (opt_len == 8 || opt_len == 10 || opt_len == 16 || opt_len == 18) {
ND_PRINT(" %s", GET_IPADDR_STRING(add_addr->u.v4.addr));
const u_char *opt, u_int opt_len, u_char flags _U_)
{
const struct mp_remove_addr *remove_addr = (const struct mp_remove_addr *) opt;
- u_int i;
+ u_int i;
if (opt_len < 4)
return 0;
const char *name;
int (*print)(netdissect_options *, const u_char *, u_int, u_char);
} mptcp_options[] = {
- { "capable", mp_capable_print},
+ { "capable", mp_capable_print },
{ "join", mp_join_print },
{ "dss", mp_dss_print },
{ "add-addr", add_addr_print },
const struct mptcp_option *opt;
u_int subtype;
- ndo->ndo_protocol = "mptcp";
+ ndo->ndo_protocol = "mptcp";
if (len < 3)
return 0;
opt = (const struct mptcp_option *) cp;
- ND_TCHECK_SIZE(opt);
- subtype = min(MPTCP_OPT_SUBTYPE(opt->sub_etc), MPTCP_SUB_FCLOSE + 1);
+ subtype = MPTCP_OPT_SUBTYPE(GET_U_1(opt->sub_etc));
+ subtype = ND_MIN(subtype, MPTCP_SUB_FCLOSE + 1);
+
+ ND_PRINT(" %u", len);
ND_PRINT(" %s", mptcp_options[subtype].name);
return mptcp_options[subtype].print(ndo, cp, len, flags);
-
-trunc:
- nd_print_trunc(ndo);
- return 0;
}