X-Git-Url: https://git.saurik.com/apple/ipsec.git/blobdiff_plain/476121220b14176dcbf5f70f47b9ef8e38f8b389..c8d8bee0bee0298e25cb827876f57e58cc0a938c:/ipsec-tools/Common/pfkey.c diff --git a/ipsec-tools/Common/pfkey.c b/ipsec-tools/Common/pfkey.c index 026ccd8..409333d 100644 --- a/ipsec-tools/Common/pfkey.c +++ b/ipsec-tools/Common/pfkey.c @@ -36,11 +36,8 @@ #include #include #include -#ifdef __APPLE__ -#include -#else #include -#endif +#include #include #ifdef HAVE_NETINET6_IPSEC # include @@ -53,57 +50,48 @@ #include #include #include +#include +#include "var.h" #include "ipsec_strerror.h" #include "libpfkey.h" #define CALLOC(size, cast) (cast)calloc(1, (size)) -static int findsupportedmap __P((int)); -static int setsupportedmap __P((struct sadb_supported *)); -static struct sadb_alg *findsupportedalg __P((u_int, u_int)); -#ifdef __APPLE__ -static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *, - struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t, - u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t, - u_int32_t, u_int32_t, u_int32_t, u_int16_t)); -#else -static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *, - struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t, +static int findsupportedmap (int); +static int setsupportedmap (struct sadb_supported *); +static struct sadb_alg *findsupportedalg (u_int, u_int); +static int pfkey_send_x1 (int, u_int, u_int, u_int, struct sockaddr_storage *, + struct sockaddr_storage *, u_int32_t, u_int32_t, u_int, caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t, - u_int32_t, u_int32_t, u_int32_t, - u_int8_t, u_int16_t, u_int16_t, struct sockaddr *, u_int16_t)); -#endif -static int pfkey_send_x2 __P((int, u_int, u_int, u_int, - struct sockaddr *, struct sockaddr *, u_int32_t)); -static int pfkey_send_x3 __P((int, u_int, u_int)); -static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int, - struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t, - char *, int, u_int32_t)); -static int pfkey_send_x5 __P((int, u_int, u_int32_t)); - -static caddr_t pfkey_setsadbmsg __P((caddr_t, caddr_t, u_int, u_int, - u_int, u_int32_t, pid_t)); -#ifdef __APPLE__ -static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int, - u_int, u_int, u_int32_t, u_int16_t)); -#else -static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int, - u_int, u_int, u_int32_t)); -#endif -static caddr_t pfkey_setsadbaddr __P((caddr_t, caddr_t, u_int, - struct sockaddr *, u_int, u_int)); -static caddr_t pfkey_setsadbkey __P((caddr_t, caddr_t, u_int, caddr_t, u_int)); -static caddr_t pfkey_setsadblifetime __P((caddr_t, caddr_t, u_int, u_int32_t, - u_int32_t, u_int32_t, u_int32_t)); -static caddr_t pfkey_setsadbxsa2 __P((caddr_t, caddr_t, u_int32_t, u_int32_t)); + u_int32_t, u_int32_t, u_int32_t, u_int16_t, u_int); +static int pfkey_send_x2 (int, u_int, u_int, u_int, + struct sockaddr_storage *, struct sockaddr_storage *, u_int32_t); +static int pfkey_send_x3 (int, u_int, u_int); +static int pfkey_send_x4 (int, u_int, struct sockaddr_storage *, struct sockaddr_storage *, u_int, + struct sockaddr_storage *, struct sockaddr_storage *, u_int, u_int, u_int64_t, u_int64_t, + char *, int, u_int32_t, char *, char *, char *, u_int); +static int pfkey_send_x5 (int, u_int, u_int32_t); + +static caddr_t pfkey_setsadbmsg (caddr_t, caddr_t, u_int, u_int, + 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, u_int16_t); +static caddr_t pfkey_setsadbaddr (caddr_t, caddr_t, u_int, + struct sockaddr_storage *, u_int, u_int); +static caddr_t pfkey_setsadbkey (caddr_t, caddr_t, u_int, caddr_t, u_int); +static caddr_t pfkey_setsadblifetime (caddr_t, caddr_t, u_int, u_int32_t, + u_int32_t, u_int32_t, u_int32_t); +static caddr_t pfkey_setsadbipsecif(caddr_t, caddr_t, char *, + char *, char *, int); +static caddr_t pfkey_setsadbxsa2 (caddr_t, caddr_t, u_int32_t, u_int32_t, u_int); #ifdef SADB_X_EXT_NAT_T_TYPE -static caddr_t pfkey_set_natt_type __P((caddr_t, caddr_t, u_int, u_int8_t)); -static caddr_t pfkey_set_natt_port __P((caddr_t, caddr_t, u_int, u_int16_t)); +static caddr_t pfkey_set_natt_type (caddr_t, caddr_t, u_int, u_int8_t); +static caddr_t pfkey_set_natt_port (caddr_t, caddr_t, u_int, u_int16_t); #endif #ifdef SADB_X_EXT_NAT_T_FRAG -static caddr_t pfkey_set_natt_frag __P((caddr_t, caddr_t, u_int, u_int16_t)); +static caddr_t pfkey_set_natt_frag (caddr_t, caddr_t, u_int, u_int16_t); #endif /* @@ -125,8 +113,7 @@ static int supported_map[] = { }; static int -findsupportedmap(satype) - int satype; +findsupportedmap(int satype) { int i; @@ -137,8 +124,7 @@ findsupportedmap(satype) } static struct sadb_alg * -findsupportedalg(satype, alg_id) - u_int satype, alg_id; +findsupportedalg(u_int satype, u_int alg_id) { int algno; int tlen; @@ -175,8 +161,7 @@ findsupportedalg(satype, alg_id) } static int -setsupportedmap(sup) - struct sadb_supported *sup; +setsupportedmap(struct sadb_supported *sup) { struct sadb_supported **ipsup; @@ -215,10 +200,7 @@ setsupportedmap(sup) * 0: valid. */ int -ipsec_check_keylen(supported, alg_id, keylen) - u_int supported; - u_int alg_id; - u_int keylen; +ipsec_check_keylen(u_int supported, u_int alg_id, u_int keylen) { u_int satype; @@ -247,10 +229,7 @@ ipsec_check_keylen(supported, alg_id, keylen) * 0: valid. */ int -ipsec_check_keylen2(satype, alg_id, keylen) - u_int satype; - u_int alg_id; - u_int keylen; +ipsec_check_keylen2(u_int satype, u_int alg_id, u_int keylen) { struct sadb_alg *alg; @@ -278,9 +257,7 @@ ipsec_check_keylen2(satype, alg_id, keylen) * 0: valid. */ int -ipsec_get_keylen(supported, alg_id, alg0) - u_int supported, alg_id; - struct sadb_alg *alg0; +ipsec_get_keylen(u_int supported, u_int alg_id, struct sadb_alg *alg0) { struct sadb_alg *alg; u_int satype; @@ -323,8 +300,7 @@ static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE; static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE; u_int -pfkey_set_softrate(type, rate) - u_int type, rate; +pfkey_set_softrate(u_int type, u_int rate) { __ipsec_errcode = EIPSEC_NO_ERROR; @@ -355,8 +331,7 @@ pfkey_set_softrate(type, rate) * ATTENTION: ~0 is returned if invalid type was passed. */ u_int -pfkey_get_softrate(type) - u_int type; +pfkey_get_softrate(u_int type) { switch (type) { case SADB_X_LIFETIME_ALLOCATIONS: @@ -379,11 +354,8 @@ pfkey_get_softrate(type) * -1 : error occured, and set errno. */ int -pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) - int so; - u_int satype, mode; - struct sockaddr *src, *dst; - u_int32_t min, max, reqid, seq; +pfkey_send_getspi(int so, u_int satype, u_int mode, struct sockaddr_storage *src, struct sockaddr_storage *dst, + u_int32_t min, u_int32_t max, u_int32_t reqid, u_int use_addtime, u_int64_t l_addtime, u_int32_t seq, u_int always_expire) { struct sadb_msg *newmsg; caddr_t ep; @@ -397,7 +369,7 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; } - if (src->sa_family != dst->sa_family) { + if (src->ss_family != dst->ss_family) { __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; return -1; } @@ -405,7 +377,7 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) __ipsec_errcode = EIPSEC_INVAL_SPI; return -1; } - switch (src->sa_family) { + switch (src->ss_family) { case AF_INET: plen = sizeof(struct in_addr) << 3; break; @@ -421,9 +393,10 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) len = sizeof(struct sadb_msg) + sizeof(struct sadb_x_sa2) + sizeof(struct sadb_address) - + PFKEY_ALIGN8(sysdep_sa_len(src)) + + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)src)) + sizeof(struct sadb_address) - + PFKEY_ALIGN8(sysdep_sa_len(dst)); + + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)dst)) + + ((use_addtime) ? sizeof(struct sadb_lifetime) : 0); if (min > 255 && max < (u_int)~0) { need_spirange++; @@ -443,7 +416,7 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) return -1; } - p = pfkey_setsadbxsa2(p, ep, mode, reqid); + p = pfkey_setsadbxsa2(p, ep, mode, reqid, always_expire); if (!p) { free(newmsg); return -1; @@ -464,6 +437,16 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) free(newmsg); return -1; } + + if (use_addtime) { + /* set sadb_lifetime, only hard lifetime applicable for larval SAs */ + p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, + 0, 0, l_addtime, 0); + if (!p) { + free(newmsg); + return -1; + } + } /* proccessing spi range */ if (need_spirange) { @@ -501,7 +484,6 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) } -#ifdef __APPLE__ /* * sending SADB_UPDATE message to the kernel. * The length of key material is a_keylen + e_keylen. @@ -510,26 +492,17 @@ pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) * -1 : error occured, and set errno. */ int -pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize, - keymat, e_type, e_keylen, a_type, a_keylen, flags, - l_alloc, l_bytes, l_addtime, l_usetime, seq, port) - int so; - u_int satype, mode, wsize; - struct sockaddr *src, *dst; - u_int32_t spi, reqid; - caddr_t keymat; - u_int e_type, e_keylen, a_type, a_keylen, flags; - u_int32_t l_alloc; - u_int64_t l_bytes, l_addtime, l_usetime; - u_int32_t seq; - u_int16_t port; +pfkey_send_update(int so, u_int satype, u_int mode, struct sockaddr_storage *src, struct sockaddr_storage *dst, + u_int32_t spi, u_int32_t reqid, u_int wsize, caddr_t keymat, u_int e_type, u_int e_keylen, + u_int a_type, u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes, + u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq, u_int16_t port, u_int always_expire) { int len; if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi, reqid, wsize, keymat, e_type, e_keylen, a_type, a_keylen, flags, l_alloc, (u_int)l_bytes, (u_int)l_addtime, - (u_int)l_usetime, seq, port)) < 0) + (u_int)l_usetime, seq, port, always_expire)) < 0) return -1; return len; @@ -544,167 +517,23 @@ pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize, * -1 : error occured, and set errno. */ int -pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize, - keymat, e_type, e_keylen, a_type, a_keylen, flags, - l_alloc, l_bytes, l_addtime, l_usetime, seq, port) - int so; - u_int satype, mode, wsize; - struct sockaddr *src, *dst; - u_int32_t spi, reqid; - caddr_t keymat; - u_int e_type, e_keylen, a_type, a_keylen, flags; - u_int32_t l_alloc; - u_int64_t l_bytes, l_addtime, l_usetime; - u_int32_t seq; - u_int16_t port; +pfkey_send_add(int so, u_int satype, u_int mode, struct sockaddr_storage *src, struct sockaddr_storage *dst, + u_int32_t spi, u_int32_t reqid, u_int wsize, caddr_t keymat, u_int e_type, u_int e_keylen, + u_int a_type, u_int a_keylen, u_int flags, u_int32_t l_alloc, u_int64_t l_bytes, + u_int64_t l_addtime, u_int64_t l_usetime, u_int32_t seq, u_int16_t port, u_int always_expire) { int len; if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi, reqid, wsize, keymat, e_type, e_keylen, a_type, a_keylen, flags, l_alloc, (u_int)l_bytes, (u_int)l_addtime, - (u_int)l_usetime, seq, port)) < 0) + (u_int)l_usetime, seq, port, always_expire)) < 0) return -1; return len; } -#else /* __APPLE__ */ - -/* - * sending SADB_UPDATE message to the kernel. - * The length of key material is a_keylen + e_keylen. - * OUT: - * positive: success and return length sent. - * -1 : error occured, and set errno. - */ -int -pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize, - keymat, e_type, e_keylen, a_type, a_keylen, flags, - l_alloc, l_bytes, l_addtime, l_usetime, seq) - int so; - u_int satype, mode, wsize; - struct sockaddr *src, *dst; - u_int32_t spi, reqid; - caddr_t keymat; - u_int e_type, e_keylen, a_type, a_keylen, flags; - u_int32_t l_alloc; - u_int64_t l_bytes, l_addtime, l_usetime; - u_int32_t seq; -{ - int len; - if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi, - reqid, wsize, - keymat, e_type, e_keylen, a_type, a_keylen, flags, - l_alloc, (u_int)l_bytes, (u_int)l_addtime, - (u_int)l_usetime, seq, 0, 0, 0, NULL, 0)) < 0) - return -1; - - return len; -} - -#ifdef SADB_X_EXT_NAT_T_TYPE -int -pfkey_send_update_nat(so, satype, mode, src, dst, spi, reqid, wsize, - keymat, e_type, e_keylen, a_type, a_keylen, flags, - l_alloc, l_bytes, l_addtime, l_usetime, seq, - l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa, - l_natt_frag) - int so; - u_int satype, mode, wsize; - struct sockaddr *src, *dst; - u_int32_t spi, reqid; - caddr_t keymat; - u_int e_type, e_keylen, a_type, a_keylen, flags; - u_int32_t l_alloc; - u_int64_t l_bytes, l_addtime, l_usetime; - u_int32_t seq; - u_int8_t l_natt_type; - u_int16_t l_natt_sport, l_natt_dport; - struct sockaddr *l_natt_oa; - u_int16_t l_natt_frag; -{ - int len; - if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi, - reqid, wsize, - keymat, e_type, e_keylen, a_type, a_keylen, flags, - l_alloc, (u_int)l_bytes, (u_int)l_addtime, - (u_int)l_usetime, seq, l_natt_type, l_natt_sport, - l_natt_dport, l_natt_oa, l_natt_frag)) < 0) - return -1; - - return len; -} -#endif - -/* - * sending SADB_ADD message to the kernel. - * The length of key material is a_keylen + e_keylen. - * OUT: - * positive: success and return length sent. - * -1 : error occured, and set errno. - */ -int -pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize, - keymat, e_type, e_keylen, a_type, a_keylen, flags, - l_alloc, l_bytes, l_addtime, l_usetime, seq) - int so; - u_int satype, mode, wsize; - struct sockaddr *src, *dst; - u_int32_t spi, reqid; - caddr_t keymat; - u_int e_type, e_keylen, a_type, a_keylen, flags; - u_int32_t l_alloc; - u_int64_t l_bytes, l_addtime, l_usetime; - u_int32_t seq; -{ - int len; - if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi, - reqid, wsize, - keymat, e_type, e_keylen, a_type, a_keylen, flags, - l_alloc, (u_int)l_bytes, (u_int)l_addtime, - (u_int)l_usetime, seq, 0, 0, 0, NULL, 0)) < 0) - return -1; - - return len; -} - -#ifdef SADB_X_EXT_NAT_T_TYPE -int -pfkey_send_add_nat(so, satype, mode, src, dst, spi, reqid, wsize, - keymat, e_type, e_keylen, a_type, a_keylen, flags, - l_alloc, l_bytes, l_addtime, l_usetime, seq, - l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa, - l_natt_frag) - int so; - u_int satype, mode, wsize; - struct sockaddr *src, *dst; - u_int32_t spi, reqid; - caddr_t keymat; - u_int e_type, e_keylen, a_type, a_keylen, flags; - u_int32_t l_alloc; - u_int64_t l_bytes, l_addtime, l_usetime; - u_int32_t seq; - u_int8_t l_natt_type; - u_int16_t l_natt_sport, l_natt_dport; - struct sockaddr *l_natt_oa; - u_int16_t l_natt_frag; -{ - int len; - if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi, - reqid, wsize, - keymat, e_type, e_keylen, a_type, a_keylen, flags, - l_alloc, (u_int)l_bytes, (u_int)l_addtime, - (u_int)l_usetime, seq, l_natt_type, l_natt_sport, - l_natt_dport, l_natt_oa, l_natt_frag)) < 0) - return -1; - - return len; -} -#endif -#endif /* __APPLE__ */ - /* * sending SADB_DELETE message to the kernel. * OUT: @@ -715,7 +544,7 @@ int pfkey_send_delete(so, satype, mode, src, dst, spi) int so; u_int satype, mode; - struct sockaddr *src, *dst; + struct sockaddr_storage *src, *dst; u_int32_t spi; { int len; @@ -736,10 +565,7 @@ pfkey_send_delete(so, satype, mode, src, dst, spi) */ /*ARGSUSED*/ int -pfkey_send_delete_all(so, satype, mode, src, dst) - int so; - u_int satype, mode; - struct sockaddr *src, *dst; +pfkey_send_delete_all(int so, u_int satype, u_int mode, struct sockaddr_storage *src, struct sockaddr_storage *dst) { struct sadb_msg *newmsg; int len; @@ -752,11 +578,11 @@ pfkey_send_delete_all(so, satype, mode, src, dst) __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; } - if (src->sa_family != dst->sa_family) { + if (src->ss_family != dst->ss_family) { __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; return -1; } - switch (src->sa_family) { + switch (src->ss_family) { case AF_INET: plen = sizeof(struct in_addr) << 3; break; @@ -771,9 +597,9 @@ pfkey_send_delete_all(so, satype, mode, src, dst) /* create new sadb_msg to reply. */ len = sizeof(struct sadb_msg) + sizeof(struct sadb_address) - + PFKEY_ALIGN8(sysdep_sa_len(src)) + + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)src)) + sizeof(struct sadb_address) - + PFKEY_ALIGN8(sysdep_sa_len(dst)); + + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)dst)); if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { __ipsec_set_strerror(strerror(errno)); @@ -818,11 +644,7 @@ pfkey_send_delete_all(so, satype, mode, src, dst) * -1 : error occured, and set errno. */ int -pfkey_send_get(so, satype, mode, src, dst, spi) - int so; - u_int satype, mode; - struct sockaddr *src, *dst; - u_int32_t spi; +pfkey_send_get(int so, u_int satype, u_int mode, struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int32_t spi) { int len; if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0) @@ -838,9 +660,7 @@ pfkey_send_get(so, satype, mode, src, dst, spi) * -1 : error occured, and set errno. */ int -pfkey_send_register(so, satype) - int so; - u_int satype; +pfkey_send_register(int so, u_int satype) { int len, algno; @@ -880,8 +700,7 @@ pfkey_send_register(so, satype) * -1: error occured, and set errno. */ int -pfkey_recv_register(so) - int so; +pfkey_recv_register(int so) { pid_t pid = getpid(); struct sadb_msg *newmsg; @@ -920,9 +739,7 @@ pfkey_recv_register(so) * -1: error occured, and set errno. */ int -pfkey_set_supported(msg, tlen) - struct sadb_msg *msg; - int tlen; +pfkey_set_supported(struct sadb_msg *msg, int tlen) { struct sadb_supported *sup; caddr_t p; @@ -984,9 +801,7 @@ pfkey_set_supported(msg, tlen) * -1 : error occured, and set errno. */ int -pfkey_send_flush(so, satype) - int so; - u_int satype; +pfkey_send_flush(int so, u_int satype) { int len; @@ -1003,9 +818,7 @@ pfkey_send_flush(so, satype) * -1 : error occured, and set errno. */ int -pfkey_send_dump(so, satype) - int so; - u_int satype; +pfkey_send_dump(int so, u_int satype) { int len; @@ -1028,9 +841,7 @@ pfkey_send_dump(so, satype) * algorithms is. */ int -pfkey_send_promisc_toggle(so, flag) - int so; - int flag; +pfkey_send_promisc_toggle(int so, int flag) { int len; @@ -1048,20 +859,15 @@ pfkey_send_promisc_toggle(so, flag) * -1 : error occured, and set errno. */ int -pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq) - int so; - struct sockaddr *src, *dst; - u_int prefs, prefd, proto; - caddr_t policy; - int policylen; - u_int32_t seq; +pfkey_send_spdadd(int so, struct sockaddr_storage *src, u_int prefs, struct sockaddr_storage *dst, + u_int prefd, u_int proto, caddr_t policy, int policylen, u_int32_t seq) { int len; if ((len = pfkey_send_x4(so, SADB_X_SPDADD, - src, prefs, dst, prefd, proto, + src, NULL, prefs, dst, NULL, prefd, proto, (u_int64_t)0, (u_int64_t)0, - policy, policylen, seq)) < 0) + policy, policylen, seq, NULL, NULL, NULL, 0)) < 0) return -1; return len; @@ -1074,22 +880,37 @@ pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq) * -1 : error occured, and set errno. */ int -pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime, - policy, policylen, seq) - int so; - struct sockaddr *src, *dst; - u_int prefs, prefd, proto; - u_int64_t ltime, vtime; - caddr_t policy; - int policylen; - u_int32_t seq; +pfkey_send_spdadd_with_interface(int so, struct sockaddr_storage *src, struct sockaddr_storage *src_end, u_int prefs, struct sockaddr_storage *dst, + struct sockaddr_storage *dst_end, u_int prefd, u_int proto, caddr_t policy, int policylen, u_int32_t seq, char *ipsec_if, + char *internal_if, char *outgoing_if, u_int disabled) +{ + int len; + + if ((len = pfkey_send_x4(so, SADB_X_SPDADD, + src, src_end, prefs, dst, dst_end, prefd, proto, + (u_int64_t)0, (u_int64_t)0, + policy, policylen, seq, ipsec_if, internal_if, outgoing_if, disabled)) < 0) + return -1; + + return len; +} + +/* + * sending SADB_X_SPDADD message to the kernel. + * OUT: + * positive: success and return length sent. + * -1 : error occured, and set errno. + */ +int +pfkey_send_spdadd2(int so, struct sockaddr_storage *src, u_int prefs, struct sockaddr_storage *dst, u_int prefd, u_int proto, u_int64_t ltime, u_int64_t vtime, + caddr_t policy, int policylen, u_int32_t seq) { int len; if ((len = pfkey_send_x4(so, SADB_X_SPDADD, - src, prefs, dst, prefd, proto, + src, NULL, prefs, dst, NULL, prefd, proto, ltime, vtime, - policy, policylen, seq)) < 0) + policy, policylen, seq, NULL, NULL, NULL, 0)) < 0) return -1; return len; @@ -1102,20 +923,15 @@ pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime, * -1 : error occured, and set errno. */ int -pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq) - int so; - struct sockaddr *src, *dst; - u_int prefs, prefd, proto; - caddr_t policy; - int policylen; - u_int32_t seq; +pfkey_send_spdupdate(int so, struct sockaddr_storage *src, u_int prefs, struct sockaddr_storage *dst, + u_int prefd, u_int proto, caddr_t policy, int policylen, u_int32_t seq) { int len; if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, - src, prefs, dst, prefd, proto, + src, NULL, prefs, dst, NULL, prefd, proto, (u_int64_t)0, (u_int64_t)0, - policy, policylen, seq)) < 0) + policy, policylen, seq, NULL, NULL, NULL, 0)) < 0) return -1; return len; @@ -1128,22 +944,16 @@ pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq) * -1 : error occured, and set errno. */ int -pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime, - policy, policylen, seq) - int so; - struct sockaddr *src, *dst; - u_int prefs, prefd, proto; - u_int64_t ltime, vtime; - caddr_t policy; - int policylen; - u_int32_t seq; +pfkey_send_spdupdate2(int so, struct sockaddr_storage *src, u_int prefs, struct sockaddr_storage *dst, + u_int prefd, u_int proto, u_int64_t ltime, u_int64_t vtime, + caddr_t policy, int policylen, u_int32_t seq) { int len; if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, - src, prefs, dst, prefd, proto, + src, NULL, prefs, dst, NULL, prefd, proto, ltime, vtime, - policy, policylen, seq)) < 0) + policy, policylen, seq, NULL, NULL, NULL, 0)) < 0) return -1; return len; @@ -1156,13 +966,8 @@ pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime, * -1 : error occured, and set errno. */ int -pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq) - int so; - struct sockaddr *src, *dst; - u_int prefs, prefd, proto; - caddr_t policy; - int policylen; - u_int32_t seq; +pfkey_send_spddelete(int so, struct sockaddr_storage *src, u_int prefs, struct sockaddr_storage *dst, + u_int prefd, u_int proto, caddr_t policy, int policylen, u_int32_t seq) { int len; @@ -1172,9 +977,9 @@ pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq) } if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE, - src, prefs, dst, prefd, proto, + src, NULL, prefs, dst, NULL, prefd, proto, (u_int64_t)0, (u_int64_t)0, - policy, policylen, seq)) < 0) + policy, policylen, seq, NULL, NULL, NULL, 0)) < 0) return -1; return len; @@ -1187,9 +992,7 @@ pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq) * -1 : error occured, and set errno. */ int -pfkey_send_spddelete2(so, spid) - int so; - u_int32_t spid; +pfkey_send_spddelete2(int so, u_int32_t spid) { int len; @@ -1199,6 +1002,28 @@ pfkey_send_spddelete2(so, spid) return len; } +int +pfkey_send_spdenable(int so, u_int32_t spid) +{ + int len; + + if ((len = pfkey_send_x5(so, SADB_X_SPDENABLE, spid)) < 0) + return -1; + + return len; +} + +int +pfkey_send_spddisable(int so, u_int32_t spid) +{ + int len; + + if ((len = pfkey_send_x5(so, SADB_X_SPDDISABLE, spid)) < 0) + return -1; + + return len; +} + /* * sending SADB_X_SPDGET message to the kernel. * OUT: @@ -1206,9 +1031,7 @@ pfkey_send_spddelete2(so, spid) * -1 : error occured, and set errno. */ int -pfkey_send_spdget(so, spid) - int so; - u_int32_t spid; +pfkey_send_spdget(int so, u_int32_t spid) { int len; @@ -1225,13 +1048,8 @@ pfkey_send_spdget(so, spid) * -1 : error occured, and set errno. */ int -pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq) - int so; - struct sockaddr *src, *dst; - u_int prefs, prefd, proto; - caddr_t policy; - int policylen; - u_int32_t seq; +pfkey_send_spdsetidx(int so, struct sockaddr_storage *src, u_int prefs, struct sockaddr_storage *dst, + u_int prefd, u_int proto, caddr_t policy, int policylen, u_int32_t seq) { int len; @@ -1241,9 +1059,9 @@ pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq) } if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX, - src, prefs, dst, prefd, proto, + src, NULL, prefs, dst, NULL, prefd, proto, (u_int64_t)0, (u_int64_t)0, - policy, policylen, seq)) < 0) + policy, policylen, seq, NULL, NULL, NULL, 0)) < 0) return -1; return len; @@ -1256,8 +1074,7 @@ pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq) * -1 : error occured, and set errno. */ int -pfkey_send_spdflush(so) - int so; +pfkey_send_spdflush(int so) { int len; @@ -1274,8 +1091,7 @@ pfkey_send_spdflush(so) * -1 : error occured, and set errno. */ int -pfkey_send_spddump(so) - int so; +pfkey_send_spddump(int so) { int len; @@ -1285,21 +1101,14 @@ pfkey_send_spddump(so) return len; } -#ifdef __APPLE__ + /* sending SADB_ADD or SADB_UPDATE message to the kernel */ static int -pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, - keymat, e_type, e_keylen, a_type, a_keylen, flags, - l_alloc, l_bytes, l_addtime, l_usetime, seq, port) - int so; - u_int type, satype, mode; - struct sockaddr *src, *dst; - u_int32_t spi, reqid; - u_int wsize; - caddr_t keymat; - u_int e_type, e_keylen, a_type, a_keylen, flags; - u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq; - u_int16_t port; +pfkey_send_x1(int so, u_int type, u_int satype, u_int mode, struct sockaddr_storage *src, + struct sockaddr_storage *dst, u_int32_t spi, u_int32_t reqid, u_int wsize, + caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type, u_int a_keylen, u_int flags, + u_int32_t l_alloc, u_int32_t l_bytes, u_int32_t l_addtime, u_int32_t l_usetime, u_int32_t seq, u_int16_t port, + u_int always_expire) { struct sadb_msg *newmsg; int len; @@ -1312,11 +1121,11 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; } - if (src->sa_family != dst->sa_family) { + if (src->ss_family != dst->ss_family) { __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; return -1; } - switch (src->sa_family) { + switch (src->ss_family) { case AF_INET: plen = sizeof(struct in_addr) << 3; break; @@ -1377,9 +1186,9 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, + sizeof(struct sadb_sa_2) + sizeof(struct sadb_x_sa2) + sizeof(struct sadb_address) - + PFKEY_ALIGN8(sysdep_sa_len(src)) + + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)src)) + sizeof(struct sadb_address) - + PFKEY_ALIGN8(sysdep_sa_len(dst)) + + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)dst)) + sizeof(struct sadb_lifetime) + sizeof(struct sadb_lifetime); @@ -1405,7 +1214,7 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, free(newmsg); return -1; } - p = pfkey_setsadbxsa2(p, ep, mode, reqid); + p = pfkey_setsadbxsa2(p, ep, mode, reqid, always_expire); if (!p) { free(newmsg); return -1; @@ -1470,277 +1279,11 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, return len; } -#else /* __APPLE__ */ - -/* sending SADB_ADD or SADB_UPDATE message to the kernel */ -static int -pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, - keymat, e_type, e_keylen, a_type, a_keylen, flags, - l_alloc, l_bytes, l_addtime, l_usetime, seq, - l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa, - l_natt_frag) - int so; - u_int type, satype, mode; - struct sockaddr *src, *dst, *l_natt_oa; - u_int32_t spi, reqid; - u_int wsize; - caddr_t keymat; - u_int e_type, e_keylen, a_type, a_keylen, flags; - u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq; - u_int16_t l_natt_sport, l_natt_dport; - u_int8_t l_natt_type; - u_int16_t l_natt_frag; -{ - struct sadb_msg *newmsg; - int len; - caddr_t p; - int plen; - caddr_t ep; - - /* validity check */ - if (src == NULL || dst == NULL) { - __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; - return -1; - } - if (src->sa_family != dst->sa_family) { - __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; - return -1; - } - switch (src->sa_family) { - case AF_INET: - plen = sizeof(struct in_addr) << 3; - break; - case AF_INET6: - plen = sizeof(struct in6_addr) << 3; - break; - default: - __ipsec_errcode = EIPSEC_INVAL_FAMILY; - return -1; - } - - switch (satype) { - case SADB_SATYPE_ESP: - if (e_type == SADB_EALG_NONE) { - __ipsec_errcode = EIPSEC_NO_ALGS; - return -1; - } - break; - case SADB_SATYPE_AH: - if (e_type != SADB_EALG_NONE) { - __ipsec_errcode = EIPSEC_INVAL_ALGS; - return -1; - } - if (a_type == SADB_AALG_NONE) { - __ipsec_errcode = EIPSEC_NO_ALGS; - return -1; - } - break; - case SADB_X_SATYPE_IPCOMP: - if (e_type == SADB_X_CALG_NONE) { - __ipsec_errcode = EIPSEC_INVAL_ALGS; - return -1; - } - if (a_type != SADB_AALG_NONE) { - __ipsec_errcode = EIPSEC_NO_ALGS; - return -1; - } - break; -#ifdef SADB_X_AALG_TCP_MD5 - case SADB_X_SATYPE_TCPSIGNATURE: - if (e_type != SADB_EALG_NONE) { - __ipsec_errcode = EIPSEC_INVAL_ALGS; - return -1; - } - if (a_type != SADB_X_AALG_TCP_MD5) { - __ipsec_errcode = EIPSEC_INVAL_ALGS; - return -1; - } - break; -#endif - default: - __ipsec_errcode = EIPSEC_INVAL_SATYPE; - return -1; - } - - /* create new sadb_msg to reply. */ - len = sizeof(struct sadb_msg) - + sizeof(struct sadb_sa) - + sizeof(struct sadb_x_sa2) - + sizeof(struct sadb_address) - + PFKEY_ALIGN8(sysdep_sa_len(src)) - + sizeof(struct sadb_address) - + PFKEY_ALIGN8(sysdep_sa_len(dst)) - + sizeof(struct sadb_lifetime) - + sizeof(struct sadb_lifetime); - - if (e_type != SADB_EALG_NONE && satype != SADB_X_SATYPE_IPCOMP) - len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen)); - if (a_type != SADB_AALG_NONE) - len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen)); - -#ifdef SADB_X_EXT_NAT_T_TYPE - /* add nat-t packets */ - if (l_natt_type) { - switch(satype) { - case SADB_SATYPE_ESP: - case SADB_X_SATYPE_IPCOMP: - break; - default: - __ipsec_errcode = EIPSEC_NO_ALGS; - return -1; - } - - len += sizeof(struct sadb_x_nat_t_type); - len += sizeof(struct sadb_x_nat_t_port); - len += sizeof(struct sadb_x_nat_t_port); - if (l_natt_oa) - len += sizeof(struct sadb_address) + - PFKEY_ALIGN8(sysdep_sa_len(l_natt_oa)); -#ifdef SADB_X_EXT_NAT_T_FRAG - if (l_natt_frag) - len += sizeof(struct sadb_x_nat_t_frag); -#endif - } -#endif - - if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { - __ipsec_set_strerror(strerror(errno)); - return -1; - } - ep = ((caddr_t)(void *)newmsg) + len; - - p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, - satype, seq, getpid()); - if (!p) { - free(newmsg); - return -1; - } - p = pfkey_setsadbsa(p, ep, spi, wsize, a_type, e_type, flags); - if (!p) { - free(newmsg); - return -1; - } - p = pfkey_setsadbxsa2(p, ep, mode, reqid); - if (!p) { - free(newmsg); - return -1; - } - p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen, - IPSEC_ULPROTO_ANY); - if (!p) { - free(newmsg); - return -1; - } - p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen, - IPSEC_ULPROTO_ANY); - if (!p) { - free(newmsg); - return -1; - } - - if (e_type != SADB_EALG_NONE && satype != SADB_X_SATYPE_IPCOMP) { - p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT, - keymat, e_keylen); - if (!p) { - free(newmsg); - return -1; - } - } - if (a_type != SADB_AALG_NONE) { - p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH, - keymat + e_keylen, a_keylen); - if (!p) { - free(newmsg); - return -1; - } - } - - /* set sadb_lifetime for destination */ - p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, - l_alloc, l_bytes, l_addtime, l_usetime); - if (!p) { - free(newmsg); - return -1; - } - p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT, - l_alloc, l_bytes, l_addtime, l_usetime); - if (!p) { - free(newmsg); - return -1; - } - -#ifdef SADB_X_EXT_NAT_T_TYPE - /* Add nat-t messages */ - if (l_natt_type) { - p = pfkey_set_natt_type(p, ep, SADB_X_EXT_NAT_T_TYPE, l_natt_type); - if (!p) { - free(newmsg); - return -1; - } - - p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_SPORT, - l_natt_sport); - if (!p) { - free(newmsg); - return -1; - } - - p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_DPORT, - l_natt_dport); - if (!p) { - free(newmsg); - return -1; - } - - if (l_natt_oa) { - p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_NAT_T_OA, - l_natt_oa, - (u_int)PFKEY_ALIGN8(sysdep_sa_len(l_natt_oa)), - IPSEC_ULPROTO_ANY); - if (!p) { - free(newmsg); - return -1; - } - } - - if (l_natt_frag) { -#ifdef SADB_X_EXT_NAT_T_FRAG - p = pfkey_set_natt_frag(p, ep, SADB_X_EXT_NAT_T_FRAG, - l_natt_frag); - if (!p) { - free(newmsg); - return -1; - } -#endif - } - } -#endif - - if (p != ep) { - free(newmsg); - return -1; - } - - /* send message */ - len = pfkey_send(so, newmsg, len); - free(newmsg); - - if (len < 0) - return -1; - - __ipsec_errcode = EIPSEC_NO_ERROR; - return len; -} -#endif /* __APPLE__ */ /* sending SADB_DELETE or SADB_GET message to the kernel */ /*ARGSUSED*/ static int -pfkey_send_x2(so, type, satype, mode, src, dst, spi) - int so; - u_int type, satype, mode; - struct sockaddr *src, *dst; - u_int32_t spi; +pfkey_send_x2(int so, u_int type, u_int satype, u_int mode, struct sockaddr_storage *src, struct sockaddr_storage *dst, u_int32_t spi) { struct sadb_msg *newmsg; int len; @@ -1753,11 +1296,11 @@ pfkey_send_x2(so, type, satype, mode, src, dst, spi) __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; } - if (src->sa_family != dst->sa_family) { + if (src->ss_family != dst->ss_family) { __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; return -1; } - switch (src->sa_family) { + switch (src->ss_family) { case AF_INET: plen = sizeof(struct in_addr) << 3; break; @@ -1771,15 +1314,11 @@ pfkey_send_x2(so, type, satype, mode, src, dst, spi) /* create new sadb_msg to reply. */ len = sizeof(struct sadb_msg) -#ifdef __APPLE__ + sizeof(struct sadb_sa_2) -#else - + sizeof(struct sadb_sa) -#endif + sizeof(struct sadb_address) - + PFKEY_ALIGN8(sysdep_sa_len(src)) + + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)src)) + sizeof(struct sadb_address) - + PFKEY_ALIGN8(sysdep_sa_len(dst)); + + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)dst)); if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { __ipsec_set_strerror(strerror(errno)); @@ -1793,11 +1332,7 @@ pfkey_send_x2(so, type, satype, mode, src, dst, spi) free(newmsg); return -1; } -#ifdef __APPLE__ p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0, 0); -#else - p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0); -#endif if (!p) { free(newmsg); return -1; @@ -1831,9 +1366,7 @@ pfkey_send_x2(so, type, satype, mode, src, dst, spi) * to the kernel */ static int -pfkey_send_x3(so, type, satype) - int so; - u_int type, satype; +pfkey_send_x3(int so, u_int type, u_int satype) { struct sadb_msg *newmsg; int len; @@ -1893,33 +1426,28 @@ pfkey_send_x3(so, type, satype) /* sending SADB_X_SPDADD message to the kernel */ static int -pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, - ltime, vtime, policy, policylen, seq) - int so; - struct sockaddr *src, *dst; - u_int type, prefs, prefd, proto; - u_int64_t ltime, vtime; - char *policy; - int policylen; - u_int32_t seq; +pfkey_send_x4(int so, u_int type, struct sockaddr_storage *src, struct sockaddr_storage *src_end, u_int prefs, struct sockaddr_storage *dst, struct sockaddr_storage *dst_end, + u_int prefd, u_int proto, u_int64_t ltime, u_int64_t vtime, char *policy, int policylen, u_int32_t seq, char *ipsec_if, char *internal_if, char *outgoing_if, + u_int disabled) { struct sadb_msg *newmsg; int len; caddr_t p; int plen; caddr_t ep; + int include_ipsec_if_msg = 0; /* validity check */ if (src == NULL || dst == NULL) { __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; return -1; } - if (src->sa_family != dst->sa_family) { + if (src->ss_family != dst->ss_family) { __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; return -1; } - switch (src->sa_family) { + switch (src->ss_family) { case AF_INET: plen = sizeof(struct in_addr) << 3; break; @@ -1934,15 +1462,22 @@ pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; return -1; } + + if (ipsec_if || internal_if || outgoing_if || disabled) { + include_ipsec_if_msg = 1; + } /* create new sadb_msg to reply. */ len = sizeof(struct sadb_msg) - + sizeof(struct sadb_address) - + PFKEY_ALIGN8(sysdep_sa_len(src)) - + sizeof(struct sadb_address) - + PFKEY_ALIGN8(sysdep_sa_len(src)) - + sizeof(struct sadb_lifetime) - + policylen; + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)src)) + + ((src_end) ? sizeof(struct sadb_address) + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)src_end)) : 0) + + sizeof(struct sadb_address) + + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)src)) + + ((dst_end) ? sizeof(struct sadb_address) + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)dst_end)) : 0) + + ((include_ipsec_if_msg) ? sizeof(struct sadb_x_ipsecif) : 0) + + sizeof(struct sadb_lifetime) + + policylen; if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) { __ipsec_set_strerror(strerror(errno)); @@ -1956,16 +1491,49 @@ pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, free(newmsg); return -1; } - p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto); - if (!p) { - free(newmsg); - return -1; - } - p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto); - if (!p) { - free(newmsg); - return -1; - } + if (src_end) { + p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_ADDR_RANGE_SRC_START, src, prefs, proto); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_ADDR_RANGE_SRC_END, src_end, prefs, proto); + if (!p) { + free(newmsg); + return -1; + } + } else { + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto); + if (!p) { + free(newmsg); + return -1; + } + } + if (dst_end) { + p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_ADDR_RANGE_DST_START, dst, prefd, proto); + if (!p) { + free(newmsg); + return -1; + } + p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_ADDR_RANGE_DST_END, dst_end, prefd, proto); + if (!p) { + free(newmsg); + return -1; + } + } else { + p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto); + if (!p) { + free(newmsg); + return -1; + } + } + if (include_ipsec_if_msg) { + p = pfkey_setsadbipsecif(p, ep, internal_if, outgoing_if, ipsec_if, disabled); + if (!p) { + free(newmsg); + return -1; + } + } p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, 0, 0, (u_int)ltime, (u_int)vtime); if (!p || p + policylen != ep) { @@ -1987,10 +1555,7 @@ pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, /* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */ static int -pfkey_send_x5(so, type, spid) - int so; - u_int type; - u_int32_t spid; +pfkey_send_x5(int so, u_int type, u_int32_t spid) { struct sadb_msg *newmsg; struct sadb_x_policy xpl; @@ -2056,7 +1621,7 @@ pfkey_open() __ipsec_set_strerror(strerror(errno)); return -1; } - + /* * This is a temporary workaround for KAME PR 154. * Don't really care even if it fails. @@ -2083,8 +1648,7 @@ pfkey_open() * -1: fail. */ void -pfkey_close(so) - int so; +pfkey_close_sock(int so) { (void)close(so); @@ -2102,11 +1666,11 @@ pfkey_close(so) * XXX should be rewritten to pass length explicitly */ struct sadb_msg * -pfkey_recv(so) - int so; +pfkey_recv(int so) { struct sadb_msg buf, *newmsg; - int len, reallen; + ssize_t len; + int reallen; while ((len = recv(so, (void *)&buf, sizeof(buf), MSG_PEEK)) < 0) { if (errno == EINTR) @@ -2160,10 +1724,7 @@ pfkey_recv(so) * -1 : fail. */ int -pfkey_send(so, msg, len) - int so; - struct sadb_msg *msg; - int len; +pfkey_send(int so, struct sadb_msg *msg, int len) { if ((len = send(so, (void *)msg, (socklen_t)len, 0)) < 0) { __ipsec_set_strerror(strerror(errno)); @@ -2189,9 +1750,7 @@ pfkey_send(so, msg, len) * XXX should be rewritten to obtain length explicitly */ int -pfkey_align(msg, mhp) - struct sadb_msg *msg; - caddr_t *mhp; +pfkey_align(struct sadb_msg *msg, caddr_t *mhp) { struct sadb_ext *ext; int i; @@ -2268,7 +1827,11 @@ pfkey_align(msg, mhp) #ifdef SADB_X_EXT_PACKET case SADB_X_EXT_PACKET: #endif - + case SADB_X_EXT_IPSECIF: + case SADB_X_EXT_ADDR_RANGE_SRC_START: + case SADB_X_EXT_ADDR_RANGE_SRC_END: + case SADB_X_EXT_ADDR_RANGE_DST_START: + case SADB_X_EXT_ADDR_RANGE_DST_END: mhp[ext->sadb_ext_type] = (void *)ext; break; default: @@ -2300,8 +1863,7 @@ pfkey_align(msg, mhp) * 0: valid. */ int -pfkey_check(mhp) - caddr_t *mhp; +pfkey_check(caddr_t * mhp) { struct sadb_msg *msg; @@ -2424,13 +1986,7 @@ pfkey_check(mhp) * `buf' must has been allocated sufficiently. */ static caddr_t -pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid) - caddr_t buf; - caddr_t lim; - u_int type, satype; - u_int tlen; - u_int32_t seq; - pid_t pid; +pfkey_setsadbmsg(caddr_t buf, caddr_t lim, u_int type, u_int tlen, u_int satype, u_int32_t seq, pid_t pid) { struct sadb_msg *p; u_int len; @@ -2454,18 +2010,12 @@ pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid) return(buf + len); } -#ifdef __APPLE__ /* * copy secasvar data into sadb_address. * `buf' must has been allocated sufficiently. */ static caddr_t -pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags, port) - caddr_t buf; - caddr_t lim; - u_int32_t spi, flags; - u_int wsize, auth, enc; - u_int16_t port; +pfkey_setsadbsa(caddr_t buf, caddr_t lim, u_int32_t spi, u_int wsize, u_int auth, u_int enc, u_int32_t flags, u_int16_t port) { struct sadb_sa_2 *p; u_int len; @@ -2489,42 +2039,6 @@ pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags, port) return(buf + len); } -#else - -/* - * copy secasvar data into sadb_address. - * `buf' must has been allocated sufficiently. - */ -static caddr_t -pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags) - caddr_t buf; - caddr_t lim; - u_int32_t spi, flags; - u_int wsize, auth, enc; -{ - struct sadb_sa *p; - u_int len; - - p = (void *)buf; - len = sizeof(struct sadb_sa); - - if (buf + len > lim) - return NULL; - - memset(p, 0, len); - 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_state = SADB_SASTATE_LARVAL; - p->sadb_sa_auth = auth; - p->sadb_sa_encrypt = enc; - p->sadb_sa_flags = flags; - p->sadb_sa_natt_port = port; - - return(buf + len); -} -#endif /* * set data into sadb_address. @@ -2532,19 +2046,13 @@ pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags) * prefixlen is in bits. */ static caddr_t -pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto) - caddr_t buf; - caddr_t lim; - u_int exttype; - struct sockaddr *saddr; - u_int prefixlen; - u_int ul_proto; +pfkey_setsadbaddr(caddr_t buf, caddr_t lim, u_int exttype, struct sockaddr_storage *saddr, u_int prefixlen, u_int ul_proto) { struct sadb_address *p; u_int len; p = (void *)buf; - len = sizeof(struct sadb_address) + PFKEY_ALIGN8(sysdep_sa_len(saddr)); + len = sizeof(struct sadb_address) + PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)saddr)); if (buf + len > lim) return NULL; @@ -2556,7 +2064,7 @@ pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto) p->sadb_address_prefixlen = prefixlen; p->sadb_address_reserved = 0; - memcpy(p + 1, saddr, (size_t)sysdep_sa_len(saddr)); + memcpy(p + 1, saddr, (size_t)sysdep_sa_len((struct sockaddr *)saddr)); return(buf + len); } @@ -2566,11 +2074,7 @@ pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto) * OUT: the pointer of buf + len. */ static caddr_t -pfkey_setsadbkey(buf, lim, type, key, keylen) - caddr_t buf; - caddr_t lim; - caddr_t key; - u_int type, keylen; +pfkey_setsadbkey(caddr_t buf, caddr_t lim, u_int type, caddr_t key, u_int keylen) { struct sadb_key *p; u_int len; @@ -2597,11 +2101,8 @@ pfkey_setsadbkey(buf, lim, type, key, keylen) * OUT: the pointer of buf + len. */ static caddr_t -pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime) - caddr_t buf; - caddr_t lim; - u_int type; - u_int32_t l_alloc, l_bytes, l_addtime, l_usetime; +pfkey_setsadblifetime(caddr_t buf, caddr_t lim, u_int type, u_int32_t l_alloc, + u_int32_t l_bytes, u_int32_t l_addtime, u_int32_t l_usetime) { struct sadb_lifetime *p; u_int len; @@ -2638,16 +2139,40 @@ pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime) return buf + len; } +static caddr_t +pfkey_setsadbipsecif(caddr_t buf, caddr_t lim, char *internal_if, char *outgoing_if, char *ipsec_if, int init_disabled) +{ + struct sadb_x_ipsecif *p; + u_int len; + + p = (void *)buf; + len = sizeof(struct sadb_x_ipsecif); + + if (buf + len > lim) + return NULL; + + memset(p, 0, len); + p->sadb_x_ipsecif_len = PFKEY_UNIT64(len); + p->sadb_x_ipsecif_exttype = SADB_X_EXT_IPSECIF; + + if (internal_if != NULL) + strncpy(p->sadb_x_ipsecif_internal_if, internal_if, sizeof(p->sadb_x_ipsecif_internal_if)); + if (outgoing_if != NULL) + strncpy(p->sadb_x_ipsecif_outgoing_if, outgoing_if, sizeof(p->sadb_x_ipsecif_outgoing_if)); + if (ipsec_if != NULL) + strncpy(p->sadb_x_ipsecif_ipsec_if, ipsec_if, sizeof(p->sadb_x_ipsecif_ipsec_if)); + + p->sadb_x_ipsecif_init_disabled = init_disabled; + + return (buf + len); +} + /* * copy secasvar data into sadb_address. * `buf' must has been allocated sufficiently. */ static caddr_t -pfkey_setsadbxsa2(buf, lim, mode0, reqid) - caddr_t buf; - caddr_t lim; - u_int32_t mode0; - u_int32_t reqid; +pfkey_setsadbxsa2(caddr_t buf, caddr_t lim, u_int32_t mode0, u_int32_t reqid, u_int always_expire) { struct sadb_x_sa2 *p; u_int8_t mode = mode0 & 0xff; @@ -2664,17 +2189,17 @@ pfkey_setsadbxsa2(buf, lim, mode0, reqid) p->sadb_x_sa2_exttype = SADB_X_EXT_SA2; p->sadb_x_sa2_mode = mode; p->sadb_x_sa2_reqid = reqid; + p->sadb_x_sa2_alwaysexpire = always_expire; +#ifdef SADB_X_EXT_SA2_DELETE_ON_DETACH + p->sadb_x_sa2_flags |= SADB_X_EXT_SA2_DELETE_ON_DETACH; +#endif /* SADB_X_EXT_SA2_DELETE_ON_DETACH */ return(buf + len); } #ifdef SADB_X_EXT_NAT_T_TYPE static caddr_t -pfkey_set_natt_type(buf, lim, type, l_natt_type) - caddr_t buf; - caddr_t lim; - u_int type; - u_int8_t l_natt_type; +pfkey_set_natt_type(caddr_t buf, caddr_t lim, u_int type, u_int8_t l_natt_type) { struct sadb_x_nat_t_type *p; u_int len; @@ -2694,11 +2219,7 @@ pfkey_set_natt_type(buf, lim, type, l_natt_type) } static caddr_t -pfkey_set_natt_port(buf, lim, type, l_natt_port) - caddr_t buf; - caddr_t lim; - u_int type; - u_int16_t l_natt_port; +pfkey_set_natt_port(caddr_t buf, caddr_t lim, u_int type, u_int16_t l_natt_port) { struct sadb_x_nat_t_port *p; u_int len; @@ -2720,11 +2241,7 @@ pfkey_set_natt_port(buf, lim, type, l_natt_port) #ifdef SADB_X_EXT_NAT_T_FRAG static caddr_t -pfkey_set_natt_frag(buf, lim, type, l_natt_frag) - caddr_t buf; - caddr_t lim; - u_int type; - u_int16_t l_natt_frag; +pfkey_set_natt_frag(caddr_t buf, caddr_t lim, u_int type, u_int16_t l_natt_frag) { struct sadb_x_nat_t_frag *p; u_int len; @@ -2744,6 +2261,7 @@ pfkey_set_natt_frag(buf, lim, type, l_natt_frag) } #endif + static caddr_t pfkey_setsadbsession_id (caddr_t buf, caddr_t lim, @@ -2785,7 +2303,7 @@ pfkey_setsadbsastats (caddr_t buf, if (!stats || !max_stats) return NULL; - p = (__typeof__(p))buf; + p = ALIGNED_CAST(__typeof__(p))buf; // Wcast-align fix - buffer passed to here is malloc'd message buffer list_len = sizeof(*stats) * max_stats; len = sizeof(*p) + PFKEY_ALIGN8(list_len);