summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/isakmpd/ike_auth.c36
-rw-r--r--sbin/isakmpd/ike_phase_1.c38
-rw-r--r--sbin/isakmpd/ipsec.c326
-rw-r--r--sbin/isakmpd/ipsec.h17
-rw-r--r--sbin/isakmpd/pf_encap.c52
-rw-r--r--sbin/isakmpd/pf_key_v2.c498
-rw-r--r--sbin/isakmpd/policy.c123
-rw-r--r--sbin/isakmpd/util.c124
-rw-r--r--sbin/isakmpd/util.h6
9 files changed, 856 insertions, 364 deletions
diff --git a/sbin/isakmpd/ike_auth.c b/sbin/isakmpd/ike_auth.c
index 6e95d4b6e22..91e19ac1475 100644
--- a/sbin/isakmpd/ike_auth.c
+++ b/sbin/isakmpd/ike_auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ike_auth.c,v 1.49 2001/06/28 21:41:58 angelos Exp $ */
+/* $OpenBSD: ike_auth.c,v 1.50 2001/06/29 04:11:59 ho Exp $ */
/* $EOM: ike_auth.c,v 1.59 2000/11/21 00:21:31 angelos Exp $ */
/*
@@ -336,7 +336,6 @@ pre_shared_gen_skeyid (struct exchange *exchange, size_t *sz)
u_int8_t *key;
u_int8_t *buf = 0;
size_t keylen;
- in_addr_t addr;
/*
* If we're the responder and have the initiator's ID (which is the
@@ -349,16 +348,16 @@ pre_shared_gen_skeyid (struct exchange *exchange, size_t *sz)
switch (exchange->id_i[0])
{
case IPSEC_ID_IPV4_ADDR:
- buf = malloc (16);
+ util_ntoa ((char **)&buf, AF_INET, exchange->id_i +
+ ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
if (!buf)
- {
- log_error ("pre_shared_gen_skeyid: malloc (16) failed");
- return 0;
- }
- addr = htonl (decode_32 (exchange->id_i + ISAKMP_ID_DATA_OFF -
- ISAKMP_GEN_SZ));
- inet_ntop (AF_INET, &addr, buf, 16);
+ return 0;
break;
+ case IPSEC_ID_IPV6_ADDR:
+ util_ntoa ((char **)&buf, AF_INET6, exchange->id_i +
+ ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
+ if (!buf)
+ return 0;
case IPSEC_ID_FQDN:
case IPSEC_ID_USER_FQDN:
@@ -901,7 +900,6 @@ rsa_sig_encode_hash (struct message *msg)
u_int8_t *id;
size_t id_len;
int idtype;
- in_addr_t addr;
id = initiator ? exchange->id_i : exchange->id_r;
id_len = initiator ? exchange->id_i_len : exchange->id_r_len;
@@ -1013,14 +1011,16 @@ rsa_sig_encode_hash (struct message *msg)
switch (id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ])
{
case IPSEC_ID_IPV4_ADDR:
- buf2 = malloc (16);
+ util_ntoa ((char **)&buf2, AF_INET, id + ISAKMP_ID_DATA_OFF -
+ ISAKMP_GEN_SZ);
if (!buf2)
- {
- log_error ("rsa_sig_encode_hash: malloc (16) failed");
- return 0;
- }
- addr = htonl (decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ));
- inet_ntop (AF_INET, &addr, buf2, 16);
+ return 0;
+ break;
+ case IPSEC_ID_IPV6_ADDR:
+ util_ntoa ((char **)&buf2, AF_INET6, id + ISAKMP_ID_DATA_OFF -
+ ISAKMP_GEN_SZ);
+ if (!buf2)
+ return 0;
break;
case IPSEC_ID_FQDN:
diff --git a/sbin/isakmpd/ike_phase_1.c b/sbin/isakmpd/ike_phase_1.c
index 5b6958b4436..d3a32c1923e 100644
--- a/sbin/isakmpd/ike_phase_1.c
+++ b/sbin/isakmpd/ike_phase_1.c
@@ -1,9 +1,10 @@
-/* $OpenBSD: ike_phase_1.c,v 1.26 2001/06/05 10:50:55 angelos Exp $ */
+/* $OpenBSD: ike_phase_1.c,v 1.27 2001/06/29 04:12:00 ho Exp $ */
/* $EOM: ike_phase_1.c,v 1.31 2000/12/11 23:47:56 niklas Exp $ */
/*
* Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved.
* Copyright (c) 1999, 2000 Angelos D. Keromytis. All rights reserved.
+ * Copyright (c) 2001 Håkan Olsson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -821,12 +822,12 @@ ike_phase_1_send_ID (struct message *msg)
switch (id_type)
{
case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
msg->transport->vtbl->get_src (msg->transport, &src, &src_len);
/* Already in network byteorder. */
- memcpy (buf + ISAKMP_ID_DATA_OFF,
- &((struct sockaddr_in *)src)->sin_addr.s_addr,
- sizeof (in_addr_t));
+ memcpy (buf + ISAKMP_ID_DATA_OFF, sockaddr_data (src),
+ sockaddr_len (src));
break;
case IPSEC_ID_FQDN:
case IPSEC_ID_USER_FQDN:
@@ -843,12 +844,18 @@ ike_phase_1_send_ID (struct message *msg)
else
{
msg->transport->vtbl->get_src (msg->transport, &src, &src_len);
- /* XXX Assumes IPv4. */
- SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV4_ADDR);
+ switch (src->sa_family)
+ {
+ case AF_INET:
+ SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV4_ADDR);
+ break;
+ case AF_INET6:
+ SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV6_ADDR);
+ break;
+ }
/* Already in network byteorder. */
- memcpy (buf + ISAKMP_ID_DATA_OFF,
- &((struct sockaddr_in *)src)->sin_addr.s_addr,
- sizeof (in_addr_t));
+ memcpy (buf + ISAKMP_ID_DATA_OFF, sockaddr_data (src),
+ sockaddr_len (src));
}
if (message_add_payload (msg, ISAKMP_PAYLOAD_ID, buf, sz, 1))
@@ -950,9 +957,20 @@ ike_phase_1_recv_ID (struct message *msg)
return -1;
}
- /* XXX IPv4 specific */
inet_pton (AF_INET, p, rid);
break;
+ case IPSEC_ID_IPV6_ADDR:
+ p = conf_get_str (rs, "Address");
+ if (!p)
+ {
+ log_print ("ike_phase_1_recv_ID: failed to get Address in "
+ "Remote-ID section [%s]", rs);
+ free (rid);
+ return -1;
+ }
+
+ inet_pton (AF_INET6, p, rid);
+ break;
case IPSEC_ID_FQDN:
case IPSEC_ID_USER_FQDN:
case IPSEC_ID_KEY_ID:
diff --git a/sbin/isakmpd/ipsec.c b/sbin/isakmpd/ipsec.c
index bb96f2bc841..a7f076b93bf 100644
--- a/sbin/isakmpd/ipsec.c
+++ b/sbin/isakmpd/ipsec.c
@@ -1,9 +1,10 @@
-/* $OpenBSD: ipsec.c,v 1.46 2001/06/27 03:31:40 angelos Exp $ */
+/* $OpenBSD: ipsec.c,v 1.47 2001/06/29 04:12:00 ho Exp $ */
/* $EOM: ipsec.c,v 1.143 2000/12/11 23:57:42 niklas Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
* Copyright (c) 2001 Angelos D. Keromytis. All rights reserved.
+ * Copyright (c) 2001 Håkan Olsson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -184,7 +185,7 @@ int16_t script_new_group_mode[] = {
};
struct dst_spi_proto_arg {
- in_addr_t dst;
+ struct sockaddr *dst;
u_int32_t spi;
u_int8_t proto;
};
@@ -207,12 +208,14 @@ ipsec_sa_check (struct sa *sa, void *v_arg)
return 0;
sa->transport->vtbl->get_dst (sa->transport, &dst, &dstlen);
- if (((struct sockaddr_in *)dst)->sin_addr.s_addr == arg->dst)
+ if (memcmp (sockaddr_data (dst), sockaddr_data (arg->dst),
+ sockaddr_len (dst)) == 0)
incoming = 0;
else
{
sa->transport->vtbl->get_src (sa->transport, &src, &srclen);
- if (((struct sockaddr_in *)src)->sin_addr.s_addr == arg->dst)
+ if (memcmp (sockaddr_data (src), sockaddr_data (arg->dst),
+ sockaddr_len (src)) == 0)
incoming = 1;
else
return 0;
@@ -228,7 +231,7 @@ ipsec_sa_check (struct sa *sa, void *v_arg)
/* Find an SA with a "name" of DST, SPI & PROTO. */
struct sa *
-ipsec_sa_lookup (in_addr_t dst, u_int32_t spi, u_int8_t proto)
+ipsec_sa_lookup (struct sockaddr *dst, u_int32_t spi, u_int8_t proto)
{
struct dst_spi_proto_arg arg = { dst, spi, proto };
@@ -250,10 +253,19 @@ ipsec_sa_check_flow (struct sa *sa, void *v_arg)
|| (sa->flags & (SA_FLAG_READY | SA_FLAG_REPLACED)) != SA_FLAG_READY)
return 0;
- return isa->src_net == isa2->src_net && isa->src_mask == isa2->src_mask
- && isa->dst_net == isa2->dst_net && isa->dst_mask == isa2->dst_mask
- && isa->tproto == isa2->tproto && isa->sport == isa2->sport
- && isa->dport == isa2->dport;
+ if (isa->tproto != isa2->tproto || isa->sport != isa2->sport
+ || isa->dport != isa2->dport)
+ return 0;
+
+ return isa->src_net->sa_family == isa2->src_net->sa_family
+ && memcmp (sockaddr_data (isa->src_net), sockaddr_data (isa2->src_net),
+ sockaddr_len (isa->src_net)) == 0
+ && memcmp (sockaddr_data (isa->src_mask), sockaddr_data (isa2->src_mask),
+ sockaddr_len (isa->src_mask)) == 0
+ && memcmp (sockaddr_data (isa->dst_net), sockaddr_data (isa2->dst_net),
+ sockaddr_len (isa->dst_net)) == 0
+ && memcmp (sockaddr_data (isa->dst_mask), sockaddr_data (isa2->dst_mask),
+ sockaddr_len (isa->dst_mask)) == 0;
}
/*
@@ -269,6 +281,9 @@ ipsec_finalize_exchange (struct message *msg)
struct ipsec_exch *ie = exchange->data;
struct sa *sa = 0, *old_sa;
struct proto *proto, *last_proto = 0;
+#ifdef USE_DEBUG
+ char *addr1, *addr2, *mask1, *mask2;
+#endif
switch (exchange->phase)
{
@@ -328,13 +343,34 @@ ipsec_finalize_exchange (struct message *msg)
/* Responder is source, initiator is destination. */
ipsec_set_network (ie->id_cr, ie->id_ci, isa);
+#ifdef USE_DEBUG
+ if (sockaddr2text (isa->src_net, &addr1, 0))
+ addr1 = 0;
+ if (sockaddr2text (isa->src_mask, &mask1, 0))
+ mask1 = 0;
+ if (sockaddr2text (isa->dst_net, &addr2, 0))
+ addr2 = 0;
+ if (sockaddr2text (isa->dst_mask, &mask2, 0))
+ mask2 = 0;
+
LOG_DBG ((LOG_EXCHANGE, 50,
"ipsec_finalize_exchange: "
"src %x %x dst %x %x tproto %u sport %u dport %u",
- ntohl (isa->src_net), ntohl (isa->src_mask),
- ntohl (isa->dst_net), ntohl (isa->dst_mask),
+ addr1 ? addr1 : "<???>" , mask1 ? mask1 : "<???>",
+ addr2 ? addr2 : "<???>" , mask2 ? mask2 : "<???>",
ntohs (isa->tproto), isa->sport, ntohs (isa->dport)));
+ if (addr1)
+ free (addr1);
+ if (mask1)
+ free (mask1);
+ if (addr2)
+ free (addr2);
+ if (mask2)
+ free (mask2);
+
+#endif /* USE_DEBUG */
+
/*
* If this is not an SA acquired by the kernel, it needs
* to have a SPD entry (a.k.a. flow) set up.
@@ -359,59 +395,118 @@ ipsec_set_network (u_int8_t *src_id, u_int8_t *dst_id, struct ipsec_sa *isa)
{
int id;
- /* Set source address. */
+ /* Set source address/mask. */
id = GET_ISAKMP_ID_TYPE (src_id);
switch (id)
{
case IPSEC_ID_IPV4_ADDR:
- memcpy (&isa->src_net, src_id + ISAKMP_ID_DATA_OFF, sizeof isa->src_net);
- isa->src_mask = htonl (0xffffffff);
- memcpy (&isa->tproto,
- src_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PROTO_OFF,
- IPSEC_ID_PROTO_LEN);
- memcpy (&isa->sport, src_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PORT_OFF,
- IPSEC_ID_PORT_LEN);
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ isa->src_net =
+ (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in));
+ /* XXX this may fail ! */
+ isa->src_net->sa_family = AF_INET;
+ isa->src_net->sa_len = sizeof (struct sockaddr_in);
+ isa->src_mask =
+ (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in));
+ /* XXX this may fail ! */
+ isa->src_mask->sa_family = AF_INET;
+ isa->src_mask->sa_len = sizeof (struct sockaddr_in);
+ break;
+
+ case IPSEC_ID_IPV6_ADDR:
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ isa->src_net =
+ (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in6));
+ /* XXX this may fail ! */
+ isa->src_net->sa_family = AF_INET6;
+ isa->src_net->sa_len = sizeof (struct sockaddr_in6);
+ isa->src_mask =
+ (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in6));
+ /* XXX this may fail ! */
+ isa->src_mask->sa_family = AF_INET6;
+ isa->src_mask->sa_len = sizeof (struct sockaddr_in6);
break;
+ }
+
+ /* Net */
+ memcpy (sockaddr_data (isa->src_net), src_id + ISAKMP_ID_DATA_OFF,
+ sockaddr_len (isa->src_net));
+ /* Mask */
+ switch (id)
+ {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
+ memset (sockaddr_data (isa->src_mask), 0xff,
+ sockaddr_len (isa->src_mask));
+ break;
case IPSEC_ID_IPV4_ADDR_SUBNET:
- memcpy (&isa->src_net, src_id + ISAKMP_ID_DATA_OFF, sizeof isa->src_net);
- memcpy (&isa->src_mask,
- src_id + ISAKMP_ID_DATA_OFF + sizeof isa->src_net,
- sizeof isa->src_mask);
- memcpy (&isa->tproto,
- src_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PROTO_OFF,
- IPSEC_ID_PROTO_LEN);
- memcpy (&isa->sport, src_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PORT_OFF,
- IPSEC_ID_PORT_LEN);
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ memcpy (sockaddr_data (isa->src_mask), src_id + ISAKMP_ID_DATA_OFF +
+ sockaddr_len (isa->src_net), sockaddr_len (isa->src_mask));
break;
- }
+ }
+
+ memcpy (&isa->tproto, dst_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PROTO_OFF,
+ IPSEC_ID_PROTO_LEN);
+ memcpy (&isa->dport, dst_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PORT_OFF,
+ IPSEC_ID_PORT_LEN);
/* Set destination address. */
id = GET_ISAKMP_ID_TYPE (dst_id);
switch (id)
{
case IPSEC_ID_IPV4_ADDR:
- memcpy (&isa->dst_net, dst_id + ISAKMP_ID_DATA_OFF, sizeof isa->dst_net);
- isa->dst_mask = htonl (0xffffffff);
- memcpy (&isa->tproto,
- dst_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PROTO_OFF,
- IPSEC_ID_PROTO_LEN);
- memcpy (&isa->dport, dst_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PORT_OFF,
- IPSEC_ID_PORT_LEN);
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ isa->dst_net =
+ (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in));
+ /* XXX this may fail ! */
+ isa->dst_net->sa_family = AF_INET;
+ isa->dst_net->sa_len = sizeof (struct sockaddr_in);
+ isa->dst_mask =
+ (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in));
+ /* XXX this may fail ! */
+ isa->dst_mask->sa_family = AF_INET;
+ isa->dst_mask->sa_len = sizeof (struct sockaddr_in);
+ break;
+ case IPSEC_ID_IPV6_ADDR:
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ isa->dst_net =
+ (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in6));
+ /* XXX this may fail ! */
+ isa->dst_net->sa_family = AF_INET6;
+ isa->dst_net->sa_len = sizeof (struct sockaddr_in6);
+ isa->dst_mask =
+ (struct sockaddr *)calloc (1, sizeof (struct sockaddr_in6));
+ /* XXX this may fail ! */
+ isa->dst_mask->sa_family = AF_INET6;
+ isa->dst_mask->sa_len = sizeof (struct sockaddr_in6);
break;
+ }
+ /* Net */
+ memcpy (sockaddr_data (isa->dst_net), dst_id + ISAKMP_ID_DATA_OFF,
+ sockaddr_len (isa->dst_net));
+
+ /* Mask */
+ switch (id)
+ {
+ case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
+ memset (sockaddr_data (isa->dst_mask), 0xff,
+ sockaddr_len (isa->dst_mask));
+ break;
case IPSEC_ID_IPV4_ADDR_SUBNET:
- memcpy (&isa->dst_net, dst_id + ISAKMP_ID_DATA_OFF, sizeof isa->dst_net);
- memcpy (&isa->dst_mask,
- dst_id + ISAKMP_ID_DATA_OFF + sizeof isa->dst_net,
- sizeof isa->dst_mask);
- memcpy (&isa->tproto,
- dst_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PROTO_OFF,
- IPSEC_ID_PROTO_LEN);
- memcpy (&isa->dport, dst_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PORT_OFF,
- IPSEC_ID_PORT_LEN);
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ memcpy (sockaddr_data (isa->dst_mask), dst_id + ISAKMP_ID_DATA_OFF +
+ sockaddr_len (isa->dst_net), sockaddr_len (isa->dst_mask));
break;
}
+
+ memcpy (&isa->tproto, dst_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PROTO_OFF,
+ IPSEC_ID_PROTO_LEN);
+ memcpy (&isa->dport, dst_id + ISAKMP_ID_DOI_DATA_OFF + IPSEC_ID_PORT_OFF,
+ IPSEC_ID_PORT_LEN);
}
/* Free the DOI-specific exchange data pointed to by VIE. */
@@ -454,6 +549,14 @@ ipsec_free_sa_data (void *visa)
{
struct ipsec_sa *isa = visa;
+ if (isa->src_net)
+ free (isa->src_net);
+ if (isa->src_mask)
+ free (isa->src_mask);
+ if (isa->dst_net)
+ free (isa->dst_net);
+ if (isa->dst_mask)
+ free (isa->dst_mask);
if (isa->skeyid_a)
free (isa->skeyid_a);
if (isa->skeyid_d)
@@ -604,13 +707,24 @@ ipsec_validate_id_information (u_int8_t type, u_int8_t *extra, u_int8_t *buf,
{
case IPSEC_ID_IPV4_ADDR:
LOG_DBG_BUF ((LOG_MESSAGE, 40, "ipsec_validate_id_information: IPv4",
- buf, 4));
+ buf, sizeof (struct in_addr)));
+ break;
+
+ case IPSEC_ID_IPV6_ADDR:
+ LOG_DBG_BUF ((LOG_MESSAGE, 40, "ipsec_validate_id_information: IPv6",
+ buf, sizeof (struct in6_addr)));
break;
case IPSEC_ID_IPV4_ADDR_SUBNET:
LOG_DBG_BUF ((LOG_MESSAGE, 40,
"ipsec_validate_id_information: IPv4 network/netmask",
- buf, 8));
+ buf, 2 * sizeof (struct in_addr)));
+ break;
+
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ LOG_DBG_BUF ((LOG_MESSAGE, 40,
+ "ipsec_validate_id_information: IPv6 network/netmask",
+ buf, 2 * sizeof (struct in6_addr)));
break;
default:
@@ -768,7 +882,6 @@ static void
ipsec_delete_spi_list (struct sockaddr *addr, u_int8_t proto,
u_int8_t *spis, int nspis, char *type)
{
- u_int32_t iaddr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
struct sa *sa;
int i;
@@ -789,7 +902,7 @@ ipsec_delete_spi_list (struct sockaddr *addr, u_int8_t proto,
{
u_int32_t spi = ((u_int32_t *)spis)[i];
- sa = ipsec_sa_lookup (iaddr, spi, proto);
+ sa = ipsec_sa_lookup (addr, spi, proto);
}
if (sa == NULL)
@@ -1568,8 +1681,8 @@ ipsec_keymat_length (struct proto *proto)
* Return 0 on success and -1 on failure.
*/
int
-ipsec_get_id (char *section, int *id, struct in_addr *addr,
- struct in_addr *mask, u_int8_t *tproto, u_int16_t *port)
+ipsec_get_id (char *section, int *id, struct sockaddr **addr,
+ struct sockaddr **mask, u_int8_t *tproto, u_int16_t *port)
{
char *type, *address, *netmask;
@@ -1584,6 +1697,7 @@ ipsec_get_id (char *section, int *id, struct in_addr *addr,
switch (*id)
{
case IPSEC_ID_IPV4_ADDR:
+ case IPSEC_ID_IPV6_ADDR:
address = conf_get_str (section, "Address");
if (!address)
{
@@ -1592,7 +1706,7 @@ ipsec_get_id (char *section, int *id, struct in_addr *addr,
return -1;
}
- if (!inet_aton (address, addr))
+ if (text2sockaddr (address, NULL, addr))
{
log_print ("ipsec_get_id: invalid address %s in section %s", section,
address);
@@ -1613,6 +1727,7 @@ ipsec_get_id (char *section, int *id, struct in_addr *addr,
#endif
case IPSEC_ID_IPV4_ADDR_SUBNET:
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
address = conf_get_str (section, "Network");
if (!address)
{
@@ -1621,7 +1736,7 @@ ipsec_get_id (char *section, int *id, struct in_addr *addr,
return -1;
}
- if (!inet_aton (address, addr))
+ if (text2sockaddr (address, NULL, addr))
{
log_print ("ipsec_get_id: invalid section %s network %s", section,
address);
@@ -1636,7 +1751,7 @@ ipsec_get_id (char *section, int *id, struct in_addr *addr,
return -1;
}
- if (!inet_aton (netmask, mask))
+ if (text2sockaddr (netmask, NULL, mask))
{
log_print ("ipsec_id_build: invalid section %s network %s", section,
netmask);
@@ -1649,12 +1764,6 @@ ipsec_get_id (char *section, int *id, struct in_addr *addr,
break;
#ifdef notyet
- case IPSEC_ID_IPV6_ADDR:
- return -1;
-
- case IPSEC_ID_IPV6_ADDR_SUBNET:
- return -1;
-
case IPSEC_ID_IPV4_RANGE:
return -1;
@@ -1681,42 +1790,17 @@ ipsec_get_id (char *section, int *id, struct in_addr *addr,
}
static void
-ipsec_ipv4toa (char *buf, size_t size, u_int8_t *addr)
-{
-#ifdef HAVE_GETNAMEINFO
- struct sockaddr_storage from;
- struct sockaddr_in *sfrom = (struct sockaddr_in *)&from;
- socklen_t fromlen = sizeof from;
-
- memset (&from, 0, fromlen);
- sfrom->sin_len = sizeof *sfrom;
- sfrom->sin_family = AF_INET;
- memcpy (&sfrom->sin_addr.s_addr, addr, sizeof sfrom->sin_addr.s_addr);
-
- if (getnameinfo ((struct sockaddr *)sfrom, sfrom->sin_len, buf, size, NULL,
- 0, NI_NUMERICHOST) != 0)
- {
- log_print ("ipsec_ipv4toa: getnameinfo () failed");
- strcpy (buf, "<error>");
- }
-#else
- strncpy (buf, inet_ntoa (*(struct in_addr *)addr), size - 1);
- buf[size - 1] = '\0';
-#endif /* HAVE_GETNAMEINFO */
-}
-
-static void
ipsec_decode_id (u_int8_t *buf, int size, u_int8_t *id, size_t id_len,
int isakmpform)
{
int id_type;
- char ntop[NI_MAXHOST], ntop2[NI_MAXHOST];
+ char *addr = 0, *mask = 0;
if (id)
{
if (!isakmpform)
{
- /* exchanges and SA's dont carry the IDs in ISAKMP form */
+ /* exchanges and SAs dont carry the IDs in ISAKMP form */
id -= ISAKMP_ID_TYPE_OFF;
id_len += ISAKMP_ID_TYPE_OFF;
}
@@ -1725,18 +1809,22 @@ ipsec_decode_id (u_int8_t *buf, int size, u_int8_t *id, size_t id_len,
switch (id_type)
{
case IPSEC_ID_IPV4_ADDR:
- ipsec_ipv4toa (ntop, sizeof ntop, id + ISAKMP_ID_DATA_OFF);
+ util_ntoa (&addr, AF_INET, id + ISAKMP_ID_DATA_OFF);
snprintf (buf, size, "%08x: %s",
- decode_32 (id + ISAKMP_ID_DATA_OFF), ntop);
+ decode_32 (id + ISAKMP_ID_DATA_OFF), addr);
break;
case IPSEC_ID_IPV4_ADDR_SUBNET:
- ipsec_ipv4toa (ntop, sizeof ntop, id + ISAKMP_ID_DATA_OFF);
- ipsec_ipv4toa (ntop2, sizeof ntop2, id + ISAKMP_ID_DATA_OFF + 4);
+ util_ntoa (&addr, AF_INET, id + ISAKMP_ID_DATA_OFF);
+ util_ntoa (&mask, AF_INET, id + ISAKMP_ID_DATA_OFF + 4);
snprintf (buf, size, "%08x/%08x: %s/%s",
decode_32 (id + ISAKMP_ID_DATA_OFF),
decode_32 (id + ISAKMP_ID_DATA_OFF + 4),
- ntop, ntop2);
+ addr, mask);
break;
+ case IPSEC_ID_IPV6_ADDR:
+ /* XXX */
+ break;
+
case IPSEC_ID_FQDN:
case IPSEC_ID_USER_FQDN:
/* String is not NUL terminated, be careful */
@@ -1745,7 +1833,6 @@ ipsec_decode_id (u_int8_t *buf, int size, u_int8_t *id, size_t id_len,
memcpy (buf, id + ISAKMP_ID_DATA_OFF, id_len);
buf[id_len] = '\0';
break;
- /* XXX - IPV6 et al */
default:
snprintf (buf, size, "<type unknown: %x>", id_type);
break;
@@ -1753,6 +1840,10 @@ ipsec_decode_id (u_int8_t *buf, int size, u_int8_t *id, size_t id_len,
}
else
snprintf (buf, size, "<no id>");
+ if (addr)
+ free (addr);
+ if (mask)
+ free (mask);
}
char *
@@ -1777,25 +1868,21 @@ ipsec_decode_ids (char *fmt, u_int8_t *id1, size_t id1_len,
u_int8_t *
ipsec_build_id (char *section, size_t *sz)
{
- struct in_addr addr, mask;
+ struct sockaddr *addr, *mask;
u_int8_t *p;
- int id;
+ int id, subnet = 0;
u_int8_t tproto = 0;
u_int16_t port = 0;
if (ipsec_get_id (section, &id, &addr, &mask, &tproto, &port))
return 0;
- *sz = ISAKMP_ID_SZ;
- switch (id)
- {
- case IPSEC_ID_IPV4_ADDR:
- *sz += sizeof addr;
- break;
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- *sz += sizeof addr + sizeof mask;
- break;
- }
+ if (id == IPSEC_ID_IPV4_ADDR_SUBNET || id == IPSEC_ID_IPV6_ADDR_SUBNET)
+ subnet = 1;
+
+ *sz = ISAKMP_ID_SZ + sockaddr_len (addr);
+ if (subnet)
+ *sz += sockaddr_len (mask);
p = malloc (*sz);
if (!p)
@@ -1807,20 +1894,13 @@ ipsec_build_id (char *section, size_t *sz)
SET_ISAKMP_ID_TYPE (p, id);
SET_ISAKMP_ID_DOI_DATA (p, "\000\000\000");
- switch (id)
- {
- case IPSEC_ID_IPV4_ADDR:
- encode_32 (p + ISAKMP_ID_DATA_OFF, ntohl (addr.s_addr));
- SET_IPSEC_ID_PROTO (p + ISAKMP_ID_DOI_DATA_OFF, tproto);
- SET_IPSEC_ID_PORT (p + ISAKMP_ID_DOI_DATA_OFF, port);
- break;
- case IPSEC_ID_IPV4_ADDR_SUBNET:
- encode_32 (p + ISAKMP_ID_DATA_OFF, ntohl (addr.s_addr));
- encode_32 (p + ISAKMP_ID_DATA_OFF + 4, ntohl (mask.s_addr));
- SET_IPSEC_ID_PROTO (p + ISAKMP_ID_DOI_DATA_OFF, tproto);
- SET_IPSEC_ID_PORT (p + ISAKMP_ID_DOI_DATA_OFF, port);
- break;
- }
+ memcpy (p + ISAKMP_ID_DATA_OFF, sockaddr_data (addr), sockaddr_len (addr));
+ if (subnet)
+ memcpy (p + ISAKMP_ID_DATA_OFF + sockaddr_len (addr),
+ sockaddr_data (mask), sockaddr_len (mask));
+
+ SET_IPSEC_ID_PROTO (p + ISAKMP_ID_DOI_DATA_OFF, tproto);
+ SET_IPSEC_ID_PORT (p + ISAKMP_ID_DOI_DATA_OFF, port);
return p;
}
@@ -2101,9 +2181,13 @@ ipsec_id_size (char *section, u_int8_t *id)
switch (*id)
{
case IPSEC_ID_IPV4_ADDR:
- return sizeof (in_addr_t);
+ return sizeof (struct in_addr);
case IPSEC_ID_IPV4_ADDR_SUBNET:
- return 2 * sizeof (in_addr_t);
+ return 2 * sizeof (struct in_addr);
+ case IPSEC_ID_IPV6_ADDR:
+ return sizeof (struct in6_addr);
+ case IPSEC_ID_IPV6_ADDR_SUBNET:
+ return 2 * sizeof (struct in6_addr);
case IPSEC_ID_FQDN:
case IPSEC_ID_USER_FQDN:
case IPSEC_ID_KEY_ID:
diff --git a/sbin/isakmpd/ipsec.h b/sbin/isakmpd/ipsec.h
index 5f46c5d0599..3b60305b8b3 100644
--- a/sbin/isakmpd/ipsec.h
+++ b/sbin/isakmpd/ipsec.h
@@ -1,9 +1,10 @@
-/* $OpenBSD: ipsec.h,v 1.16 2001/06/27 03:31:41 angelos Exp $ */
+/* $OpenBSD: ipsec.h,v 1.17 2001/06/29 04:12:00 ho Exp $ */
/* $EOM: ipsec.h,v 1.42 2000/12/03 07:58:20 angelos Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
* Copyright (c) 1999 Angelos D. Keromytis. All rights reserved.
+ * Copyright (c) 2001 Håkan Olsson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -110,10 +111,10 @@ struct ipsec_sa {
u_int16_t group_desc;
/* Tunnel parameters. These are in network byte order. */
- in_addr_t src_net;
- in_addr_t src_mask;
- in_addr_t dst_net;
- in_addr_t dst_mask;
+ struct sockaddr *src_net;
+ struct sockaddr *src_mask;
+ struct sockaddr *dst_net;
+ struct sockaddr *dst_mask;
u_int8_t tproto;
u_int16_t sport;
u_int16_t dport;
@@ -143,8 +144,8 @@ extern int ipsec_esp_authkeylength (struct proto *);
extern int ipsec_esp_enckeylength (struct proto *);
extern int ipsec_fill_in_hash (struct message *msg);
extern int ipsec_gen_g_x (struct message *);
-extern int ipsec_get_id (char *, int *, struct in_addr *, struct in_addr *,
- u_int8_t *, u_int16_t *);
+extern int ipsec_get_id (char *, int *, struct sockaddr **,
+ struct sockaddr **, u_int8_t *, u_int16_t *);
extern ssize_t ipsec_id_size (char *, u_int8_t *);
extern void ipsec_init (void);
extern int ipsec_initial_contact (struct message *msg);
@@ -152,7 +153,7 @@ extern int ipsec_is_attribute_incompatible (u_int16_t, u_int8_t *, u_int16_t,
void *);
extern int ipsec_keymat_length (struct proto *);
extern int ipsec_save_g_x (struct message *);
-extern struct sa *ipsec_sa_lookup (in_addr_t, u_int32_t, u_int8_t);
+extern struct sa *ipsec_sa_lookup (struct sockaddr *, u_int32_t, u_int8_t);
extern char *ipsec_decode_ids(char *, u_int8_t *, size_t, u_int8_t *, size_t,
int);
diff --git a/sbin/isakmpd/pf_encap.c b/sbin/isakmpd/pf_encap.c
index 14322ff8d53..f905180d320 100644
--- a/sbin/isakmpd/pf_encap.c
+++ b/sbin/isakmpd/pf_encap.c
@@ -1,8 +1,9 @@
-/* $OpenBSD: pf_encap.c,v 1.22 2001/06/27 03:31:42 angelos Exp $ */
+/* $OpenBSD: pf_encap.c,v 1.23 2001/06/29 04:12:00 ho Exp $ */
/* $EOM: pf_encap.c,v 1.73 2000/12/04 04:46:34 angelos Exp $ */
/*
* Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved.
+ * Copyright (c) 2001 Håkan Olsson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -724,11 +725,14 @@ pf_encap_enable_sa (struct sa *sa, struct sa *isakmp_sa)
/* Enable a flow. */
int
-pf_encap_enable_spi (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
- in_addr_t rmask, u_int8_t *spi, u_int8_t proto,
- in_addr_t dst)
+pf_encap_enable_spi (struct sockaddr *laddr, struct sockaddr *lmask,
+ struct sockaddr *raddr, struct sockaddr *rmask,
+ u_int8_t *spi, u_int8_t proto, in_addr_t dst)
{
struct encap_msghdr *emsg = 0;
+#ifdef USE_DEBUG
+ char *la_str, *lm_str, *ra_str, *rm_str;
+#endif
emsg = calloc (1, EMT_ENABLESPI_FLEN);
if (!emsg)
@@ -741,12 +745,34 @@ pf_encap_enable_spi (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
memcpy (&emsg->em_ena_spi, spi, sizeof emsg->em_ena_spi);
emsg->em_ena_dst.s_addr = dst;
+#ifdef USE_DEBUG
+ if (sockaddr2text (laddr, &la_str))
+ la_str = 0;
+ if (sockaddr2text (lmask, &lm_str))
+ lm_str = 0;
+ if (sockaddr2text (raddr, &ra_str))
+ ra_str = 0;
+ if (sockaddr2text (rmask, &rm_str))
+ rm_str = 0;
+
LOG_DBG ((LOG_SYSDEP, 50, "pf_encap_enable_spi: src %x %x dst %x %x",
- htonl (laddr), htonl (lmask), htonl (raddr), htonl (rmask)));
- emsg->em_ena_isrc.s_addr = laddr;
- emsg->em_ena_ismask.s_addr = lmask;
- emsg->em_ena_idst.s_addr = raddr;
- emsg->em_ena_idmask.s_addr = rmask;
+ la_str ? la_str : "<???>", lm_str : lm_str ? "<???>",
+ ra_str ? ra_str : "<???>", rm_str : rm_str ? "<???>"));
+
+ if (la_str)
+ free (la_str);
+ if (lm_str)
+ free (lm_str);
+ if (ra_str)
+ free (ra_str);
+ if (rm_str)
+ free (rm_str);
+#endif /* USE_DEBUG */
+
+ emsg->em_ena_isrc.s_addr = ((struct sockaddr_in *)laddr)->sin_addr.s_addr;
+ emsg->em_ena_ismask.s_addr = ((struct sockaddr_in *)lmask)->sin_addr.s_addr;
+ emsg->em_ena_idst.s_addr = ((struct sockaddr_in *)raddr)->sin_addr.s_addr;
+ emsg->em_ena_idmask.s_addr = ((struct sockaddr_in *)rmask)->sin_addr.s_addr;
emsg->em_ena_flags = ENABLE_FLAG_REPLACE;
/* XXX What if IPCOMP etc. comes along? */
@@ -903,7 +929,8 @@ void
pf_encap_connection_check (char *conn)
{
char *conf, *doi_str, *local_id, *remote_id, *peer, *address;
- struct in_addr laddr, lmask, raddr, rmask, gwaddr;
+ struct sockaddr *laddr, *lmask, *raddr, *rmask;
+ struct in_addr gwaddr;
int lid, rid, err;
u_int8_t tproto;
u_int16_t sport, dport;
@@ -974,7 +1001,10 @@ pf_encap_connection_check (char *conn)
if (err)
return;
- if (pf_encap_route (laddr.s_addr, lmask.s_addr, raddr.s_addr, rmask.s_addr,
+ if (pf_encap_route (((struct sockaddr_in *)laddr)->sin_addr.s_addr,
+ ((struct sockaddr_in *)lmask)->sin_addr.s_addr,
+ ((struct sockaddr_in *)raddr)->sin_addr.s_addr,
+ ((struct sockaddr_in *)rmask)->sin_addr.s_addr,
gwaddr.s_addr))
{
pf_encap_deregister_on_demand_connection (conn);
diff --git a/sbin/isakmpd/pf_key_v2.c b/sbin/isakmpd/pf_key_v2.c
index e4fbf459ddc..1011d6536fd 100644
--- a/sbin/isakmpd/pf_key_v2.c
+++ b/sbin/isakmpd/pf_key_v2.c
@@ -1,9 +1,10 @@
-/* $OpenBSD: pf_key_v2.c,v 1.67 2001/06/27 03:31:43 angelos Exp $ */
+/* $OpenBSD: pf_key_v2.c,v 1.68 2001/06/29 04:12:00 ho Exp $ */
/* $EOM: pf_key_v2.c,v 1.79 2000/12/12 00:33:19 niklas Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
* Copyright (c) 1999, 2000, 2001 Angelos D. Keromytis. All rights reserved.
+ * Copyright (c) 2001 Håkan Olsson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -53,20 +54,22 @@
#include <unistd.h>
#include <pwd.h>
#include <errno.h>
+#include <bitstring.h>
#include "sysdep.h"
+#include "cert.h"
#include "conf.h"
#include "exchange.h"
#include "ipsec.h"
#include "ipsec_num.h"
+#include "key.h"
#include "log.h"
#include "pf_key_v2.h"
#include "sa.h"
#include "timer.h"
#include "transport.h"
-#include "cert.h"
-#include "key.h"
+#include "util.h"
#ifdef USE_KEYNOTE
#include "policy.h"
@@ -647,10 +650,9 @@ pf_key_v2_get_spi (size_t *sz, u_int8_t proto, struct sockaddr *src,
/* Setup the ADDRESS extensions. */
len = sizeof (struct sadb_address) + PF_KEY_V2_ROUND (srclen);
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
- memset (addr + 1, '\0', sizeof (struct sockaddr_in));
addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
#ifndef __OpenBSD__
@@ -659,18 +661,24 @@ pf_key_v2_get_spi (size_t *sz, u_int8_t proto, struct sockaddr *src,
#endif
addr->sadb_address_reserved = 0;
memcpy (addr + 1, src, srclen);
- /* XXX IPv4-specific. */
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ switch (((struct sockaddr *)(addr + 1))->sa_family)
+ {
+ case AF_INET:
+ ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
+ break;
+ }
if (pf_key_v2_msg_add (getspi, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
addr = 0;
len = sizeof (struct sadb_address) + PF_KEY_V2_ROUND (dstlen);
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
- memset (addr + 1, '\0', sizeof (struct sockaddr_in));
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
#ifndef __OpenBSD__
@@ -679,8 +687,15 @@ pf_key_v2_get_spi (size_t *sz, u_int8_t proto, struct sockaddr *src,
#endif
addr->sadb_address_reserved = 0;
memcpy (addr + 1, dst, dstlen);
- /* XXX IPv4-specific. */
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ switch (((struct sockaddr *)(addr + 1))->sa_family)
+ {
+ case AF_INET:
+ ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
+ break;
+ }
if (pf_key_v2_msg_add (getspi, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
@@ -761,7 +776,7 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming,
struct sockaddr *src, *dst;
struct sadb_ident *sid = 0;
char *pp;
- int dstlen, srclen, keylen, hashlen, err, idtype;
+ int srclen, dstlen, keylen, hashlen, err, idtype;
struct pf_key_v2_msg *update = 0, *ret = 0;
struct ipsec_proto *iproto = proto->data;
#if defined (SADB_X_CREDTYPE_NONE) || defined (SADB_X_AUTHTYPE_NONE)
@@ -771,6 +786,9 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming,
#ifdef KAME
struct sadb_x_sa2 ssa2;
#endif
+#ifdef USE_DEBUG
+ char *addr_str;
+#endif
msg.sadb_msg_type = incoming ? SADB_UPDATE : SADB_ADD;
switch (proto->proto)
@@ -1002,15 +1020,13 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming,
/*
* Setup the ADDRESS extensions.
- *
- * XXX Addresses have to be thought through. Assumes IPv4.
*/
if (incoming)
sa->transport->vtbl->get_dst (sa->transport, &src, &srclen);
else
sa->transport->vtbl->get_src (sa->transport, &src, &srclen);
len = sizeof *addr + PF_KEY_V2_ROUND (srclen);
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
@@ -1021,14 +1037,22 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming,
#endif
addr->sadb_address_reserved = 0;
memcpy (addr + 1, src, srclen);
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ switch (((struct sockaddr *)(addr + 1))->sa_family)
+ {
+ case AF_INET:
+ ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
+ break;
+ }
if (pf_key_v2_msg_add (update, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
addr = 0;
len = sizeof *addr + PF_KEY_V2_ROUND (dstlen);
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
@@ -1039,7 +1063,15 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming,
#endif
addr->sadb_address_reserved = 0;
memcpy (addr + 1, dst, dstlen);
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ switch (((struct sockaddr *)(addr + 1))->sa_family)
+ {
+ case AF_INET:
+ ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
+ break;
+ }
if (pf_key_v2_msg_add (update, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
@@ -1050,7 +1082,7 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming,
if (iproto->encap_mode == IPSEC_ENCAP_TUNNEL)
{
len = sizeof *addr + PF_KEY_V2_ROUND (dstlen);
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
@@ -1061,7 +1093,15 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming,
#endif
addr->sadb_address_reserved = 0;
memcpy (addr + 1, dst, dstlen);
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ switch (((struct sockaddr *)(addr + 1))->sa_family)
+ {
+ case AF_INET:
+ ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
+ break;
+ }
if (pf_key_v2_msg_add (update, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
@@ -1320,12 +1360,18 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming,
/* XXX Here can sensitivity extensions be setup. */
- /* XXX IPv4 specific. */
+#ifdef USE_DEBUG
+ if (sockaddr2text (dst, &addr_str, 0))
+ addr_str = 0;
+
LOG_DBG ((LOG_SYSDEP, 10, "pf_key_v2_set_spi: satype %d dst %s SPI 0x%x",
- msg.sadb_msg_satype,
- inet_ntoa (((struct sockaddr_in *)dst)->sin_addr),
+ msg.sadb_msg_satype, addr_str ? addr_str : "unknown",
ntohl (ssa.sadb_sa_spi)));
+ if (addr_str)
+ free (addr_str);
+#endif /* USE_DEBUG */
+
/*
* Although PF_KEY knows about expirations, it is unreliable per the specs
* thus we need to do them inside isakmpd as well.
@@ -1380,7 +1426,61 @@ pf_key_v2_set_spi (struct sa *sa, struct proto *proto, int incoming,
static __inline__ int
pf_key_v2_mask_to_bits (u_int32_t mask)
{
- return (33 - ffs (~mask + 1)) % 33;
+ u_int32_t hmask = ntohl (mask);
+ return (33 - ffs (~hmask + 1)) % 33;
+}
+
+static int
+pf_key_v2_mask6_to_bits (u_int8_t *mask)
+{
+ int n;
+ bit_ffc (mask, 128, &n);
+ return n;
+}
+
+static void
+pf_key_v2_setup_sockaddr (void *res, struct sockaddr *src,
+ struct sockaddr *dst, in_port_t port, int ingress)
+{
+ struct sockaddr_in *ip4_sa;
+ struct sockaddr_in6 *ip6_sa;
+ u_int8_t *p;
+
+ switch (src->sa_family)
+ {
+ case AF_INET:
+ ip4_sa = (struct sockaddr_in *)res;
+ ip4_sa->sin_family = AF_INET;
+ ip4_sa->sin_len = sizeof *ip4_sa;
+ ip4_sa->sin_port = port;
+ if (dst)
+ p = (u_int8_t *)(ingress ?
+ &((struct sockaddr_in *)src)->sin_addr.s_addr :
+ &((struct sockaddr_in *)dst)->sin_addr.s_addr);
+ else
+ p = (u_int8_t *)&((struct sockaddr_in *)src)->sin_addr.s_addr;
+ ip4_sa->sin_addr.s_addr = *((in_addr_t *)p);
+ break;
+
+ case AF_INET6:
+ ip6_sa = (struct sockaddr_in6 *)res;
+ ip6_sa->sin6_family = AF_INET6;
+ ip6_sa->sin6_len = sizeof *ip6_sa;
+ ip6_sa->sin6_port = port;
+ if (dst)
+ p = (u_int8_t *)(ingress ?
+ &((struct sockaddr_in6 *)src)->sin6_addr.s6_addr :
+ &((struct sockaddr_in6 *)dst)->sin6_addr.s6_addr);
+ else
+ p = (u_int8_t *)&((struct sockaddr_in6 *)src)->sin6_addr.s6_addr;
+ memcpy (ip6_sa->sin6_addr.s6_addr, p, sizeof (struct in6_addr));
+ break;
+
+ default:
+ log_print ("pf_key_v2_setup_sockaddr: unknown family %d\n",
+ src->sa_family);
+ break;
+ }
}
/*
@@ -1389,10 +1489,11 @@ pf_key_v2_mask_to_bits (u_int32_t mask)
* Should probably be moved to sysdep.c
*/
static int
-pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
- in_addr_t rmask, u_int8_t tproto, u_int16_t sport,
- u_int16_t dport, u_int8_t *spi, u_int8_t proto,
- in_addr_t dst, in_addr_t src, int delete, int ingress,
+pf_key_v2_flow (struct sockaddr *laddr, struct sockaddr *lmask,
+ struct sockaddr *raddr, struct sockaddr *rmask,
+ u_int8_t tproto, u_int16_t sport, u_int16_t dport,
+ u_int8_t *spi, u_int8_t proto, struct sockaddr *dst,
+ struct sockaddr *src, int delete, int ingress,
u_int8_t srcid_type, u_int8_t *srcid, int srcid_len,
u_int8_t dstid_type, u_int8_t *dstid, int dstid_len)
{
@@ -1409,6 +1510,9 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
struct pf_key_v2_msg *flow = 0, *ret = 0;
size_t len;
int err;
+#ifdef USE_DEBUG
+ char *laddr_str, *lmask_str, *raddr_str, *rmask_str;
+#endif
#if !defined (SADB_X_SAFLAGS_INGRESS_FLOW) && !defined (SADB_X_EXT_FLOW_TYPE)
if (ingress)
@@ -1517,98 +1621,74 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
/*
* Setup the ADDRESS extensions.
- *
- * XXX Addresses have to be thought through. Assumes IPv4.
*/
- len = sizeof *addr + PF_KEY_V2_ROUND (sizeof (struct sockaddr_in));
+ len = sizeof *addr + PF_KEY_V2_ROUND (src->sa_len);
#ifndef SADB_X_EXT_FLOW_TYPE
if (!delete || ingress)
#else
if (!delete)
#endif /* SADB_X_EXT_FLOW_TYPE */
{
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
addr->sadb_address_reserved = 0;
- memset (addr + 1, '\0', sizeof (struct sockaddr_in));
- ((struct sockaddr_in *)(addr + 1))->sin_len
- = sizeof (struct sockaddr_in);
- ((struct sockaddr_in *)(addr + 1))->sin_family = AF_INET;
#ifdef SADB_X_EXT_FLOW_TYPE
- ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr
- = ingress ? src : dst;
+ pf_key_v2_setup_sockaddr (addr + 1, src, dst, 0, ingress);
#else
- ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr = dst;
+ pf_key_v2_setup_sockaddr (addr + 1, dst, NULL, 0, 0);
#endif
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
addr = 0;
}
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_X_EXT_SRC_FLOW;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
addr->sadb_address_reserved = 0;
- memset (addr + 1, '\0', sizeof (struct sockaddr_in));
- ((struct sockaddr_in *)(addr + 1))->sin_len = sizeof (struct sockaddr_in);
- ((struct sockaddr_in *)(addr + 1))->sin_family = AF_INET;
- ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr = laddr;
- ((struct sockaddr_in *)(addr + 1))->sin_port = sport;
+ pf_key_v2_setup_sockaddr (addr + 1, laddr, NULL, sport, 0);
if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
addr = 0;
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_X_EXT_SRC_MASK;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
addr->sadb_address_reserved = 0;
- memset (addr + 1, '\0', sizeof (struct sockaddr_in));
- ((struct sockaddr_in *)(addr + 1))->sin_len = sizeof (struct sockaddr_in);
- ((struct sockaddr_in *)(addr + 1))->sin_family = AF_INET;
- ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr = lmask;
- ((struct sockaddr_in *)(addr + 1))->sin_port = sport ? 0xffff : 0;
+ pf_key_v2_setup_sockaddr (addr + 1, lmask, NULL, sport ? 0xffff : 0, 0);
if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
addr = 0;
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_X_EXT_DST_FLOW;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
addr->sadb_address_reserved = 0;
- memset (addr + 1, '\0', sizeof (struct sockaddr_in));
- ((struct sockaddr_in *)(addr + 1))->sin_len = sizeof (struct sockaddr_in);
- ((struct sockaddr_in *)(addr + 1))->sin_family = AF_INET;
- ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr = raddr;
- ((struct sockaddr_in *)(addr + 1))->sin_port = dport;
+ pf_key_v2_setup_sockaddr (addr + 1, raddr, NULL, sport, 0);
if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
addr = 0;
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_X_EXT_DST_MASK;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
addr->sadb_address_reserved = 0;
- memset (addr + 1, '\0', sizeof (struct sockaddr_in));
- ((struct sockaddr_in *)(addr + 1))->sin_len = sizeof (struct sockaddr_in);
- ((struct sockaddr_in *)(addr + 1))->sin_family = AF_INET;
- ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr = rmask;
- ((struct sockaddr_in *)(addr + 1))->sin_port = dport ? 0xffff : 0;
+ pf_key_v2_setup_sockaddr (addr + 1, rmask, NULL, sport ? 0xffff : 0, 0);
if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
@@ -1623,11 +1703,32 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
if (pf_key_v2_msg_add (flow, (struct sadb_ext *)&tprotocol, 0) == -1)
goto cleanup;
+#ifdef USE_DEBUG
+ if (sockaddr2text (laddr, &laddr_str, 0))
+ laddr_str = 0;
+ if (sockaddr2text (lmask, &lmask_str, 0))
+ lmask_str = 0;
+ if (sockaddr2text (raddr, &raddr_str, 0))
+ raddr_str = 0;
+ if (sockaddr2text (rmask, &rmask_str, 0))
+ rmask_str = 0;
+
LOG_DBG ((LOG_SYSDEP, 50,
"pf_key_v2_flow: src %x %x dst %x %x proto %u sport %u dport %u",
- ntohl (laddr), ntohl (lmask), ntohl (raddr), ntohl (rmask),
+ laddr_str ? laddr_str : "<???>", lmask_str ? laddr_str : "<???>",
+ raddr_str ? laddr_str : "<???>", rmask_str ? laddr_str : "<???>",
tproto, ntohs (sport), ntohs (dport)));
+ if (laddr_str)
+ free (laddr_str);
+ if (lmask_str)
+ free (lmask_str);
+ if (raddr_str)
+ free (raddr_str);
+ if (rmask_str)
+ free (rmask_str);
+#endif /* USE_DEBUG */
+
ret = pf_key_v2_call (flow);
pf_key_v2_msg_free (flow);
flow = 0;
@@ -1669,10 +1770,9 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
struct sadb_x_ipsecrequest *ipsecrequest;
struct sadb_x_sa2 ssa2;
struct sadb_address *addr = 0;
- struct sockaddr_in *saddr;
- u_int8_t
- policy_buf[sizeof *policy + sizeof *ipsecrequest + 2 * sizeof *saddr];
+ struct sockaddr *saddr;
struct pf_key_v2_msg *flow = 0, *ret = 0;
+ u_int8_t *policy_buf;
size_t len;
int err;
@@ -1692,47 +1792,70 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
/*
* Setup the ADDRESS extensions.
- *
- * XXX Addresses have to be thought through. Assumes IPv4.
*/
- len = sizeof *addr + PF_KEY_V2_ROUND (sizeof (struct sockaddr_in));
- addr = malloc (len);
+ len = sizeof *addr + PF_KEY_V2_ROUND (src->sa_len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
addr->sadb_address_proto = IPSEC_ULPROTO_ANY;
- addr->sadb_address_prefixlen = pf_key_v2_mask_to_bits (ntohl (lmask));
addr->sadb_address_reserved = 0;
- memset (addr + 1, '\0', sizeof (struct sockaddr_in));
- ((struct sockaddr_in *)(addr + 1))->sin_len = sizeof (struct sockaddr_in);
- ((struct sockaddr_in *)(addr + 1))->sin_family = AF_INET;
- ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr = laddr;
- ((struct sockaddr_in *)(addr + 1))->sin_port = IPSEC_PORT_ANY;
+ pf_key_v2_setup_sockaddr (addr + 1, laddr, NULL, IPSEC_PORT_ANY, 0);
+ switch (laddr->sa_family)
+ {
+ case AF_INET:
+ ip4_sa = (struct sockaddr_in *)lmask;
+ addr->sadb_address_prefixlen =
+ pf_key_v2_mask_to_bits (ip4_sa->sin_addr.in_addr);
+ break;
+ case AF_INET6:
+ ip6_sa = (struct sockaddr_in6 *)lmask;
+ addr->sadb_address_prefixlen =
+ pf_key_v2_mask6_to_bits (ip6_sa->sin6_addr.in6_addr);
+ break;
+ }
if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
addr = 0;
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
addr->sadb_address_len = len / PF_KEY_V2_CHUNK;
addr->sadb_address_proto = IPSEC_ULPROTO_ANY;
- addr->sadb_address_prefixlen = pf_key_v2_mask_to_bits (ntohl (rmask));
addr->sadb_address_reserved = 0;
- memset (addr + 1, '\0', sizeof (struct sockaddr_in));
- ((struct sockaddr_in *)(addr + 1))->sin_len = sizeof (struct sockaddr_in);
- ((struct sockaddr_in *)(addr + 1))->sin_family = AF_INET;
- ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr = raddr;
- ((struct sockaddr_in *)(addr + 1))->sin_port = IPSEC_PORT_ANY;
+ pf_key_v2_setup_sockaddr (addr + 1, raddr, NULL, IPSEC_PORT_ANY, 0);
+ switch (raddr->sa_family)
+ {
+ case AF_INET:
+ ip4_sa = (struct sockaddr_in *)rmask;
+ addr->sadb_address_prefixlen =
+ pf_key_v2_mask_to_bits (ip4_sa->sin_addr.in_addr);
+ break;
+ case AF_INET6:
+ ip6_sa = (struct sockaddr_in6 *)rmask;
+ addr->sadb_address_prefixlen =
+ pf_key_v2_mask6_to_bits (ip6_sa->sin6_addr.in6_addr);
+ break;
+ }
if (pf_key_v2_msg_add (flow, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
addr = 0;
/* Setup the POLICY extension. */
+ policy_buf = (u_int8_t *)calloc (1, sizeof *policy + sizeof *ipsecrequest +
+ 2 * sockaddr_len (src));
+ if (!policy_buf)
+ {
+ log_error ("pf_key_v2_flow: calloc %d failed", sizeof *policy +
+ sizeof *ipsecrequest + 2 * sockaddr_len (src));
+ goto cleanup;
+ }
+
policy = (struct sadb_x_policy *)policy_buf;
policy->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
policy->sadb_x_policy_len = sizeof policy_buf / PF_KEY_V2_CHUNK;
@@ -1746,7 +1869,7 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
/* Setup the IPSECREQUEST extension part. */
ipsecrequest = (struct sadb_x_ipsecrequest *)(policy + 1);
ipsecrequest->sadb_x_ipsecrequest_len
- = sizeof *ipsecrequest + 2 * sizeof *saddr;
+ = sizeof *ipsecrequest + 2 * sockaddr_len (src);
switch (proto)
{
case IPSEC_PROTO_IPSEC_ESP:
@@ -1764,26 +1887,45 @@ pf_key_v2_flow (in_addr_t laddr, in_addr_t lmask, in_addr_t raddr,
= ingress ? IPSEC_LEVEL_USE : IPSEC_LEVEL_REQUIRE;
ipsecrequest->sadb_x_ipsecrequest_reqid = 0; /* XXX */
- /* Add source and destination addresses. XXX IPv4 dependent */
- saddr = (struct sockaddr_in *)(ipsecrequest + 1);
- memset (saddr, '\0', sizeof *saddr);
- saddr->sin_len = sizeof (struct sockaddr_in);
- saddr->sin_family = AF_INET;
- saddr->sin_addr.s_addr = src;
- saddr->sin_port = 0;
-
- saddr++;
- memset (saddr, '\0', sizeof *saddr);
- saddr->sin_len = sizeof (struct sockaddr_in);
- saddr->sin_family = AF_INET;
- saddr->sin_addr.s_addr = dst;
- saddr->sin_port = 0;
-
+ /* Add source and destination addresses. */
+ saddr = (struct sockaddr *)(ipsecrequest + 1);
+ pf_key_v2_setup_sockaddr (saddr, src, NULL, 0, 0);
+ switch (src->sa_family)
+ {
+ case AF_INET:
+ saddr = (struct sockaddr_in *)saddr + 1;
+ break;
+ case AF_INET6:
+ saddr = (struct sockaddr_in6 *)saddr + 1;
+ break;
+ }
+ pf_key_v2_setup_sockaddr (saddr, dst, NULL, 0, 0);
if (pf_key_v2_msg_add (flow, (struct sadb_ext *)policy, 0) == -1)
goto cleanup;
+#ifdef USE_DEBUG
+ if (sockaddr2text (laddr, &laddr_str, 0))
+ laddr_str = 0;
+ if (sockaddr2text (lmask, &lmask_str, 0))
+ lmask_str = 0;
+ if (sockaddr2text (raddr, &raddr_str, 0))
+ raddr_str = 0;
+ if (sockaddr2text (rmask, &rmask_str, 0))
+ rmask_str = 0;
+
LOG_DBG ((LOG_SYSDEP, 50, "pf_key_v2_flow: src %x %x dst %x %x",
- ntohl (laddr), ntohl (lmask), ntohl (raddr), ntohl (rmask)));
+ laddr_str ? laddr_str : "<???>", lmask_str ? laddr_str : "<???>",
+ raddr_str ? laddr_str : "<???>", rmask_str ? laddr_str : "<???>"));
+
+ if (laddr_str)
+ free (laddr_str);
+ if (lmask_str)
+ free (lmask_str);
+ if (raddr_str)
+ free (raddr_str);
+ if (rmask_str)
+ free (rmask_str);
+#endif
ret = pf_key_v2_call (flow);
pf_key_v2_msg_free (flow);
@@ -1825,6 +1967,7 @@ pf_key_v2_convert_id (u_int8_t *id, int idlen, int *reslen, int *idtype)
{
u_int8_t *res = 0;
char addrbuf[ADDRESS_MAX + 5];
+ char *addr;
switch (id[0])
{
@@ -1864,7 +2007,7 @@ pf_key_v2_convert_id (u_int8_t *id, int idlen, int *reslen, int *idtype)
case IPSEC_ID_IPV6_ADDR: /* XXX CONNECTION ? */
if (inet_ntop (AF_INET6, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
addrbuf, ADDRESS_MAX) != NULL)
- *reslen = strlen (addrbuf) + 4;
+ *reslen = strlen (addrbuf) + 5;
strcat (addrbuf, "/128");
res = strdup (addrbuf);
if (!res)
@@ -1873,7 +2016,30 @@ pf_key_v2_convert_id (u_int8_t *id, int idlen, int *reslen, int *idtype)
return res;
case IPSEC_ID_IPV4_ADDR_SUBNET: /* XXX PREFIX */
+ addr = id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
+ if (inet_ntop (AF_INET, addr, addrbuf, ADDRESS_MAX) != NULL)
+ *reslen = strlen (addrbuf) + 4;
+ sprintf (addrbuf + strlen (addrbuf), "/%d",
+ pf_key_v2_mask_to_bits ((u_int32_t)*(addr +
+ sizeof (struct in_addr))));
+ res = strdup (addrbuf);
+ if (!res)
+ return 0;
+ *idtype = SADB_IDENTTYPE_PREFIX;
+ return res;
+
case IPSEC_ID_IPV6_ADDR_SUBNET: /* XXX PREFIX */
+ addr = id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
+ if (inet_ntop (AF_INET6, addr, addrbuf, ADDRESS_MAX) != NULL)
+ *reslen = strlen (addrbuf) + 5;
+ sprintf (addrbuf + strlen (addrbuf), "/%d",
+ pf_key_v2_mask6_to_bits (addr + sizeof (struct in6_addr)));
+ res = strdup (addrbuf);
+ if (!res)
+ return 0;
+ *idtype = SADB_IDENTTYPE_PREFIX;
+ return res;
+
case IPSEC_ID_IPV4_RANGE:
case IPSEC_ID_IPV6_RANGE:
case IPSEC_ID_DER_ASN1_DN:
@@ -1897,7 +2063,8 @@ pf_key_v2_enable_sa (struct sa *sa, struct sa *isakmp_sa)
int sidtype = 0, didtype = 0, sidlen = 0, didlen = 0;
u_int8_t *sid = 0, *did = 0;
#ifndef SADB_X_EXT_FLOW_TYPE
- in_addr_t hostmask = 0xffffffff; /* XXX IPv4 specific */
+ struct sockaddr_storage hostmask_storage;
+ struct sockaddr *hostmask = (struct sockaddr *)&hostmask_storage;
#endif /* SADB_X_EXT_FLOW_TYPE */
sa->transport->vtbl->get_dst (sa->transport, &dst, &dstlen);
@@ -1925,26 +2092,36 @@ pf_key_v2_enable_sa (struct sa *sa, struct sa *isakmp_sa)
}
#endif /* SADB_X_EXT_FLOW_TYPE */
- /* XXX IPv4 specific */
error = pf_key_v2_flow (isa->src_net, isa->src_mask, isa->dst_net,
isa->dst_mask, isa->tproto, isa->sport, isa->dport,
- proto->spi[0], proto->proto,
- ((struct sockaddr_in *)dst)->sin_addr.s_addr,
- ((struct sockaddr_in *)src)->sin_addr.s_addr, 0, 0,
+ proto->spi[0], proto->proto, dst, src, 0, 0,
sidtype, sid, sidlen, didtype, did, didlen);
if (error)
goto cleanup;
#ifndef SADB_X_EXT_FLOW_TYPE
+ /* Set hostmask to '-1'. */
+ switch (dst->sa_family)
+ {
+ case AF_INET:
+ ((struct sockaddr_in *)hostmask)->sin_family = AF_INET;
+ ((struct sockaddr_in *)hostmask)->sin_len = sizeof (struct in_addr);
+ memset (&((struct sockaddr_in *)hostmask)->sin_addr.s_addr, 0xff,
+ sizeof (struct in_addr));
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)hostmask)->sin6_family = AF_INET6;
+ ((struct sockaddr_in6 *)hostmask)->sin6_len = sizeof (struct in6_addr);
+ memset (&((struct sockaddr_in6 *)hostmask)->sin6_addr.s6_addr, 0xff,
+ sizeof (struct in6_addr));
+ break;
+ }
+
/* Ingress flows, handling SA bundles. */
while (TAILQ_NEXT (proto, link))
{
- error = pf_key_v2_flow (((struct sockaddr_in *)dst)->sin_addr.s_addr,
- hostmask,
- ((struct sockaddr_in *)src)->sin_addr.s_addr,
- hostmask, 0, 0, 0, proto->spi[1], proto->proto,
- ((struct sockaddr_in *)src)->sin_addr.s_addr,
- ((struct sockaddr_in *)dst)->sin_addr.s_addr,
+ error = pf_key_v2_flow (dst, hostmask, src, hostmask, 0, 0, 0,
+ proto->spi[1], proto->proto, src, dst,
0, 1, 0, 0, 0, 0, 0, 0);
if (error)
goto cleanup;
@@ -1954,9 +2131,7 @@ pf_key_v2_enable_sa (struct sa *sa, struct sa *isakmp_sa)
error = pf_key_v2_flow (isa->dst_net, isa->dst_mask, isa->src_net,
isa->src_mask, isa->tproto, isa->dport, isa->sport,
- proto->spi[1], proto->proto,
- ((struct sockaddr_in *)src)->sin_addr.s_addr,
- ((struct sockaddr_in *)dst)->sin_addr.s_addr, 0, 1,
+ proto->spi[1], proto->proto, src, dst, 0, 1,
sidtype, sid, sidlen, didtype, did, didlen);
cleanup:
@@ -2104,7 +2279,8 @@ pf_key_v2_disable_sa (struct sa *sa, int incoming)
int dstlen, srclen;
struct proto *proto = TAILQ_FIRST (&sa->protos);
#ifndef SADB_X_EXT_FLOW_TYPE
- in_addr_t hostmask = 0xffffffff; /* XXX IPv4 specific */
+ struct sockaddr_storage hostmask_storage;
+ struct sockaddr *hostmask = (struct sockaddr *)&hostmask_storage;
int error;
#endif /* SADB_X_EXT_FLOW_TYPE */
@@ -2114,23 +2290,34 @@ pf_key_v2_disable_sa (struct sa *sa, int incoming)
if (!incoming)
return pf_key_v2_flow (isa->src_net, isa->src_mask, isa->dst_net,
isa->dst_mask, isa->tproto, isa->sport, isa->dport,
- proto->spi[0], proto->proto,
- ((struct sockaddr_in *)dst)->sin_addr.s_addr,
- ((struct sockaddr_in *)src)->sin_addr.s_addr, 1, 0,
+ proto->spi[0], proto->proto, src, dst, 1, 0,
0, 0, 0, 0, 0, 0);
else
{
#ifndef SADB_X_EXT_FLOW_TYPE
+ /* Set hostmask to '-1'. */
+ switch (dst->sa_family)
+ {
+ case AF_INET:
+ ((struct sockaddr_in *)hostmask)->sin_family = AF_INET;
+ ((struct sockaddr_in *)hostmask)->sin_len = sizeof (struct in_addr);
+ memset (&((struct sockaddr_in *)hostmask)->sin_addr.s_addr, 0xff,
+ sizeof (struct in_addr));
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)hostmask)->sin6_family = AF_INET6;
+ ((struct sockaddr_in6 *)hostmask)->sin6_len =
+ sizeof (struct in6_addr);
+ memset (&((struct sockaddr_in6 *)hostmask)->sin6_addr.s6_addr, 0xff,
+ sizeof (struct in6_addr));
+ break;
+ }
+
/* Ingress flow --- SA bundles */
while (TAILQ_NEXT (proto, link))
{
- error = pf_key_v2_flow (((struct sockaddr_in *)dst)->sin_addr.s_addr,
- hostmask,
- ((struct sockaddr_in *)src)->sin_addr.s_addr,
- hostmask, 0, 0, 0,
- proto->spi[1], proto->proto,
- ((struct sockaddr_in *)src)->sin_addr.s_addr,
- ((struct sockaddr_in *)dst)->sin_addr.s_addr,
+ error = pf_key_v2_flow (dst, hostmask, src, hostmask, 0, 0, 0,
+ proto->spi[1], proto->proto, src, dst,
1, 1, 0, 0, 0, 0, 0, 0);
if (error)
return error;
@@ -2141,9 +2328,7 @@ pf_key_v2_disable_sa (struct sa *sa, int incoming)
return pf_key_v2_flow (isa->dst_net, isa->dst_mask, isa->src_net,
isa->src_mask, isa->tproto, isa->dport,
isa->sport, proto->spi[1], proto->proto,
- ((struct sockaddr_in *)src)->sin_addr.s_addr,
- ((struct sockaddr_in *)dst)->sin_addr.s_addr,
- 1, 1, 0, 0, 0, 0, 0, 0);
+ src, dst, 1, 1, 0, 0, 0, 0, 0, 0);
}
}
@@ -2222,15 +2407,13 @@ pf_key_v2_delete_spi (struct sa *sa, struct proto *proto, int incoming)
/*
* Setup the ADDRESS extensions.
- *
- * XXX Addresses have to be thought through. Assumes IPv4.
*/
if (incoming)
sa->transport->vtbl->get_dst (sa->transport, &saddr, &saddrlen);
else
sa->transport->vtbl->get_src (sa->transport, &saddr, &saddrlen);
len = sizeof *addr + PF_KEY_V2_ROUND (saddrlen);
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
@@ -2241,7 +2424,15 @@ pf_key_v2_delete_spi (struct sa *sa, struct proto *proto, int incoming)
#endif
addr->sadb_address_reserved = 0;
memcpy (addr + 1, saddr, saddrlen);
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ switch (saddr->sa_family)
+ {
+ case AF_INET:
+ ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
+ break;
+ }
if (pf_key_v2_msg_add (delete, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
@@ -2252,7 +2443,7 @@ pf_key_v2_delete_spi (struct sa *sa, struct proto *proto, int incoming)
else
sa->transport->vtbl->get_dst (sa->transport, &saddr, &saddrlen);
len = sizeof *addr + PF_KEY_V2_ROUND (saddrlen);
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
@@ -2263,7 +2454,15 @@ pf_key_v2_delete_spi (struct sa *sa, struct proto *proto, int incoming)
#endif
addr->sadb_address_reserved = 0;
memcpy (addr + 1, saddr, saddrlen);
- ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ switch (saddr->sa_family)
+ {
+ case AF_INET:
+ ((struct sockaddr_in *)(addr + 1))->sin_port = 0;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)(addr + 1))->sin6_port = 0;
+ break;
+ }
if (pf_key_v2_msg_add (delete, (struct sadb_ext *)addr,
PF_KEY_V2_NODE_MALLOCED) == -1)
goto cleanup;
@@ -2345,6 +2544,7 @@ pf_key_v2_expire (struct pf_key_v2_msg *pmsg)
struct sadb_lifetime *life, *lifecurrent;
struct sa *sa;
struct pf_key_v2_node *lifenode, *ext;
+ char *dst_str;
msg = (struct sadb_msg *)TAILQ_FIRST (pmsg)->seg;
ext = pf_key_v2_find_ext (pmsg, SADB_EXT_SA);
@@ -2380,13 +2580,21 @@ pf_key_v2_expire (struct pf_key_v2_msg *pmsg)
}
lifecurrent = lifenode->seg;
- /* XXX IPv4 specific. */
+#ifdef USE_DEBUG
+
+ if (sockaddr2text (dstaddr, &dst_str, 0))
+ dst_str = 0;
+
LOG_DBG ((LOG_SYSDEP, 20, "pf_key_v2_expire: %s dst %s SPI %x sproto %d",
life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_SOFT ? "SOFT"
- : "HARD",
- inet_ntoa (((struct sockaddr_in *)dstaddr)->sin_addr),
+ : "HARD", dst_str ? dst_str : "<unknown>",
ntohl (ssa->sadb_sa_spi), msg->sadb_msg_satype));
+ if (dst_str)
+ free (dst_str);
+
+#endif /* USE_DEBUG */
+
/*
* Find the IPsec SA. The IPsec stack has two SAs for every IKE SA,
* one outgoing and one incoming, we regard expirations for any of
@@ -2396,10 +2604,8 @@ pf_key_v2_expire (struct pf_key_v2_msg *pmsg)
* of the full suite.
*
* XXX When anything else than AH and ESP is supported this needs to change.
- * XXX IPv4 specific.
*/
- sa = ipsec_sa_lookup (((struct sockaddr_in *)dstaddr)->sin_addr.s_addr,
- ssa->sadb_sa_spi,
+ sa = ipsec_sa_lookup (dstaddr, ssa->sadb_sa_spi,
msg->sadb_msg_satype == SADB_SATYPE_ESP
? IPSEC_PROTO_IPSEC_ESP : IPSEC_PROTO_IPSEC_AH);
@@ -3647,15 +3853,13 @@ pf_key_v2_group_spis (struct sa *sa, struct proto *proto1,
/*
* Setup the ADDRESS extensions.
- *
- * XXX Addresses have to be thought through. Assumes IPv4.
*/
if (incoming)
sa->transport->vtbl->get_src (sa->transport, &saddr, &saddrlen);
else
sa->transport->vtbl->get_dst (sa->transport, &saddr, &saddrlen);
len = sizeof *addr + PF_KEY_V2_ROUND (saddrlen);
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
@@ -3672,7 +3876,7 @@ pf_key_v2_group_spis (struct sa *sa, struct proto *proto1,
goto cleanup;
addr = 0;
- addr = malloc (len);
+ addr = calloc (1, len);
if (!addr)
goto cleanup;
addr->sadb_address_exttype = SADB_X_EXT_DST2;
diff --git a/sbin/isakmpd/policy.c b/sbin/isakmpd/policy.c
index 4645c338011..ef0566eef8d 100644
--- a/sbin/isakmpd/policy.c
+++ b/sbin/isakmpd/policy.c
@@ -1,9 +1,10 @@
-/* $OpenBSD: policy.c,v 1.32 2001/06/07 04:46:45 angelos Exp $ */
+/* $OpenBSD: policy.c,v 1.33 2001/06/29 04:12:01 ho Exp $ */
/* $EOM: policy.c,v 1.49 2000/10/24 13:33:39 niklas Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Angelos D. Keromytis. All rights reserved.
* Copyright (c) 1999, 2000, 2001 Niklas Hallqvist. All rights reserved.
+ * Copyright (c) 2001 Håkan Olsson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -165,13 +166,14 @@ policy_callback (char *name)
u_int8_t *attr, *value, *id, *idlocal, *idremote;
size_t id_sz, idlocalsz, idremotesz;
- struct sockaddr_in *sin;
+ struct sockaddr *sin;
struct ipsec_exch *ie;
struct ipsec_sa *is;
int fmt, i, lifetype = 0;
in_addr_t net, subnet;
u_int16_t len, type;
time_t tt;
+ char *addr;
static char mytimeofday[15];
/* We use all these as a cache. */
@@ -626,16 +628,23 @@ policy_callback (char *name)
}
}
- /* XXX IPv4-specific. */
- policy_sa->transport->vtbl->get_src (policy_sa->transport,
- (struct sockaddr **)&sin, &fmt);
- my_inet_ntop4 (&(sin->sin_addr.s_addr), local_ike_address,
- sizeof local_ike_address - 1, 0);
+ policy_sa->transport->vtbl->get_src (policy_sa->transport, &sin, &fmt);
+ if (sockaddr2text (sin, &addr, 1))
+ {
+ log_error ("policy_callback: sockaddr2text failed");
+ goto bad;
+ }
+ memcpy (local_ike_address, addr, sizeof local_ike_address);
+ free (addr);
- policy_sa->transport->vtbl->get_dst (policy_sa->transport,
- (struct sockaddr **)&sin, &fmt);
- my_inet_ntop4 (&(sin->sin_addr.s_addr), remote_ike_address,
- sizeof remote_ike_address - 1, 0);
+ policy_sa->transport->vtbl->get_dst (policy_sa->transport, &sin, &fmt);
+ if (sockaddr2text (sin, &addr, 1))
+ {
+ log_error ("policy_callback: sockaddr2text failed");
+ goto bad;
+ }
+ memcpy (local_ike_address, addr, sizeof remote_ike_address);
+ free (addr);
switch (policy_isakmp_sa->exch_type)
{
@@ -1039,15 +1048,31 @@ policy_callback (char *name)
}
else
{
- policy_sa->transport->vtbl->get_dst (policy_sa->transport,
- (struct sockaddr **) &sin,
+ policy_sa->transport->vtbl->get_dst (policy_sa->transport, &sin,
&fmt);
- remote_filter_type = "IPv4 address";
-
- my_inet_ntop4 (&(sin->sin_addr.s_addr), remote_filter_addr_upper,
- sizeof remote_filter_addr_upper - 1, 0);
- my_inet_ntop4 (&(sin->sin_addr.s_addr), remote_filter_addr_lower,
- sizeof remote_filter_addr_lower - 1, 0);
+ switch (sin->sa_family)
+ {
+ case AF_INET:
+ remote_filter_type = "IPv4 address";
+ break;
+ case AF_INET6:
+ remote_filter_type = "IPv6 address";
+ break;
+ default:
+ log_print ("policy_callback: unsupported protocol family %d",
+ sin->sa_family);
+ goto bad;
+ }
+ if (sockaddr2text (sin, &addr, 1))
+ {
+ log_error ("policy_callback: sockaddr2text failed");
+ goto bad;
+ }
+ memcpy (remote_filter_addr_upper, addr,
+ sizeof remote_filter_addr_upper);
+ memcpy (remote_filter_addr_lower, addr,
+ sizeof remote_filter_addr_lower);
+ free (addr);
remote_filter = strdup (remote_filter_addr_upper);
if (!remote_filter)
{
@@ -1242,13 +1267,30 @@ policy_callback (char *name)
policy_sa->transport->vtbl->get_src (policy_sa->transport,
(struct sockaddr **)&sin,
&fmt);
+ switch (sin->sa_family)
+ {
+ case AF_INET:
+ local_filter_type = "IPv4 address";
+ break;
+ case AF_INET6:
+ local_filter_type = "IPv6 address";
+ break;
+ default:
+ log_print ("policy_callback: unsupported protocol family %d",
+ sin->sa_family);
+ goto bad;
+ }
- local_filter_type = "IPv4 address";
-
- my_inet_ntop4 (&(sin->sin_addr.s_addr), local_filter_addr_upper,
- sizeof local_filter_addr_upper - 1, 0);
- my_inet_ntop4 (&(sin->sin_addr.s_addr), local_filter_addr_lower,
- sizeof local_filter_addr_lower - 1, 0);
+ if (sockaddr2text (sin, &addr, 1))
+ {
+ log_error ("policy_callback: sockaddr2text failed");
+ goto bad;
+ }
+ memcpy (local_filter_addr_upper, addr,
+ sizeof local_filter_addr_upper);
+ memcpy (local_filter_addr_lower, addr,
+ sizeof local_filter_addr_lower);
+ free (addr);
local_filter = strdup (local_filter_addr_upper);
if (!local_filter)
{
@@ -1704,7 +1746,7 @@ int
keynote_cert_obtain (u_int8_t *id, size_t id_len, void *data, u_int8_t **cert,
u_int32_t *certlen)
{
- char *dirname, *file;
+ char *dirname, *file, *addr_str;
struct stat sb;
int idtype, fd, len;
@@ -1732,21 +1774,24 @@ keynote_cert_obtain (u_int8_t *id, size_t id_len, void *data, u_int8_t **cert,
switch (idtype)
{
case IPSEC_ID_IPV4_ADDR:
- {
- struct in_addr in;
+ case IPSEC_ID_IPV6_ADDR:
+ util_ntoa (&addr_str, idtype == IPSEC_ID_IPV4_ADDR ? AF_INET : AF_INET6,
+ id);
+ if (addr_str == 0)
+ return 0;
- file = calloc (len + 15, sizeof (char));
- if (file == NULL)
- {
- log_error ("keynote_cert_obtain: failed to allocate %d bytes",
- len + 15);
- return 0;
- }
+ file = calloc (len + strlen (addr_str), sizeof (char));
+ if (file == NULL)
+ {
+ log_error ("keynote_cert_obtain: failed to allocate %d bytes",
+ len + strlen (addr_str));
+ free (addr_str);
+ return 0;
+ }
- memcpy (&in, id, sizeof in);
- sprintf (file, "%s/%s/%s", dirname, inet_ntoa (in), CREDENTIAL_FILE);
- break;
- }
+ sprintf (file, "%s/%s/%s", dirname, addr_str, CREDENTIAL_FILE);
+ free (addr_str);
+ break;
case IPSEC_ID_FQDN:
case IPSEC_ID_USER_FQDN:
diff --git a/sbin/isakmpd/util.c b/sbin/isakmpd/util.c
index e9ebba748e6..3e45942d551 100644
--- a/sbin/isakmpd/util.c
+++ b/sbin/isakmpd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.14 2001/06/27 05:16:49 ho Exp $ */
+/* $OpenBSD: util.c,v 1.15 2001/06/29 04:12:01 ho Exp $ */
/* $EOM: util.c,v 1.23 2000/11/23 12:22:08 niklas Exp $ */
/*
@@ -269,10 +269,16 @@ text2sockaddr (char *address, char *port, struct sockaddr **sa)
#endif
}
+/*
+ * Convert a sockaddr to text. With zflag non-zero fill out with zeroes,
+ * i.e 10.0.0.10 --> "010.000.000.010"
+ */
int
-sockaddr2text (struct sockaddr *sa, char **address)
+sockaddr2text (struct sockaddr *sa, char **address, int zflag)
{
char buf[NI_MAXHOST];
+ char *token, *bstart, *p;
+ int c_pre = 0, c_post = 0;
#ifdef HAVE_GETNAMEINFO
if (getnameinfo (sa, sa->sa_len, buf, sizeof buf, 0, 0,
@@ -293,10 +299,79 @@ sockaddr2text (struct sockaddr *sa, char **address)
}
#endif
- *address = malloc (strlen (buf) + 1);
- if (!address)
- return -1;
-
+ if (zflag == 0)
+ {
+ *address = malloc (strlen (buf) + 1);
+ if (*address == NULL)
+ return -1;
+ }
+ else
+ switch (sa->sa_family)
+ {
+ case AF_INET:
+ *address = malloc (16);
+ if (*address == NULL)
+ return -1;
+ bstart = buf; **address = '\0';
+ while ((token = strsep (&bstart, ".")) != NULL)
+ {
+ if (strlen (*address) > 12)
+ {
+ free (*address);
+ return -1;
+ }
+ sprintf (*address + strlen (*address), "%03ld",
+ strtol (token, NULL, 10));
+ if (bstart)
+ strcat (*address + strlen (*address), ".");
+ }
+ break;
+ case AF_INET6:
+ *address = malloc (40);
+ if (!address)
+ return -1;
+ bstart = buf; **address = '\0';
+ buf[40] = '\0'; /* Make sure buf is terminated. */
+ while ((token = strsep (&bstart, ":")) != NULL)
+ {
+ if (strlen (token) == 0)
+ {
+ /* Encountered a '::'. Fill out the string. */
+ /* XXX Isn't there a library function for this somewhere? */
+ for (p = buf; p < token - 1; p++)
+ if (*p == 0)
+ c_pre++;
+ for (p = token + 1; p < (bstart + strlen (bstart)); p++)
+ if (*p == ':')
+ c_post++;
+ /* The number of zero groups to add. */
+ c_pre = 7 - c_pre - c_post - 1;
+ if (c_pre > 6 || strlen (*address) > (40 - 5 * c_pre))
+ {
+ free (*address);
+ return -1;
+ }
+ for (; c_pre; c_pre--)
+ strcat (*address + strlen (*address), "0000:");
+ }
+ else
+ {
+ if (strlen (*address) > 35)
+ {
+ free (*address);
+ return -1;
+ }
+ sprintf (*address + strlen (*address), "%04lx",
+ strtol (token, NULL, 16));
+ if (bstart)
+ strcat (*address + strlen (*address), ":");
+ }
+ }
+ break;
+ default:
+ strcpy (buf, "<error>");
+ }
+
strcpy (*address, buf);
return 0;
}
@@ -334,7 +409,41 @@ sockaddr_data (struct sockaddr *sa)
return 0; /* XXX */
}
}
-
+
+/*
+ * Convert network address to text. The network address does not need
+ * to be properly aligned.
+ */
+void
+util_ntoa (char **buf, int af, u_int8_t *addr)
+{
+ struct sockaddr_storage from;
+ struct sockaddr *sfrom = (struct sockaddr *)&from;
+ socklen_t fromlen = sizeof from;
+ u_int32_t ip4_buf;
+
+ memset (&from, 0, fromlen);
+ sfrom->sa_family = af;
+ switch (af)
+ {
+ case AF_INET:
+ sfrom->sa_len = sizeof (struct sockaddr_in);
+ memcpy (&ip4_buf, addr, sizeof (struct in_addr));
+ ((struct sockaddr_in *)sfrom)->sin_addr.s_addr = htonl (ip4_buf);
+ break;
+ case AF_INET6:
+ sfrom->sa_len = sizeof (struct sockaddr_in6);
+ memcpy (sockaddr_data (sfrom), addr, sizeof (struct in6_addr));
+ break;
+ }
+
+ if (sockaddr2text (sfrom, buf, 0))
+ {
+ log_error ("util_ntoa: sockaddr2text () failed");
+ *buf = 0;
+ }
+}
+
/*
* Perform sanity check on files containing secret information.
* Returns -1 on failure, 0 otherwise.
@@ -370,4 +479,3 @@ check_file_secrecy (char *name, off_t *file_size)
return 0;
}
-
diff --git a/sbin/isakmpd/util.h b/sbin/isakmpd/util.h
index 84b25d084f0..8e7e4defbb2 100644
--- a/sbin/isakmpd/util.h
+++ b/sbin/isakmpd/util.h
@@ -1,8 +1,9 @@
-/* $OpenBSD: util.h,v 1.8 2001/06/27 00:10:35 ho Exp $ */
+/* $OpenBSD: util.h,v 1.9 2001/06/29 04:12:01 ho Exp $ */
/* $EOM: util.h,v 1.10 2000/10/24 13:33:39 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
+ * Copyright (c) 2001 Håkan Olsson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,7 +61,8 @@ extern void encode_128 (u_int8_t *, u_int8_t *);
#endif
extern u_int8_t *getrandom (u_int8_t *, size_t);
extern int hex2raw (char *, u_int8_t *, size_t);
-extern int sockaddr2text (struct sockaddr *, char **);
+extern int sockaddr2text (struct sockaddr *, char **, int);
+extern void util_ntoa (char **, int, u_int8_t *);
extern int text2sockaddr (char *, char *, struct sockaddr **);
extern int sockaddr_len (struct sockaddr *);
extern u_int8_t *sockaddr_data (struct sockaddr *);