The following provides address pools for iked. It's nothing fancy, but
it seems to work, at least in the cursory testing done against the
Windows 7 client.

Each policy gets it's own pool, configured by "config address <start
ip> - <end ip>".
There is a hard limit of 65536 addresses (8kb) per pool, which should be plenty.
There is NO ipv6 support, partly because I'm not really sure how or
why it would be needed.
A request for a specific ip that is available in the pool will be honoured.

Comments please!

--Ryan Slack


Index: addr_pool.c
===================================================================
RCS file: addr_pool.c
diff -N addr_pool.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ addr_pool.c 7 Jun 2013 03:05:46 -0000
@@ -0,0 +1,188 @@
+
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <err.h>
+
+#include "iked.h"
+
+int
+addr_pool_init_mask(struct addr_pool* pool,
+                   struct sockaddr_storage *address, u_int8_t prefixlengh)
+{
+       struct sockaddr_in      *a4;
+       /* struct sockaddr_in6  *a6; */
+
+       if(pool == NULL) return(-1);
+
+       memcpy(&pool->addr, address, sizeof(pool->addr));
+
+       switch(address->ss_family){
+       case AF_INET:
+               if (!(16 < prefixlengh && prefixlengh < 30)) {
+                       log_warnx("%s: prefixlengh (%d) out of range [16:30]",
+                                 __func__,prefixlengh);
+                       return(-1);
+               }
+               //pool->mask = prefixlen2mask(prefixlengh);
+               pool->size = (1<<(32 - prefixlengh)) - 2;
+
+               a4 = (struct sockaddr_in *)&pool->addr;
+               a4->sin_addr.s_addr = ntohl(a4->sin_addr.s_addr) + 1;
+               a4->sin_addr.s_addr = htonl(a4->sin_addr.s_addr);
+
+               break;
+       case AF_INET6:
+       default:
+               errno = EAFNOSUPPORT;
+               log_warn("%s: ",__func__);
+               return (-1);
+       }
+
+       return(0);
+}
+
+int
+addr_pool_init_range(struct addr_pool* pool,
+                    struct sockaddr_storage *start,
+                    struct sockaddr_storage *end)
+{
+       struct sockaddr_in      *a4, *b4;
+       //struct sockaddr_in6   *a6, *b6;
+       uint32_t size_l;
+
+       if(pool == NULL || start == NULL || end == NULL) return(-1);
+
+       if (start->ss_family != end->ss_family) {
+               log_debug("%s: address family mismatch", __func__);
+               return (-1);
+       }
+
+
+       switch(start->ss_family){
+       case AF_INET:
+               a4 = (struct sockaddr_in *)start;
+               b4 = (struct sockaddr_in *)end;
+
+               size_l = ntohl(b4->sin_addr.s_addr) -
ntohl(a4->sin_addr.s_addr) + 1;
+
+               if ( size_l > ADDR_POOL_SIZE_MAX ) {
+                       log_warnx("%s: size (%d) out of range
(%d)",__func__, size_l, ADDR_POOL_SIZE_MAX);
+                       return(-1);
+               }
+               pool->size = size_l;
+
+               break;
+       case AF_INET6:
+       default:
+               errno = EAFNOSUPPORT;
+               log_warn("%s: ", __func__);
+               return (-1);
+       }
+
+       memcpy(&pool->addr, start, sizeof(pool->addr));
+
+       return(0);
+}
+
+
+int
+addr_pool_alloc(struct addr_pool* pool)
+{
+       if((pool->pool = bit_alloc(pool->size))==NULL)
+               return (-1);
+
+       log_debug("%s: %s+%d", __func__,
+                 print_host(&pool->addr, NULL, 0), pool->size);
+
+       return(0);
+}
+
+int
+addr_pool_free(struct addr_pool* pool){
+       if(pool->size)
+               free(pool->pool);
+       return (0);
+}
+
+int
+addr_pool_reqest(struct addr_pool* pool, struct sockaddr_storage *address)
+{
+       struct sockaddr_in *a4;
+       //struct sockaddr_in6 *sa6,*pa6;
+       u_int32_t h_addr;
+       int32_t i;
+       if(pool->addr.ss_family != address->ss_family){
+               log_debug("%s: address family mismatch", __func__);
+               return(-1);
+       }
+       switch(pool->addr.ss_family){
+       case AF_INET:
+               a4 = ((struct sockaddr_in *)address);
+               h_addr = ntohl(((struct
sockaddr_in*)&pool->addr)->sin_addr.s_addr);
+               i = ntohl(a4->sin_addr.s_addr) - h_addr;
+               if (0 <= i && (uint32_t)i < pool->size &&
!bit_test(pool->pool,i)) {
+                       bit_set(pool->pool,i);
+               } else {
+                       bit_ffc(pool->pool,pool->size,&i);
+                       bit_set(pool->pool,i);
+                       a4->sin_addr.s_addr = htonl(h_addr + i);
+               }
+               log_debug("%s: assigned %s [%d]", __func__,
+                         print_host(address, NULL, 0), i);
+
+               break;
+       case AF_INET6:
+       default:
+               errno = EAFNOSUPPORT;
+               log_warn("%s: ", __func__);
+               return (-1);
+       }
+
+       return (0);
+}
+
+int
+addr_pool_release(struct addr_pool* pool, struct sockaddr_storage *address)
+{
+       struct sockaddr_in *a4;
+       //struct sockaddr_in6 *sa6,pa6;
+       u_int32_t h_addr;
+       int32_t i;
+
+       if (pool->addr.ss_family != address->ss_family) {
+               log_warnx("%s: address family mismatch", __func__);
+               return(-1);
+       }
+
+       switch(pool->addr.ss_family){
+       case AF_INET:
+               a4 = ((struct sockaddr_in *)address);
+               //if (a4->sin_addr.s_addr == 0x) return (-1);
+               h_addr = ntohl(((struct
sockaddr_in*)&pool->addr)->sin_addr.s_addr);
+               i = ntohl(a4->sin_addr.s_addr) - h_addr;
+               if (0 <= i && (uint32_t)i < pool->size &&
bit_test(pool->pool,i)) {
+                       bit_clear(pool->pool,i);
+                       log_debug("%s: released %s [%d]", __func__,
+                                 print_host(address, NULL, 0), i);
+
+               } else {
+                       log_debug("%s: %s is not from pool %s+%d", __func__,
+                                 print_host(address, NULL, 0),
+                                 print_host(&pool->addr, NULL, 0), pool->size);
+                       return (-1);
+               }
+               break;
+       case AF_INET6:
+       default:
+               errno = EAFNOSUPPORT;
+               log_warn("%s: ", __func__);
+               return (-1);
+       }
+
+       return (0);
+}
Index: addr_pool.h
===================================================================
RCS file: addr_pool.h
diff -N addr_pool.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ addr_pool.h 7 Jun 2013 03:05:46 -0000
@@ -0,0 +1,41 @@
+
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <bitstring.h>
+
+#ifndef _ADDR_POOL_H
+#define _ADDR_POOL_H
+
+/* 8kb bitstring */
+#define ADDR_POOL_SIZE_MAX 65536
+
+struct addr_pool{
+       struct sockaddr_storage  addr;
+       u_int32_t                size;
+       bitstr_t                *pool;
+};
+
+int
+addr_pool_init_mask(struct addr_pool* pool,
+                   struct sockaddr_storage *address,
+                   u_int8_t prefixlengh);
+
+int
+addr_pool_init_range(struct addr_pool *pool,
+                    struct sockaddr_storage *start,
+                    struct sockaddr_storage *end);
+
+int
+addr_pool_alloc(struct addr_pool* pool);
+
+int
+addr_pool_free(struct addr_pool* pool);
+
+int
+addr_pool_reqest(struct addr_pool* pool, struct sockaddr_storage *address);
+
+int
+addr_pool_release(struct addr_pool* pool, struct sockaddr_storage *address);
+
+#endif /* _ADDR_POOL_H */
Index: config.c
===================================================================
RCS file: /cvs/src/sbin/iked/config.c,v
retrieving revision 1.20
diff -u -p -r1.20 config.c
--- config.c    21 Mar 2013 04:30:14 -0000      1.20
+++ config.c    7 Jun 2013 03:05:46 -0000
@@ -134,6 +134,11 @@ config_free_sa(struct iked *env, struct
                free(sa->sa_eapid);
        ibuf_release(sa->sa_eapmsk);

+       if (sa->sa_policy->pol_addr_pool.size &&
+           sa->sa_cp.cfg_type == IKEV2_CFG_INTERNAL_IP4_ADDRESS)
+               addr_pool_release(&sa->sa_policy->pol_addr_pool,
+                                 &sa->sa_cp.cfg.address.addr);
+
        free(sa);
 }

@@ -173,6 +178,7 @@ config_free_policy(struct iked *env, str
  remove:
        config_free_proposals(&pol->pol_proposals, 0);
        config_free_flows(env, &pol->pol_flows);
+       addr_pool_free(&pol->pol_addr_pool);
        free(pol);
 }

@@ -696,6 +702,9 @@ config_getpolicy(struct iked *env, struc

                RB_INSERT(iked_flows, &pol->pol_flows, flow);
        }
+
+       addr_pool_alloc(&pol->pol_addr_pool);
+

        TAILQ_INSERT_TAIL(&env->sc_policies, pol, pol_entry);

Index: iked.h
===================================================================
RCS file: /cvs/src/sbin/iked/iked.h,v
retrieving revision 1.56
diff -u -p -r1.56 iked.h
--- iked.h      8 Jan 2013 10:38:19 -0000       1.56
+++ iked.h      7 Jun 2013 03:05:46 -0000
@@ -16,13 +16,17 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */

+#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/tree.h>
 #include <sys/queue.h>
 #include <imsg.h>
+#include <event.h>
+

 #include "types.h"
 #include "dh.h"
+#include "addr_pool.h"

 #ifndef _IKED_H
 #define _IKED_H
@@ -266,6 +270,8 @@ struct iked_policy {
        struct iked_cfg                  pol_cfg[IKED_CFG_MAX];
        u_int                            pol_ncfg;

+       struct addr_pool                 pol_addr_pool;
+
        struct iked_lifetime             pol_lifetime;

        struct iked_sapeers              pol_sapeers;
@@ -356,7 +362,7 @@ struct iked_sa {
        u_int                            sa_stateinit;  /* SA_INIT */
        u_int                            sa_statevalid; /* IKE_AUTH */

-       int                              sa_cp;         /* XXX */
+       struct iked_cfg                  sa_cp;

        struct iked_policy              *sa_policy;
        struct timeval                   sa_timecreated;
Index: ikev2.c
===================================================================
RCS file: /cvs/src/sbin/iked/ikev2.c,v
retrieving revision 1.82
diff -u -p -r1.82 ikev2.c
--- ikev2.c     21 Mar 2013 04:30:14 -0000      1.82
+++ ikev2.c     7 Jun 2013 03:05:47 -0000
@@ -952,7 +952,7 @@ ikev2_init_ike_auth(struct iked *env, st
        len = ibuf_size(sa->sa_localauth.id_buf) + sizeof(*auth);

        /* CP payload */
-       if (sa->sa_cp) {
+       if (sa->sa_cp.cfg_action) {
                if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_CP) == -1)
                        goto done;

@@ -1396,12 +1396,13 @@ ikev2_add_cp(struct iked *env, struct ik
        struct sockaddr_in      *in4;
        struct sockaddr_in6     *in6;
        u_int8_t                 prefixlen;
+       u_int32_t                mask;

        if ((cp = ibuf_advance(buf, sizeof(*cp))) == NULL)
                return (-1);
        len = sizeof(*cp);

-       switch (sa->sa_cp) {
+       switch (sa->sa_cp.cfg_action) {
        case IKEV2_CP_REQUEST:
                cp->cp_type = IKEV2_CP_REPLY;
                break;
@@ -1409,34 +1410,61 @@ ikev2_add_cp(struct iked *env, struct ik
        case IKEV2_CP_SET:
        case IKEV2_CP_ACK:
                /* Not yet supported */
+               log_debug("%s: action 0x%04x not yet supported", __func__,
+                         sa->sa_cp.cfg_action);
                return (-1);
        }
-
+       log_debug("%s: pol->pol_ncfg = %d", __func__,pol->pol_ncfg);
        for (i = 0; i < pol->pol_ncfg; i++) {
                ikecfg = &pol->pol_cfg[i];
                if (ikecfg->cfg_action != cp->cp_type)
                        continue;

+               log_debug("%s: %s", __func__,
+                         print_map(ikecfg->cfg_type, ikev2_cfg_map));
+
                if ((cfg = ibuf_advance(buf, sizeof(*cfg))) == NULL)
                        return (-1);

                cfg->cfg_type = htobe16(ikecfg->cfg_type);
                len += sizeof(*cfg);

+               in4 = NULL;
+
                switch (ikecfg->cfg_type) {
                case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
+                       log_debug("%s: INTERNAL_IP4_ADDRESS reply", __func__);
+                       if(pol->pol_addr_pool.size &&
+                          sa->sa_cp.cfg.address.addr.ss_family == AF_INET){
+                               if (addr_pool_reqest(&pol->pol_addr_pool,
+
&sa->sa_cp.cfg.address.addr) == -1)
+                                       return (-1);
+                               in4 = ((struct
sockaddr_in*)&sa->sa_cp.cfg.address.addr);
+                       }
                case IKEV2_CFG_INTERNAL_IP4_NETMASK:
                case IKEV2_CFG_INTERNAL_IP4_DNS:
                case IKEV2_CFG_INTERNAL_IP4_NBNS:
                case IKEV2_CFG_INTERNAL_IP4_DHCP:
                case IKEV2_CFG_INTERNAL_IP4_SERVER:
                        /* 4 bytes IPv4 address */
-                       in4 = (struct sockaddr_in *)&ikecfg->cfg.address.addr;
+                       if (in4 == NULL)
+                               in4 = (struct sockaddr_in
*)&ikecfg->cfg.address.addr;
                        cfg->cfg_length = htobe16(4);
                        if (ibuf_add(buf, &in4->sin_addr.s_addr, 4) == -1)
                                return (-1);
                        len += 4;
                        break;
+               case IKEV2_CFG_INTERNAL_IP4_SUBNET:
+                       /* 4 bytes IPv4 address + 4 bytes IPv4 mask + */
+                       in4 = (struct sockaddr_in *)&ikecfg->cfg.address.addr;
+                       mask = prefixlen2mask(ikecfg->cfg.address.addr_mask);
+                       cfg->cfg_length = htobe16(8);
+                       if (ibuf_add(buf, &in4->sin_addr.s_addr, 4) == -1)
+                               return (-1);
+                       if (ibuf_add(buf, &mask, 4) == -1)
+                               return (-1);
+                       len += 8;
+                       break;
                case IKEV2_CFG_INTERNAL_IP6_DNS:
                case IKEV2_CFG_INTERNAL_IP6_NBNS:
                case IKEV2_CFG_INTERNAL_IP6_DHCP:
@@ -1449,6 +1477,7 @@ ikev2_add_cp(struct iked *env, struct ik
                        len += 16;
                        break;
                case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
+               case IKEV2_CFG_INTERNAL_IP6_SUBNET:
                        /* 16 bytes IPv6 address + 1 byte prefix length */
                        in6 = (struct sockaddr_in6 *)&ikecfg->cfg.address.addr;
                        cfg->cfg_length = htobe16(17);
@@ -1469,6 +1498,7 @@ ikev2_add_cp(struct iked *env, struct ik
                }
        }

+       log_debug("%s: length %d", __func__, len);
        return (len);
 }

@@ -1962,7 +1992,7 @@ ikev2_resp_ike_auth(struct iked *env, st
        len = ibuf_size(sa->sa_localauth.id_buf) + sizeof(*auth);

        /* CP payload */
-       if (sa->sa_cp) {
+       if (sa->sa_cp.cfg_action) {
                if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_CP) == -1)
                        goto done;

Index: ikev2_pld.c
===================================================================
RCS file: /cvs/src/sbin/iked/ikev2_pld.c,v
retrieving revision 1.31
diff -u -p -r1.31 ikev2_pld.c
--- ikev2_pld.c 21 Mar 2013 04:30:14 -0000      1.31
+++ ikev2_pld.c 7 Jun 2013 03:05:47 -0000
@@ -1046,6 +1046,9 @@ ikev2_pld_cp(struct iked *env, struct ik
        size_t                   len, i;
        u_int8_t                *msgbuf = ibuf_data(msg->msg_data);
        struct iked_sa          *sa = msg->msg_sa;
+        struct iked_cfg         *ikecfg;
+        struct sockaddr_in      *in4;
+        struct sockaddr_in6     *in6;

        memcpy(&cp, msgbuf + offset, sizeof(cp));
        offset += sizeof(cp);
@@ -1061,9 +1064,45 @@ ikev2_pld_cp(struct iked *env, struct ik
                cfg = (struct ikev2_cfg *)(buf + i);

                log_debug("%s: %s 0x%04x length %d", __func__,
-                   print_map(betoh16(cfg->cfg_type), ikev2_cfg_map),
-                   betoh16(cfg->cfg_type),
-                   betoh16(cfg->cfg_length));
+                         print_map(betoh16(cfg->cfg_type), ikev2_cfg_map),
+                         betoh16(cfg->cfg_type),
+                         betoh16(cfg->cfg_length));
+
+               if(ikev2_msg_frompeer(msg) && sa &&
+                  cp.cp_type == IKEV2_CP_REQUEST){
+
+                       ikecfg = &sa->sa_cp;
+
+                       switch(betoh16(cfg->cfg_type)) {
+                       case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
+                               /* 4 bytes IPv4 address */
+                               in4 = (struct sockaddr_in *)
+                                       &ikecfg->cfg.address.addr;
+                               in4->sin_len = sizeof(*in4);
+                               in4->sin_family = AF_INET;
+                               ikecfg->cfg.address.addr_af = AF_INET;
+                               if (cfg->cfg_length >= 4){
+                                       memcpy(&in4->sin_addr.s_addr,buf, 4);
+                               }
+                               ikecfg->cfg_type =
IKEV2_CFG_INTERNAL_IP4_ADDRESS;
+                               break;
+
+                       case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
+                               /* 16 bytes IPv6 address */
+                               in6 = (struct sockaddr_in6 *)
+                                       &ikecfg->cfg.address.addr;
+                               in6->sin6_len = sizeof(*in6);
+                               in6->sin6_family = AF_INET6;
+                               ikecfg->cfg.address.addr_af = AF_INET6;
+
+                               if (cfg->cfg_length >= 16){
+                                       memcpy(&in6->sin6_addr.s6_addr,buf, 16);
+                               }else{
+                                       bzero(&in6->sin6_addr.s6_addr, 16);
+                               }
+                               break;
+                       }
+               }

                i += betoh16(cfg->cfg_length) + sizeof(*cfg);
        }
@@ -1072,7 +1111,7 @@ ikev2_pld_cp(struct iked *env, struct ik
                return (0);

        if (sa)
-               sa->sa_cp = cp.cp_type;
+               sa->sa_cp.cfg_action = cp.cp_type;

        return (0);
 }
Index: parse.y
===================================================================
RCS file: /cvs/src/sbin/iked/parse.y,v
retrieving revision 1.30
diff -u -p -r1.30 parse.y
--- parse.y     21 Mar 2013 04:30:14 -0000      1.30
+++ parse.y     7 Jun 2013 03:05:48 -0000
@@ -266,7 +266,8 @@ const struct ipsec_xf cpxfs[] = {
        { "protected-subnet", IKEV2_CFG_INTERNAL_IP4_SUBNET,    AF_INET },
        { "protected-subnet", IKEV2_CFG_INTERNAL_IP6_SUBNET,    AF_INET6 },
        { "access-server", IKEV2_CFG_INTERNAL_IP4_SERVER,       AF_INET },
-       { "access-server", IKEV2_CFG_INTERNAL_IP6_SERVER,       AF_INET6 }
+       { "access-server", IKEV2_CFG_INTERNAL_IP6_SERVER,       AF_INET6 },
+       { NULL }
 };

 const struct iked_lifetime deflifetime = {
@@ -321,7 +322,7 @@ int                  create_ike(char *, int, u_int8_t,
                             struct ipsec_mode *, u_int8_t,
                             u_int8_t, char *, char *, struct iked_lifetime *,
                             struct iked_auth *, struct ipsec_filters *,
-                            struct ipsec_addr_wrap *);
+                            struct ipsec_hosts *, struct ipsec_addr_wrap *);
 int                     create_user(const char *, const char *);
 int                     get_id_type(char *);
 u_int8_t                x2i(unsigned char *);
@@ -344,6 +345,7 @@ typedef struct {
                struct ipsec_hosts       peers;
                struct ipsec_addr_wrap  *anyhost;
                struct ipsec_addr_wrap  *host;
+               struct ipsec_hosts       pool;
                struct ipsec_addr_wrap  *cfg;
                struct {
                        char            *srcid;
@@ -367,7 +369,7 @@ typedef struct {
 %token FILENAME AUTHXF PRFXF ENCXF ERROR IKEV2 IKESA CHILDSA
 %token PASSIVE ACTIVE ANY TAG TAP PROTO LOCAL GROUP NAME CONFIG EAP USER
 %token IKEV1 FLOW SA TCPMD5 TUNNEL TRANSPORT COUPLE DECOUPLE SET
-%token INCLUDE LIFETIME BYTES INET INET6 QUICK SKIP DEFAULT
+%token INCLUDE LIFETIME BYTES INET INET6 QUICK SKIP DEFAULT ADDRESS
 %token <v.string>              STRING
 %token <v.number>              NUMBER
 %type  <v.string>              string
@@ -392,6 +394,7 @@ typedef struct {
 %type  <v.number>              byte_spec time_spec
 %type  <v.string>              name
 %type  <v.cfg>                 cfg ikecfg ikecfgvals
+%type  <v.pool>                cfg_pool pool
 %%

 grammar                : /* empty */
@@ -437,13 +440,31 @@ user              : USER STRING STRING            {
                ;

 ikev2rule      : IKEV2 name ikeflags satype af proto hosts_list peers
-                   ike_sa child_sa ids lifetime ikeauth ikecfg filters {
+                   ike_sa child_sa ids lifetime ikeauth cfg_pool
ikecfg filters {
                        if (create_ike($2, $5, $6, $7, &$8, $9, $10, $4, $3,
-                           $11.srcid, $11.dstid, &$12, &$13, $15, $14) == -1)
+                           $11.srcid, $11.dstid, &$12, &$13, $16,
&$14, $15) == -1)
                                YYERROR;
                }
                ;

+
+cfg_pool       : CONFIG ADDRESS pool           { $$ = $3; }
+               ;
+
+pool           : ANY                           {
+                       $$.src = host_any();
+                       $$.dst = NULL;
+               }
+               | host_spec             {
+                       $$.src = $1;
+                       $$.dst = NULL;
+               }
+               | host_spec '-' host_spec       {
+                       $$.src = $1;
+                       $$.dst = $3;
+               }
+               ;
+
 ikecfg         : /* empty */                   { $$ = NULL; }
                | ikecfgvals                    { $$ = $1; }
                ;
@@ -1053,6 +1074,7 @@ lookup(char *s)
        /* this has to be sorted always */
        static const struct keywords keywords[] = {
                { "active",             ACTIVE },
+               { "address",            ADDRESS },
                { "ah",                 AH },
                { "any",                ANY },
                { "auth",               AUTHXF },
@@ -2321,7 +2343,7 @@ create_ike(char *name, int af, u_int8_t
     struct ipsec_mode *ipsec_sa, u_int8_t saproto,
     u_int8_t flags, char *srcid, char *dstid, struct iked_lifetime *lt,
     struct iked_auth *authtype, struct ipsec_filters *filter,
-    struct ipsec_addr_wrap *ikecfg)
+    struct ipsec_hosts *pool, struct ipsec_addr_wrap *ikecfg)
 {
        struct ipsec_addr_wrap  *ipa, *ipb;
        struct iked_policy       pol;
@@ -2542,6 +2564,36 @@ create_ike(char *name, int af, u_int8_t

                pol.pol_nflows++;
                RB_INSERT(iked_flows, &pol.pol_flows, &flows[j]);
+       }
+
+
+       if (pool && (pol.pol_af != AF_UNSPEC) &&
+           ((pool->src && (pool->src->af != AF_UNSPEC) &&
+             (pool->src->af != pol.pol_af)) ||
+            (pool->dst && (pool->dst->af != AF_UNSPEC) &&
+             (pool->dst->af != pol.pol_af))))
+               fatalx("create_ike: policy address family mismatch");
+
+       if (pool && pool->src){
+               if (pool->dst != NULL) {
+                       if (addr_pool_init_range(&pol.pol_addr_pool,
+                                                &pool->src->address,
+                                                &pool->dst->address) == -1)
+                               return (-1);
+
+               } else if (pool->src->mask) {
+                       if (addr_pool_init_mask(&pol.pol_addr_pool,
+                                                &pool->src->address,
+                                                pool->src->mask) == -1)
+                               return (-1);
+               } else {
+                       // XXX build from hosts/flows
+                       return (-1);
+               }
+               pool->src->type = IKEV2_CFG_INTERNAL_IP4_ADDRESS;
+               pool->src->action = IKEV2_CP_REPLY;     /* XXX */
+               ikecfg->tail->next = pool->src;
+               ikecfg->tail = pool->src->tail;
        }

        for (j = 0, ipa = ikecfg; ipa; ipa = ipa->next, j++) {

Reply via email to