aboutsummaryrefslogtreecommitdiffstats
path: root/programs/pluto/modecfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'programs/pluto/modecfg.c')
-rw-r--r--programs/pluto/modecfg.c798
1 files changed, 0 insertions, 798 deletions
diff --git a/programs/pluto/modecfg.c b/programs/pluto/modecfg.c
deleted file mode 100644
index 1c22845a5..000000000
--- a/programs/pluto/modecfg.c
+++ /dev/null
@@ -1,798 +0,0 @@
-/* Mode config related functions
- * Copyright (C) 2001-2002 Colubris Networks
- * Copyright (C) 2003 Sean Mathews - Nu Tech Software Solutions, inc.
- * Copyright (C) 2003-2004 Xelerance Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: modecfg.c,v 1.6 2006/04/24 20:44:57 as Exp $
- *
- * This code originally written by Colubris Networks, Inc.
- * Extraction of patch and porting to 1.99 codebases by Xelerance Corporation
- * Porting to 2.x by Sean Mathews
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "state.h"
-#include "demux.h"
-#include "timer.h"
-#include "ipsec_doi.h"
-#include "log.h"
-#include "md5.h"
-#include "sha1.h"
-#include "crypto.h"
-#include "modecfg.h"
-#include "whack.h"
-
-/*
- * Addresses assigned (usually via MODE_CONFIG) to the Initiator
- */
-struct internal_addr
-{
- ip_address ipaddr;
- ip_address dns[2];
- ip_address wins[2];
-};
-
-/*
- * Get inside IP address for a connection
- */
-static void
-get_internal_addresses(struct connection *c, struct internal_addr *ia)
-{
- zero(ia);
-
- if (isanyaddr(&c->spd.that.host_srcip))
- {
- /* not defined in connection - fetch it from LDAP */
- }
- else
- {
- ia->ipaddr = c->spd.that.host_srcip;
- }
-}
-
-/*
- * Compute HASH of Mode Config.
- */
-static size_t
-mode_cfg_hash(u_char *dest, const u_char *start, const u_char *roof
- , const struct state *st)
-{
- struct hmac_ctx ctx;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid_a);
- hmac_update(&ctx, (const u_char *) &st->st_msgid, sizeof(st->st_msgid));
- hmac_update(&ctx, start, roof-start);
- hmac_final(dest, &ctx);
-
- DBG(DBG_CRYPT,
- DBG_log("MODE CFG: HASH computed:");
- DBG_dump("", dest, ctx.hmac_digest_size)
- )
- return ctx.hmac_digest_size;
-}
-
-
-/* Mode Config Reply
- * Generates a reply stream containing Mode Config information (eg: IP, DNS, WINS)
- */
-stf_status modecfg_resp(struct state *st
- , u_int resp
- , pb_stream *rbody
- , u_int16_t replytype
- , bool hackthat
- , u_int16_t ap_id)
-{
- u_char *r_hash_start,*r_hashval;
-
- /* START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_ATTR); */
-
- {
- pb_stream hash_pbs;
- int np = ISAKMP_NEXT_ATTR;
-
- if (!out_generic(np, &isakmp_hash_desc, rbody, &hash_pbs))
- return STF_INTERNAL_ERROR;
- r_hashval = hash_pbs.cur; /* remember where to plant value */
- if (!out_zero(st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&hash_pbs);
- r_hash_start = (rbody)->cur; /* hash from after HASH payload */
- }
-
- /* ATTR out */
- {
- struct isakmp_mode_attr attrh;
- struct isakmp_attribute attr;
- pb_stream strattr,attrval;
- int attr_type;
- struct internal_addr ia;
- int dns_idx, wins_idx;
- bool dont_advance;
-
- attrh.isama_np = ISAKMP_NEXT_NONE;
- attrh.isama_type = replytype;
-
- attrh.isama_identifier = ap_id;
- if (!out_struct(&attrh, &isakmp_attr_desc, rbody, &strattr))
- return STF_INTERNAL_ERROR;
-
- get_internal_addresses(st->st_connection, &ia);
-
- if (!isanyaddr(&ia.dns[0])) /* We got DNS addresses, answer with those */
- resp |= LELEM(INTERNAL_IP4_DNS);
- else
- resp &= ~LELEM(INTERNAL_IP4_DNS);
-
- if (!isanyaddr(&ia.wins[0])) /* We got WINS addresses, answer with those */
- resp |= LELEM(INTERNAL_IP4_NBNS);
- else
- resp &= ~LELEM(INTERNAL_IP4_NBNS);
-
- if (hackthat)
- {
- if (memcmp(&st->st_connection->spd.that.client.addr
- ,&ia.ipaddr
- ,sizeof(ia.ipaddr)) != 0)
- {
- /* Make the Internal IP address and Netmask
- * as that client address
- */
- st->st_connection->spd.that.client.addr = ia.ipaddr;
- st->st_connection->spd.that.client.maskbits = 32;
- st->st_connection->spd.that.has_client = TRUE;
- }
- }
-
- attr_type = 0;
- dns_idx = 0;
- wins_idx = 0;
-
- while (resp != 0)
- {
- dont_advance = FALSE;
- if (resp & 1)
- {
- const u_char *byte_ptr;
- u_int len;
-
- /* ISAKMP attr out */
- attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TLV;
- out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, &attrval);
-
- switch (attr_type)
- {
- case INTERNAL_IP4_ADDRESS:
- {
- char srcip[ADDRTOT_BUF];
-
- addrtot(&ia.ipaddr, 0, srcip, sizeof(srcip));
- plog("assigning virtual IP source address %s", srcip);
- len = addrbytesptr(&ia.ipaddr, &byte_ptr);
- out_raw(byte_ptr,len,&attrval,"IP4_addr");
- }
- break;
- case INTERNAL_IP4_NETMASK:
- {
- u_int mask;
-#if 0
- char mask[4],bits[8]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
- int t,m=st->st_connection->that.host_addr.maskbit;
- for (t=0; t<4; t++)
- {
- if (m < 8)
- mask[t] = bits[m];
- else
- mask[t] = 0xff;
- m -= 8;
- }
-#endif
- if (st->st_connection->spd.this.client.maskbits == 0)
- mask = 0;
- else
- mask = 0xffffffff * 1;
- out_raw(&mask,4,&attrval,"IP4_mask");
- }
- break;
- case INTERNAL_IP4_SUBNET:
- {
- char mask[4];
- char bits[8] = {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
- int t;
- int m = st->st_connection->spd.this.client.maskbits;
-
- for (t = 0; t < 4; t++)
- {
- if (m < 8)
- mask[t] = bits[m];
- else
- mask[t] = 0xff;
- m -= 8;
- if (m < 0)
- m = 0;
- }
- len = addrbytesptr(&st->st_connection->spd.this.client.addr, &byte_ptr);
- out_raw(byte_ptr,len,&attrval,"IP4_subnet");
- out_raw(mask,sizeof(mask),&attrval,"IP4_submsk");
- }
- break;
- case INTERNAL_IP4_DNS:
- len = addrbytesptr(&ia.dns[dns_idx++], &byte_ptr);
- out_raw(byte_ptr,len,&attrval,"IP4_dns");
- if (dns_idx < 2 && !isanyaddr(&ia.dns[dns_idx]))
- {
- dont_advance = TRUE;
- }
- break;
- case INTERNAL_IP4_NBNS:
- len = addrbytesptr(&ia.wins[wins_idx++], &byte_ptr);
- out_raw(byte_ptr,len,&attrval,"IP4_wins");
- if (wins_idx < 2 && !isanyaddr(&ia.wins[wins_idx]))
- {
- dont_advance = TRUE;
- }
- break;
- default:
- plog("attempt to send unsupported mode cfg attribute %s."
- , enum_show(&modecfg_attr_names, attr_type));
- break;
- }
- close_output_pbs(&attrval);
-
- }
- if (!dont_advance)
- {
- attr_type++;
- resp >>= 1;
- }
- }
- close_message(&strattr);
- }
-
- mode_cfg_hash(r_hashval,r_hash_start,rbody->cur,st);
- close_message(rbody);
- encrypt_message(rbody, st);
- return STF_OK;
-}
-
-/* Set MODE_CONFIG data to client.
- * Pack IP Addresses, DNS, etc... and ship
- */
-stf_status modecfg_send_set(struct state *st)
-{
- pb_stream reply,rbody;
- char buf[256];
-
- /* set up reply */
- init_pbs(&reply, buf, sizeof(buf), "ModecfgR1");
-
- st->st_state = STATE_MODE_CFG_R1;
- /* HDR out */
- {
- struct isakmp_hdr hdr;
-
- zero(&hdr); /* default to 0 */
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_HASH;
- hdr.isa_xchg = ISAKMP_XCHG_MODE_CFG;
- hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
- memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
- memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
- hdr.isa_msgid = st->st_msgid;
-
- if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
- {
- return STF_INTERNAL_ERROR;
- }
- }
-
-#define MODECFG_SET_ITEM ( LELEM(INTERNAL_IP4_ADDRESS) | LELEM(INTERNAL_IP4_SUBNET) | LELEM(INTERNAL_IP4_NBNS) | LELEM(INTERNAL_IP4_DNS) )
-
- modecfg_resp(st, MODECFG_SET_ITEM
- , &rbody
- , ISAKMP_CFG_SET
- , TRUE
- , 0/* XXX ID */);
-#undef MODECFG_SET_ITEM
-
- clonetochunk(st->st_tpacket, reply.start
- , pbs_offset(&reply), "ModeCfg set");
-
- /* Transmit */
- send_packet(st, "ModeCfg set");
-
- /* RETRANSMIT if Main, SA_REPLACE if Aggressive */
- if (st->st_event->ev_type != EVENT_RETRANSMIT
- && st->st_event->ev_type != EVENT_NULL)
- {
- delete_event(st);
- event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
- }
-
- return STF_OK;
-}
-
-/* Set MODE_CONFIG data to client.
- * Pack IP Addresses, DNS, etc... and ship
- */
-stf_status
-modecfg_start_set(struct state *st)
-{
- if (st->st_msgid == 0)
- {
- /* pick a new message id */
- st->st_msgid = generate_msgid(st);
- }
- st->st_modecfg.vars_set = TRUE;
-
- return modecfg_send_set(st);
-}
-
-/*
- * Send modecfg IP address request (IP4 address)
- */
-stf_status
-modecfg_send_request(struct state *st)
-{
- pb_stream reply;
- pb_stream rbody;
- char buf[256];
- u_char *r_hash_start,*r_hashval;
-
- /* set up reply */
- init_pbs(&reply, buf, sizeof(buf), "modecfg_buf");
-
- plog("sending ModeCfg request");
-
- /* this is the beginning of a new exchange */
- st->st_msgid = generate_msgid(st);
- st->st_state = STATE_MODE_CFG_I1;
-
- /* HDR out */
- {
- struct isakmp_hdr hdr;
-
- zero(&hdr); /* default to 0 */
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_HASH;
- hdr.isa_xchg = ISAKMP_XCHG_MODE_CFG;
- hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
- memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
- memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
- hdr.isa_msgid = st->st_msgid;
-
- if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
- {
- return STF_INTERNAL_ERROR;
- }
- }
-
- START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_ATTR);
-
- /* ATTR out */
- {
- struct isakmp_mode_attr attrh;
- struct isakmp_attribute attr;
- pb_stream strattr;
-
- attrh.isama_np = ISAKMP_NEXT_NONE;
- attrh.isama_type = ISAKMP_CFG_REQUEST;
- attrh.isama_identifier = 0;
- if (!out_struct(&attrh, &isakmp_attr_desc, &rbody, &strattr))
- return STF_INTERNAL_ERROR;
- /* ISAKMP attr out (ipv4) */
- attr.isaat_af_type = INTERNAL_IP4_ADDRESS;
- attr.isaat_lv = 0;
- out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, NULL);
-
- /* ISAKMP attr out (netmask) */
- attr.isaat_af_type = INTERNAL_IP4_NETMASK;
- attr.isaat_lv = 0;
- out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, NULL);
-
- close_message(&strattr);
- }
-
- mode_cfg_hash(r_hashval,r_hash_start,rbody.cur,st);
-
- close_message(&rbody);
- close_output_pbs(&reply);
-
- init_phase2_iv(st, &st->st_msgid);
- encrypt_message(&rbody, st);
-
- clonetochunk(st->st_tpacket, reply.start, pbs_offset(&reply)
- , "modecfg: req");
-
- /* Transmit */
- send_packet(st, "modecfg: req");
-
- /* RETRANSMIT if Main, SA_REPLACE if Aggressive */
- if (st->st_event->ev_type != EVENT_RETRANSMIT)
- {
- delete_event(st);
- event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0 * 3, st);
- }
- st->st_modecfg.started = TRUE;
-
- return STF_OK;
-}
-
-/*
- * parse a modecfg attribute payload
- */
-static stf_status
-modecfg_parse_attributes(pb_stream *attrs, u_int *set)
-{
- struct isakmp_attribute attr;
- pb_stream strattr;
-
- while (pbs_left(attrs) > sizeof(struct isakmp_attribute))
- {
- if (!in_struct(&attr, &isakmp_modecfg_attribute_desc, attrs, &strattr))
- {
- int len = (attr.isaat_af_type & 0x8000)? 4 : attr.isaat_lv;
-
- if (len < 4)
- {
- plog("Attribute was too short: %d", len);
- return STF_FAIL;
- }
-
- attrs->cur += len;
- }
-
- switch (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK )
- {
- case INTERNAL_IP4_ADDRESS:
- case INTERNAL_IP4_NETMASK:
- case INTERNAL_IP4_DNS:
- case INTERNAL_IP4_SUBNET:
- case INTERNAL_IP4_NBNS:
- *set |= LELEM(attr.isaat_af_type);
- break;
- default:
- plog("unsupported mode cfg attribute %s received."
- , enum_show(&modecfg_attr_names
- , attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK ));
- break;
- }
- }
- return STF_OK;
-}
-
-/* STATE_MODE_CFG_R0:
- * HDR*, HASH, ATTR(REQ=IP) --> HDR*, HASH, ATTR(REPLY=IP)
- *
- * This state occurs both in the responder and in the initiator.
- *
- * In the responding server, it occurs when the client *asks* for an IP
- * address or other information.
- *
- * Otherwise, it occurs in the initiator when the server sends a challenge
- * a set, or has a reply to our request.
- */
-stf_status
-modecfg_inR0(struct msg_digest *md)
-{
- struct state *const st = md->st;
- struct payload_digest *p;
- stf_status stat;
-
- plog("received ModeCfg request");
-
- st->st_msgid = md->hdr.isa_msgid;
- CHECK_QUICK_HASH(md, mode_cfg_hash(hash_val
- ,hash_pbs->roof
- , md->message_pbs.roof, st)
- , "MODECFG-HASH", "MODE R0");
-
- /* process the MODECFG payloads therein */
- for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
- {
- u_int set_modecfg_attrs = LEMPTY;
-
- switch (p->payload.attribute.isama_type)
- {
- default:
- plog("Expecting ISAKMP_CFG_REQUEST, got %s instead (ignored)."
- , enum_name(&attr_msg_type_names
- , p->payload.attribute.isama_type));
-
- stat = modecfg_parse_attributes(&p->pbs, &set_modecfg_attrs);
- if (stat != STF_OK)
- return stat;
- break;
-
- case ISAKMP_CFG_REQUEST:
- stat = modecfg_parse_attributes(&p->pbs, &set_modecfg_attrs);
- if (stat != STF_OK)
- return stat;
-
- stat = modecfg_resp(st, set_modecfg_attrs
- ,&md->rbody
- ,ISAKMP_CFG_REPLY
- ,TRUE
- ,p->payload.attribute.isama_identifier);
-
- if (stat != STF_OK)
- {
- /* notification payload - not exactly the right choice, but okay */
- md->note = CERTIFICATE_UNAVAILABLE;
- return stat;
- }
-
- /* they asked us, we responded, msgid is done */
- st->st_msgid = 0;
- }
- }
- return STF_OK;
-}
-
-/* STATE_MODE_CFG_R2:
- * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK)
- *
- * used in server push mode, on the client (initiator).
- */
-static stf_status
-modecfg_inI2(struct msg_digest *md)
-{
- struct state *const st = md->st;
- pb_stream *attrs = &md->chain[ISAKMP_NEXT_ATTR]->pbs;
- int resp = LEMPTY;
- stf_status stat;
- struct payload_digest *p;
- u_int16_t isama_id = 0;
-
- st->st_msgid = md->hdr.isa_msgid;
- CHECK_QUICK_HASH(md
- , mode_cfg_hash(hash_val
- ,hash_pbs->roof
- , md->message_pbs.roof
- , st)
- , "MODECFG-HASH", "MODE R1");
-
- for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
- {
- struct isakmp_attribute attr;
- pb_stream strattr;
-
- isama_id = p->payload.attribute.isama_identifier;
-
- if (p->payload.attribute.isama_type != ISAKMP_CFG_SET)
- {
- plog("Expecting MODE_CFG_SET, got %x instead."
- ,md->chain[ISAKMP_NEXT_ATTR]->payload.attribute.isama_type);
- return STF_IGNORE;
- }
-
- /* CHECK that SET has been received. */
-
- while (pbs_left(attrs) > sizeof(struct isakmp_attribute))
- {
- if (!in_struct(&attr, &isakmp_modecfg_attribute_desc
- , attrs, &strattr))
- {
- int len;
-
- /* Skip unknown */
- if (attr.isaat_af_type & 0x8000)
- len = 4;
- else
- len = attr.isaat_lv;
-
- if (len < 4)
- {
- plog("Attribute was too short: %d", len);
- return STF_FAIL;
- }
-
- attrs->cur += len;
- }
-
- switch (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK )
- {
- case INTERNAL_IP4_ADDRESS:
- {
- struct connection *c = st->st_connection;
- ip_address a;
- u_int32_t *ap = (u_int32_t *)(strattr.cur);
- a.u.v4.sin_family = AF_INET;
-
- memcpy(&a.u.v4.sin_addr.s_addr, ap
- , sizeof(a.u.v4.sin_addr.s_addr));
-
- if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0
- || isanyaddr(&c->spd.this.host_srcip))
- {
- char srcip[ADDRTOT_BUF];
-
- c->spd.this.host_srcip = a;
- addrtot(&a, 0, srcip, sizeof(srcip));
- plog("setting virtual IP source address to %s", srcip);
- }
-
- /* setting client subnet as srcip/32 */
- addrtosubnet(&a, &c->spd.this.client);
- c->spd.this.has_client = TRUE;
- }
- resp |= LELEM(attr.isaat_af_type);
- break;
- case INTERNAL_IP4_NETMASK:
- case INTERNAL_IP4_DNS:
- case INTERNAL_IP4_SUBNET:
- case INTERNAL_IP4_NBNS:
- resp |= LELEM(attr.isaat_af_type);
- break;
- default:
- plog("unsupported mode cfg attribute %s received."
- , enum_show(&modecfg_attr_names, (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK )));
- break;
- }
- }
- }
-
- /* ack things */
- stat = modecfg_resp(st, resp
- ,&md->rbody
- ,ISAKMP_CFG_ACK
- ,FALSE
- ,isama_id);
-
- if (stat != STF_OK)
- {
- /* notification payload - not exactly the right choice, but okay */
- md->note = CERTIFICATE_UNAVAILABLE;
- return stat;
- }
-
- /*
- * we are done with this exchange, clear things so
- * that we can start phase 2 properly
- */
- st->st_msgid = 0;
-
- if (resp)
- {
- st->st_modecfg.vars_set = TRUE;
- }
- return STF_OK;
-}
-
-/* STATE_MODE_CFG_R1:
- * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK)
- */
-stf_status
-modecfg_inR1(struct msg_digest *md)
-{
- struct state *const st = md->st;
- pb_stream *attrs = &md->chain[ISAKMP_NEXT_ATTR]->pbs;
- int set_modecfg_attrs = LEMPTY;
- stf_status stat;
- struct payload_digest *p;
-
- plog("parsing ModeCfg reply");
-
- st->st_msgid = md->hdr.isa_msgid;
- CHECK_QUICK_HASH(md, mode_cfg_hash(hash_val,hash_pbs->roof, md->message_pbs.roof, st)
- , "MODECFG-HASH", "MODE R1");
-
-
- /* process the MODECFG payloads therein */
- for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
- {
- struct isakmp_attribute attr;
- pb_stream strattr;
-
- attrs = &p->pbs;
-
- switch (p->payload.attribute.isama_type)
- {
- default:
- {
- plog("Expecting MODE_CFG_ACK, got %x instead."
- ,md->chain[ISAKMP_NEXT_ATTR]->payload.attribute.isama_type);
- return STF_IGNORE;
- }
- break;
-
- case ISAKMP_CFG_ACK:
- /* CHECK that ACK has been received. */
- stat = modecfg_parse_attributes(attrs, &set_modecfg_attrs);
- if (stat != STF_OK)
- return stat;
- break;
-
- case ISAKMP_CFG_REPLY:
- while (pbs_left(attrs) > sizeof(struct isakmp_attribute))
- {
- if (!in_struct(&attr, &isakmp_modecfg_attribute_desc
- , attrs, &strattr))
- {
- /* Skip unknown */
- int len;
- if (attr.isaat_af_type & 0x8000)
- len = 4;
- else
- len = attr.isaat_lv;
-
- if (len < 4)
- {
- plog("Attribute was too short: %d", len);
- return STF_FAIL;
- }
-
- attrs->cur += len;
- }
-
- switch (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK )
- {
- case INTERNAL_IP4_ADDRESS:
- {
- struct connection *c = st->st_connection;
- ip_address a;
- u_int32_t *ap = (u_int32_t *)(strattr.cur);
- a.u.v4.sin_family = AF_INET;
-
- memcpy(&a.u.v4.sin_addr.s_addr, ap
- , sizeof(a.u.v4.sin_addr.s_addr));
-
- if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0
- || isanyaddr(&c->spd.this.host_srcip))
- {
- char srcip[ADDRTOT_BUF];
-
- c->spd.this.host_srcip = a;
- addrtot(&a, 0, srcip, sizeof(srcip));
- plog("setting virtual IP source address to %s", srcip);
- }
-
- /* setting client subnet as srcip/32 */
- addrtosubnet(&a, &c->spd.this.client);
- setportof(0, &c->spd.this.client.addr);
- c->spd.this.has_client = TRUE;
- }
- /* fall through to set attribute flage */
-
- case INTERNAL_IP4_NETMASK:
- case INTERNAL_IP4_DNS:
- case INTERNAL_IP4_SUBNET:
- case INTERNAL_IP4_NBNS:
- set_modecfg_attrs |= LELEM(attr.isaat_af_type);
- break;
- default:
- plog("unsupported mode cfg attribute %s received."
- , enum_show(&modecfg_attr_names
- , (attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK )));
- break;
- }
- }
- break;
- }
- }
-
- /* we are done with this exchange, clear things so that we can start phase 2 properly */
- st->st_msgid = 0;
-
- if (set_modecfg_attrs)
- {
- st->st_modecfg.vars_set = TRUE;
- }
- return STF_OK;
-}