Index: head/lib/libipsec/pfkey.c =================================================================== --- head/lib/libipsec/pfkey.c +++ head/lib/libipsec/pfkey.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -69,6 +70,7 @@ u_int, u_int32_t, pid_t); static caddr_t pfkey_setsadbsa(caddr_t, caddr_t, u_int32_t, u_int, u_int, u_int, u_int32_t); +static caddr_t pfkey_setsadbxreplay(caddr_t, caddr_t, uint32_t); static caddr_t pfkey_setsadbaddr(caddr_t, caddr_t, u_int, struct sockaddr *, u_int, u_int); static caddr_t pfkey_setsadbkey(caddr_t, caddr_t, u_int, caddr_t, u_int); @@ -1196,6 +1198,13 @@ + sizeof(struct sadb_lifetime) + sizeof(struct sadb_lifetime); + if (wsize > UINT8_MAX) { + if (wsize > (UINT32_MAX - 32) >> 3) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return (-1); + } + len += sizeof(struct sadb_x_sa_replay); + } if (e_type != SADB_EALG_NONE) len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen)); if (a_type != SADB_AALG_NONE) @@ -1223,6 +1232,13 @@ free(newmsg); return -1; } + if (wsize > UINT8_MAX) { + p = pfkey_setsadbxreplay(p, ep, wsize); + if (!p) { + free(newmsg); + return (-1); + } + } p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen, IPSEC_ULPROTO_ANY); if (!p) { @@ -1982,7 +1998,7 @@ p->sadb_sa_len = PFKEY_UNIT64(len); p->sadb_sa_exttype = SADB_EXT_SA; p->sadb_sa_spi = spi; - p->sadb_sa_replay = wsize; + p->sadb_sa_replay = wsize > UINT8_MAX ? UINT8_MAX: wsize; p->sadb_sa_state = SADB_SASTATE_LARVAL; p->sadb_sa_auth = auth; p->sadb_sa_encrypt = enc; @@ -1992,6 +2008,31 @@ } /* + * Set data into sadb_x_sa_replay. + * `buf' must has been allocated sufficiently. + */ +static caddr_t +pfkey_setsadbxreplay(caddr_t buf, caddr_t lim, uint32_t wsize) +{ + struct sadb_x_sa_replay *p; + u_int len; + + p = (struct sadb_x_sa_replay *)buf; + len = sizeof(struct sadb_x_sa_replay); + + if (buf + len > lim) + return (NULL); + + memset(p, 0, len); + p->sadb_x_sa_replay_len = PFKEY_UNIT64(len); + p->sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY; + /* Convert wsize from bytes to number of packets. */ + p->sadb_x_sa_replay_replay = wsize << 3; + + return (buf + len); +} + +/* * set data into sadb_address. * `buf' must has been allocated sufficiently. * prefixlen is in bits. Index: head/sbin/setkey/Makefile =================================================================== --- head/sbin/setkey/Makefile +++ head/sbin/setkey/Makefile @@ -51,6 +51,9 @@ SRCS+= y.tab.h y.tab.h: parse.y CFLAGS+= -DIPSEC_DEBUG -DYY_NO_UNPUT +.if ${MK_INET_SUPPORT} != "no" +CFLAGS+= -DINET +.endif .if ${MK_INET6_SUPPORT} != "no" CFLAGS+= -DINET6 .endif Index: head/sbin/setkey/parse.y =================================================================== --- head/sbin/setkey/parse.y +++ head/sbin/setkey/parse.y @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -513,6 +514,8 @@ return -1; } p_replay = $2; + if (p_replay > (UINT32_MAX - 32) >> 3) + yyerror("replay window is too large"); } | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } @@ -899,6 +902,7 @@ int l, l0, len; struct sadb_sa m_sa; struct sadb_x_sa2 m_sa2; + struct sadb_x_sa_replay m_replay; struct sadb_address m_addr; struct addrinfo *s, *d; int n; @@ -920,7 +924,8 @@ m_sa.sadb_sa_len = PFKEY_UNIT64(len); m_sa.sadb_sa_exttype = SADB_EXT_SA; m_sa.sadb_sa_spi = htonl(p_spi); - m_sa.sadb_sa_replay = p_replay; + m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX: + p_replay; m_sa.sadb_sa_state = 0; m_sa.sadb_sa_auth = p_alg_auth; m_sa.sadb_sa_encrypt = p_alg_enc; @@ -937,6 +942,17 @@ memcpy(buf + l, &m_sa2, len); l += len; + + if (p_replay > UINT8_MAX) { + len = sizeof(struct sadb_x_sa_replay); + m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len); + m_replay.sadb_x_sa_replay_exttype = + SADB_X_EXT_SA_REPLAY; + m_replay.sadb_x_sa_replay_replay = p_replay << 3; + + memcpy(buf + l, &m_replay, len); + l += len; + } } l0 = l; @@ -1017,6 +1033,7 @@ struct sadb_sa m_sa; struct sadb_x_sa2 m_sa2; struct sadb_address m_addr; + struct sadb_x_sa_replay m_replay; struct addrinfo *s, *d; int n; int plen; @@ -1100,7 +1117,7 @@ m_sa.sadb_sa_len = PFKEY_UNIT64(len); m_sa.sadb_sa_exttype = SADB_EXT_SA; m_sa.sadb_sa_spi = htonl(p_spi); - m_sa.sadb_sa_replay = p_replay; + m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX: p_replay; m_sa.sadb_sa_state = 0; m_sa.sadb_sa_auth = p_alg_auth; m_sa.sadb_sa_encrypt = p_alg_enc; @@ -1118,6 +1135,15 @@ memcpy(buf + l, &m_sa2, len); l += len; + if (p_replay > UINT8_MAX) { + len = sizeof(struct sadb_x_sa_replay); + m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len); + m_replay.sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY; + m_replay.sadb_x_sa_replay_replay = p_replay << 3; + + memcpy(buf + l, &m_replay, len); + l += len; + } l0 = l; n = 0; Index: head/sys/netipsec/key_debug.c =================================================================== --- head/sys/netipsec/key_debug.c +++ head/sys/netipsec/key_debug.c @@ -63,6 +63,7 @@ #include #include #include +#include #endif /* !_KERNEL */ static void kdebug_sadb_prop(struct sadb_ext *); @@ -73,6 +74,8 @@ static void kdebug_sadb_address(struct sadb_ext *); static void kdebug_sadb_key(struct sadb_ext *); static void kdebug_sadb_x_sa2(struct sadb_ext *); +static void kdebug_sadb_x_sa_replay(struct sadb_ext *); +static void kdebug_sadb_x_natt(struct sadb_ext *); #ifdef _KERNEL static void kdebug_secreplay(struct secreplay *); @@ -131,6 +134,10 @@ case SADB_EXT_ADDRESS_SRC: case SADB_EXT_ADDRESS_DST: case SADB_EXT_ADDRESS_PROXY: + case SADB_X_EXT_NAT_T_OAI: + case SADB_X_EXT_NAT_T_OAR: + case SADB_X_EXT_NEW_ADDRESS_SRC: + case SADB_X_EXT_NEW_ADDRESS_DST: kdebug_sadb_address(ext); break; case SADB_EXT_KEY_AUTH: @@ -159,6 +166,14 @@ case SADB_X_EXT_SA2: kdebug_sadb_x_sa2(ext); break; + case SADB_X_EXT_SA_REPLAY: + kdebug_sadb_x_sa_replay(ext); + break; + case SADB_X_EXT_NAT_T_TYPE: + case SADB_X_EXT_NAT_T_SPORT: + case SADB_X_EXT_NAT_T_DPORT: + kdebug_sadb_x_natt(ext); + break; default: printf("%s: invalid ext_type %u\n", __func__, ext->sadb_ext_type); @@ -342,8 +357,6 @@ ((u_char *)&addr->sadb_address_reserved)[1]); kdebug_sockaddr((struct sockaddr *)((caddr_t)ext + sizeof(*addr))); - - return; } static void @@ -392,6 +405,41 @@ return; } +static void +kdebug_sadb_x_sa_replay(struct sadb_ext *ext) +{ + struct sadb_x_sa_replay *replay; + + /* sanity check */ + if (ext == NULL) + panic("%s: NULL pointer was passed.\n", __func__); + + replay = (struct sadb_x_sa_replay *)ext; + printf("sadb_x_sa_replay{ replay=%u }\n", + replay->sadb_x_sa_replay_replay); +} + +static void +kdebug_sadb_x_natt(struct sadb_ext *ext) +{ + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *port; + + /* sanity check */ + if (ext == NULL) + panic("%s: NULL pointer was passed.\n", __func__); + + if (ext->sadb_ext_type == SADB_X_EXT_NAT_T_TYPE) { + type = (struct sadb_x_nat_t_type *)ext; + printf("sadb_x_nat_t_type{ type=%u }\n", + type->sadb_x_nat_t_type_type); + } else { + port = (struct sadb_x_nat_t_port *)ext; + printf("sadb_x_nat_t_port{ port=%u }\n", + ntohs(port->sadb_x_nat_t_port_port)); + } +} + void kdebug_sadb_x_policy(struct sadb_ext *ext) { @@ -402,9 +450,11 @@ if (ext == NULL) panic("%s: NULL pointer was passed.\n", __func__); - printf("sadb_x_policy{ type=%u dir=%u id=%x }\n", + printf("sadb_x_policy{ type=%u dir=%u id=%x scope=%u %s=%u }\n", xpl->sadb_x_policy_type, xpl->sadb_x_policy_dir, - xpl->sadb_x_policy_id); + xpl->sadb_x_policy_id, xpl->sadb_x_policy_scope, + xpl->sadb_x_policy_scope == IPSEC_POLICYSCOPE_IFNET ? + "ifindex": "priority", xpl->sadb_x_policy_priority); if (xpl->sadb_x_policy_type == IPSEC_POLICY_IPSEC) { int tlen; @@ -850,39 +900,42 @@ void kdebug_sockaddr(struct sockaddr *addr) { - struct sockaddr_in *sin4; -#ifdef INET6 - struct sockaddr_in6 *sin6; -#endif + char buf[IPSEC_ADDRSTRLEN]; /* sanity check */ if (addr == NULL) panic("%s: NULL pointer was passed.\n", __func__); - /* NOTE: We deal with port number as host byte order. */ - printf("sockaddr{ len=%u family=%u", addr->sa_len, addr->sa_family); - switch (addr->sa_family) { - case AF_INET: - sin4 = (struct sockaddr_in *)addr; - printf(" port=%u\n", ntohs(sin4->sin_port)); - ipsec_hexdump((caddr_t)&sin4->sin_addr, sizeof(sin4->sin_addr)); +#ifdef INET + case AF_INET: { + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *)addr; + inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)); break; + } +#endif #ifdef INET6 - case AF_INET6: + case AF_INET6: { + struct sockaddr_in6 *sin6; + sin6 = (struct sockaddr_in6 *)addr; - printf(" port=%u\n", ntohs(sin6->sin6_port)); - printf(" flowinfo=0x%08x, scope_id=0x%08x\n", - sin6->sin6_flowinfo, sin6->sin6_scope_id); - ipsec_hexdump((caddr_t)&sin6->sin6_addr, - sizeof(sin6->sin6_addr)); + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { + snprintf(buf, sizeof(buf), "%s%%%u", + inet_ntop(AF_INET6, &sin6->sin6_addr, buf, + sizeof(buf)), sin6->sin6_scope_id); + } else + inet_ntop(AF_INET6, &sin6->sin6_addr, buf, + sizeof(buf)); break; + } #endif + default: + sprintf(buf, "unknown"); } - - printf(" }\n"); - - return; + printf("sockaddr{ len=%u family=%u addr=%s }\n", addr->sa_len, + addr->sa_family, buf); } void