]> git.saurik.com Git - apple/ipsec.git/blobdiff - ipsec-tools/Common/pfkey.c
ipsec-292.tar.gz
[apple/ipsec.git] / ipsec-tools / Common / pfkey.c
index 026ccd835efa85035232e1f5dd0f80ae9612f836..409333d2a9791c580db7cf5562d8d2e0f55c6237 100644 (file)
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/socket.h>
-#ifdef __APPLE__
-#include <System/net/pfkeyv2.h>
-#else
 #include <net/pfkeyv2.h>
-#endif
+#include <sys/sysctl.h>
 #include <netinet/in.h>
 #ifdef HAVE_NETINET6_IPSEC
 #  include <netinet6/ipsec.h>
 #include <string.h>
 #include <errno.h>
 #include <stdio.h>
+#include <fcntl.h>
 
+#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);