summaryrefslogtreecommitdiff
path: root/src/charon/encoding
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/encoding')
-rw-r--r--src/charon/encoding/message.c47
-rw-r--r--src/charon/encoding/message.h13
-rw-r--r--src/charon/encoding/payloads/endpoint_notify.c422
-rw-r--r--src/charon/encoding/payloads/endpoint_notify.h185
-rw-r--r--src/charon/encoding/payloads/id_payload.c44
-rw-r--r--src/charon/encoding/payloads/id_payload.h36
-rw-r--r--src/charon/encoding/payloads/ike_header.c22
-rw-r--r--src/charon/encoding/payloads/ike_header.h11
-rw-r--r--src/charon/encoding/payloads/notify_payload.c42
-rw-r--r--src/charon/encoding/payloads/notify_payload.h16
-rw-r--r--src/charon/encoding/payloads/payload.c21
-rw-r--r--src/charon/encoding/payloads/payload.h23
-rw-r--r--src/charon/encoding/payloads/sa_payload.c2
13 files changed, 800 insertions, 84 deletions
diff --git a/src/charon/encoding/message.c b/src/charon/encoding/message.c
index 980ff12b5..3dfa64fb9 100644
--- a/src/charon/encoding/message.c
+++ b/src/charon/encoding/message.c
@@ -6,7 +6,8 @@
*/
/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -149,9 +150,15 @@ static payload_rule_t ike_auth_i_payload_rules[] = {
{CERTIFICATE,0,1,TRUE,FALSE},
{CERTIFICATE_REQUEST,0,1,TRUE,FALSE},
{ID_RESPONDER,0,1,TRUE,FALSE},
+#ifdef P2P
+ {SECURITY_ASSOCIATION,0,1,TRUE,FALSE},
+ {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE},
+ {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE},
+#else
{SECURITY_ASSOCIATION,1,1,TRUE,FALSE},
{TRAFFIC_SELECTOR_INITIATOR,1,1,TRUE,FALSE},
{TRAFFIC_SELECTOR_RESPONDER,1,1,TRUE,FALSE},
+#endif /* P2P */
{CONFIGURATION,0,1,TRUE,FALSE},
{VENDOR_ID,0,10,TRUE,FALSE},
};
@@ -222,6 +229,24 @@ static payload_rule_t create_child_sa_r_payload_rules[] = {
{VENDOR_ID,0,10,TRUE,FALSE},
};
+#ifdef P2P
+/**
+ * Message rule for P2P_CONNECT from initiator.
+ */
+static payload_rule_t p2p_connect_i_payload_rules[] = {
+ {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE},
+ {ID_PEER,1,1,TRUE,FALSE},
+ {VENDOR_ID,0,10,TRUE,FALSE}
+};
+
+/**
+ * Message rule for P2P_CONNECT from responder.
+ */
+static payload_rule_t p2p_connect_r_payload_rules[] = {
+ {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE},
+ {VENDOR_ID,0,10,TRUE,FALSE}
+};
+#endif /* P2P */
/**
* Message rules, defines allowed payloads.
@@ -235,6 +260,10 @@ static message_rule_t message_rules[] = {
{INFORMATIONAL,FALSE,TRUE,(sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)),informational_r_payload_rules},
{CREATE_CHILD_SA,TRUE,TRUE,(sizeof(create_child_sa_i_payload_rules)/sizeof(payload_rule_t)),create_child_sa_i_payload_rules},
{CREATE_CHILD_SA,FALSE,TRUE,(sizeof(create_child_sa_r_payload_rules)/sizeof(payload_rule_t)),create_child_sa_r_payload_rules},
+#ifdef P2P
+ {P2P_CONNECT,TRUE,TRUE,(sizeof(p2p_connect_i_payload_rules)/sizeof(payload_rule_t)),p2p_connect_i_payload_rules},
+ {P2P_CONNECT,FALSE,TRUE,(sizeof(p2p_connect_r_payload_rules)/sizeof(payload_rule_t)),p2p_connect_r_payload_rules},
+#endif /* P2P */
};
@@ -446,6 +475,14 @@ static exchange_type_t get_exchange_type (private_message_t *this)
}
/**
+ * Implementation of message_t.get_first_payload_type.
+ */
+static payload_type_t get_first_payload_type (private_message_t *this)
+{
+ return this->first_payload;
+}
+
+/**
* Implementation of message_t.set_request.
*/
static void set_request (private_message_t *this,bool request)
@@ -672,6 +709,13 @@ static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, si
return SUCCESS;
}
+ if (!crypter || !signer)
+ {
+ DBG2(DBG_ENC, "no crypter or signer specified, do not encrypt message");
+ /* message contains no content to encrypt */
+ return SUCCESS;
+ }
+
DBG2(DBG_ENC, "copy all payloads to a temporary list");
all_payloads = linked_list_create();
@@ -1255,6 +1299,7 @@ message_t *message_create_from_packet(packet_t *packet)
this->public.get_ike_sa_id = (ike_sa_id_t*(*)(message_t*))get_ike_sa_id;
this->public.set_exchange_type = (void(*)(message_t*, exchange_type_t))set_exchange_type;
this->public.get_exchange_type = (exchange_type_t(*)(message_t*))get_exchange_type;
+ this->public.get_first_payload_type = (payload_type_t(*)(message_t*))get_first_payload_type;
this->public.set_request = (void(*)(message_t*, bool))set_request;
this->public.get_request = (bool(*)(message_t*))get_request;
this->public.add_payload = (void(*)(message_t*,payload_t*))add_payload;
diff --git a/src/charon/encoding/message.h b/src/charon/encoding/message.h
index 73c2e05c6..35b659f33 100644
--- a/src/charon/encoding/message.h
+++ b/src/charon/encoding/message.h
@@ -6,7 +6,8 @@
*/
/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -152,6 +153,14 @@ struct message_t {
* @return exchange type of the message
*/
exchange_type_t (*get_exchange_type) (message_t *this);
+
+ /**
+ * @brief Gets the payload type of the first payload.
+ *
+ * @param this message_t object
+ * @return payload type of the first payload
+ */
+ payload_type_t (*get_first_payload_type) (message_t *this);
/**
* @brief Sets the request flag.
@@ -319,7 +328,7 @@ struct message_t {
iterator_t * (*get_payload_iterator) (message_t *this);
/**
- * @brief Find a payload of a spicific type.
+ * @brief Find a payload of a specific type.
*
* Returns the first occurance.
*
diff --git a/src/charon/encoding/payloads/endpoint_notify.c b/src/charon/encoding/payloads/endpoint_notify.c
new file mode 100644
index 000000000..30f3ecd5f
--- /dev/null
+++ b/src/charon/encoding/payloads/endpoint_notify.c
@@ -0,0 +1,422 @@
+/**
+ * @file endpoint_notify.c
+ *
+ * @brief Implementation of endpoint_notify_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2007 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+#include "endpoint_notify.h"
+
+#include <math.h>
+
+#include <daemon.h>
+
+typedef struct private_endpoint_notify_t private_endpoint_notify_t;
+
+/**
+ * Private data of an notify_payload_t object.
+ *
+ */
+struct private_endpoint_notify_t {
+ /**
+ * Public endpoint_notify_t interface.
+ */
+ endpoint_notify_t public;
+
+ /**
+ * Priority
+ */
+ u_int32_t priority;
+
+ /**
+ * Family
+ */
+ p2p_endpoint_family_t family;
+
+ /**
+ * Endpoint type
+ */
+ p2p_endpoint_type_t type;
+
+ /**
+ * Endpoint
+ */
+ host_t *endpoint;
+
+ /**
+ * Base (used for server reflexive endpoints)
+ */
+ host_t *base;
+};
+
+/* Notification data:
+ 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Priority !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Family ! Type ! Port !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! IP Address (variable)
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+/**
+ * Helper functions to parse integer values
+ */
+static status_t parse_uint8(u_int8_t **cur, u_int8_t *top, u_int8_t *val)
+{
+ if (*cur + sizeof(u_int8_t) > top)
+ {
+ return FAILED;
+ }
+ *val = *(u_int8_t*)*cur;
+ *cur += sizeof(u_int8_t);
+ return SUCCESS;
+}
+
+static status_t parse_uint16(u_int8_t **cur, u_int8_t *top, u_int16_t *val)
+{
+ if (*cur + sizeof(u_int16_t) > top)
+ {
+ return FAILED;
+ }
+ *val = ntohs(*(u_int16_t*)*cur);
+ *cur += sizeof(u_int16_t);
+ return SUCCESS;
+}
+
+static status_t parse_uint32(u_int8_t **cur, u_int8_t *top, u_int32_t *val)
+{
+ if (*cur + sizeof(u_int32_t) > top)
+ {
+ return FAILED;
+ }
+ *val = ntohl(*(u_int32_t*)*cur);
+ *cur += sizeof(u_int32_t);
+ return SUCCESS;
+}
+
+/**
+ * Parses the notification data of a P2P_ENDPOINT notify
+ */
+static status_t parse_notification_data(private_endpoint_notify_t *this, chunk_t data)
+{
+ u_int8_t family, type, addr_family;
+ u_int16_t port;
+ chunk_t addr;
+ u_int8_t *cur = data.ptr;
+ u_int8_t *top = data.ptr + data.len;
+
+ DBG3(DBG_IKE, "p2p_endpoint_data %B", &data);
+
+ if (parse_uint32(&cur, top, &this->priority) != SUCCESS)
+ {
+ DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid priority");
+ return FAILED;
+ }
+
+ if (parse_uint8(&cur, top, &family) != SUCCESS || family >= MAX_FAMILY)
+ {
+ DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid family");
+ return FAILED;
+ }
+
+ this->family = (p2p_endpoint_family_t)family;
+
+ if (parse_uint8(&cur, top, &type) != SUCCESS || type >= MAX_TYPE)
+ {
+ DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid type");
+ return FAILED;
+ }
+
+ this->type = (p2p_endpoint_type_t)type;
+
+ addr_family = AF_INET;
+ addr.len = 4;
+
+ switch(this->family)
+ {
+ case NO_FAMILY:
+ this->endpoint = NULL;
+ break;
+
+ case IPv6:
+ addr_family = AF_INET6;
+ addr.len = 16;
+ // fall-through
+ case IPv4:
+ if (parse_uint16(&cur, top, &port) != SUCCESS)
+ {
+ DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid port");
+ return FAILED;
+ }
+
+ if (cur + addr.len > top)
+ {
+ DBG1(DBG_IKE, "failed to parse P2P_ENDPOINT: invalid IP address");
+ return FAILED;
+ }
+
+ addr.ptr = cur;
+
+ this->endpoint = host_create_from_chunk(addr_family, addr, port);
+ break;
+ }
+
+ return SUCCESS;
+}
+
+
+/**
+ * Generates the notification data of a P2P_ENDPOINT notify
+ */
+static chunk_t build_notification_data(private_endpoint_notify_t *this)
+{
+ chunk_t prio_chunk, family_chunk, type_chunk, port_chunk, addr_chunk;
+ chunk_t data;
+ u_int32_t prio;
+ u_int16_t port;
+ u_int8_t family, type;
+
+ prio = htonl(this->priority);
+ prio_chunk = chunk_from_thing(prio);
+ family = this->family;
+ family_chunk = chunk_from_thing(family);
+ type = this->type;
+ type_chunk = chunk_from_thing(type);
+
+ if (this->endpoint)
+ {
+ port = htons(this->endpoint->get_port(this->endpoint));
+ addr_chunk = this->endpoint->get_address(this->endpoint);
+ }
+ else
+ {
+ port = 0;
+ addr_chunk = chunk_empty;
+ }
+ port_chunk = chunk_from_thing(port);
+
+ // data = prio | family | type | port | addr
+ data = chunk_cat("ccccc", prio_chunk, family_chunk, type_chunk,
+ port_chunk, addr_chunk);
+ DBG3(DBG_IKE, "p2p_endpoint_data %B", &data);
+
+ return data;
+}
+
+/**
+ * Implementation of endpoint_notify_t.build_notify
+ */
+static notify_payload_t *build_notify(private_endpoint_notify_t *this)
+{
+ chunk_t data;
+ notify_payload_t *notify;
+
+ notify = notify_payload_create();
+ notify->set_notify_type(notify, P2P_ENDPOINT);
+ data = build_notification_data(this);
+ notify->set_notification_data(notify, data);
+ chunk_free(&data);
+
+ return notify;
+}
+
+/**
+ * Implementation of endpoint_notify_t.get_priority.
+ */
+static u_int32_t get_priority(private_endpoint_notify_t *this)
+{
+ return this->priority;
+}
+
+/**
+ * Implementation of endpoint_notify_t.set_priority.
+ */
+static void set_priority(private_endpoint_notify_t *this, u_int32_t priority)
+{
+ return this->priority = priority;
+}
+
+/**
+ * Implementation of endpoint_notify_t.get_type.
+ */
+static p2p_endpoint_type_t get_type(private_endpoint_notify_t *this)
+{
+ return this->type;
+}
+
+/**
+ * Implementation of endpoint_notify_t.get_family.
+ */
+static p2p_endpoint_family_t get_family(private_endpoint_notify_t *this)
+{
+ return this->family;
+}
+
+/**
+ * Implementation of endpoint_notify_t.get_host.
+ */
+static host_t *get_host(private_endpoint_notify_t *this)
+{
+ return this->endpoint;
+}
+
+/**
+ * Implementation of endpoint_notify_t.get_base.
+ */
+static host_t *get_base(private_endpoint_notify_t *this)
+{
+ return (!this->base) ? this->endpoint : this->base;
+}
+
+/**
+ * Implementation of endpoint_notify_t.clone.
+ */
+static endpoint_notify_t *_clone(private_endpoint_notify_t *this)
+{
+ private_endpoint_notify_t *clone = (private_endpoint_notify_t*)endpoint_notify_create();
+
+ clone->priority = this->priority;
+ clone->type = this->type;
+ clone->family = this->family;
+ if (this->endpoint)
+ {
+ clone->endpoint = this->endpoint->clone(this->endpoint);
+ }
+
+ if (this->base)
+ {
+ clone->base = this->base->clone(this->base);
+ }
+
+ return &clone->public;
+}
+
+/**
+ * Implementation of endpoint_notify_t.destroy.
+ */
+static status_t destroy(private_endpoint_notify_t *this)
+{
+ DESTROY_IF(this->endpoint);
+ free(this);
+ return SUCCESS;
+}
+
+/*
+ * Described in header
+ */
+endpoint_notify_t *endpoint_notify_create()
+{
+ private_endpoint_notify_t *this = malloc_thing(private_endpoint_notify_t);
+
+ /* public functions */
+ this->public.get_priority = (u_int32_t (*) (endpoint_notify_t *)) get_priority;
+ this->public.set_priority = (void (*) (endpoint_notify_t *, u_int32_t)) set_priority;
+ this->public.get_type = (p2p_endpoint_type_t (*) (endpoint_notify_t *)) get_type;
+ this->public.get_family = (p2p_endpoint_family_t (*) (endpoint_notify_t *)) get_family;
+ this->public.get_host = (host_t *(*) (endpoint_notify_t *)) get_host;
+ this->public.get_base = (host_t *(*) (endpoint_notify_t *)) get_base;
+ this->public.build_notify = (notify_payload_t *(*) (endpoint_notify_t *)) build_notify;
+ this->public.clone = (endpoint_notify_t *(*) (endpoint_notify_t *)) _clone;
+ this->public.destroy = (void (*) (endpoint_notify_t *)) destroy;
+
+ /* set default values of the fields */
+ this->priority = 0;
+ this->family = NO_FAMILY;
+ this->type = NO_TYPE;
+ this->endpoint = NULL;
+ this->base = NULL;
+
+ return &this->public;
+}
+
+/**
+ * Described in header
+ */
+endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type, host_t *host, host_t *base)
+{
+ private_endpoint_notify_t *this = (private_endpoint_notify_t*)endpoint_notify_create();
+
+ this->type = type;
+
+ switch(type)
+ {
+ case HOST:
+ this->priority = pow(2, 16) * P2P_PRIO_HOST;
+ break;
+ case SERVER_REFLEXIVE:
+ this->priority = pow(2, 16) * P2P_PRIO_SERVER;
+ break;
+ case PEER_REFLEXIVE:
+ this->priority = pow(2, 16) * P2P_PRIO_PEER;
+ break;
+ case RELAYED:
+ this->priority = pow(2, 16) * P2P_PRIO_RELAY;
+ break;
+ }
+
+ this->priority += 65535;
+
+ if (!host) {
+ return &this->public;
+ }
+
+ switch(host->get_family(host))
+ {
+ case AF_INET:
+ this->family = IPv4;
+ break;
+ case AF_INET6:
+ this->family = IPv6;
+ break;
+ default:
+ // unsupported family type, we do not set the hsot (family is set to NO_FAMILY)
+ return &this->public;
+ }
+
+ this->endpoint = host->clone(host);
+
+ if (base)
+ {
+ this->base = base->clone(base);
+ }
+
+ return &this->public;
+}
+
+/**
+ * Described in header
+ */
+endpoint_notify_t *endpoint_notify_create_from_payload(notify_payload_t *notify)
+{
+ if (notify->get_notify_type(notify) != P2P_ENDPOINT)
+ {
+ return NULL;
+ }
+
+ private_endpoint_notify_t *this = (private_endpoint_notify_t*)endpoint_notify_create();
+ chunk_t data = notify->get_notification_data(notify);
+ if (parse_notification_data(this, data) != SUCCESS)
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
diff --git a/src/charon/encoding/payloads/endpoint_notify.h b/src/charon/encoding/payloads/endpoint_notify.h
new file mode 100644
index 000000000..272301d5b
--- /dev/null
+++ b/src/charon/encoding/payloads/endpoint_notify.h
@@ -0,0 +1,185 @@
+/**
+ * @file endpoint_notify.h
+ *
+ * @brief Interface of endpoint_notify_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2007 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+
+#ifndef ENDPOINT_NOTIFY_H_
+#define ENDPOINT_NOTIFY_H_
+
+#define P2P_PRIO_HOST 255
+#define P2P_PRIO_SERVER 100
+#define P2P_PRIO_PEER 120
+#define P2P_PRIO_RELAY 0
+
+typedef enum p2p_endpoint_family_t p2p_endpoint_family_t;
+typedef enum p2p_endpoint_type_t p2p_endpoint_type_t;
+typedef struct endpoint_notify_t endpoint_notify_t;
+
+#include <encoding/payloads/notify_payload.h>
+
+enum p2p_endpoint_family_t {
+
+ NO_FAMILY = 0,
+
+ IPv4 = 1,
+
+ IPv6 = 2,
+
+ MAX_FAMILY = 3
+
+};
+
+enum p2p_endpoint_type_t {
+
+ NO_TYPE = 0,
+
+ HOST = 1,
+
+ SERVER_REFLEXIVE = 2,
+
+ PEER_REFLEXIVE = 3,
+
+ RELAYED = 4,
+
+ MAX_TYPE = 5
+
+};
+
+/**
+ * @brief Class representing a P2P_ENDPOINT notify. In fact it's not
+ * the notify per se, but the notification data of that notify that is
+ * handled with this class.
+ *
+ * @b Constructors:
+ * - endpoint_notify_create()
+ * - endpoint_notify_create_from_host()
+ *
+ * @ingroup payloads
+ */
+struct endpoint_notify_t {
+ /**
+ * @brief Returns the priority of this endpoint.
+ *
+ * @param this object
+ * @return priority
+ */
+ u_int32_t (*get_priority) (endpoint_notify_t *this);
+
+ /**
+ * @brief Sets the priority of this endpoint.
+ *
+ * @param this object
+ * @param priority priority
+ */
+ void (*set_priority) (endpoint_notify_t *this, u_int32_t priority);
+
+ /**
+ * @brief Returns the endpoint type of this endpoint.
+ *
+ * @param this object
+ * @return endpoint type
+ */
+ p2p_endpoint_type_t (*get_type) (endpoint_notify_t *this);
+
+ /**
+ * @brief Returns the endpoint family of this endpoint.
+ *
+ * @param this object
+ * @return endpoint family
+ */
+ p2p_endpoint_family_t (*get_family) (endpoint_notify_t *this);
+
+ /**
+ * @brief Returns the host of this endpoint.
+ *
+ * @param this object
+ * @return host
+ */
+ host_t *(*get_host) (endpoint_notify_t *this);
+
+ /**
+ * @brief Returns the base of this endpoint.
+ *
+ * If this is not a SERVER_REFLEXIVE endpoint, the returned host is the same
+ * as the one returned by get_host.
+ *
+ * @param this object
+ * @return host
+ */
+ host_t *(*get_base) (endpoint_notify_t *this);
+
+ /**
+ * @brief Generates a notification payload from this endpoint.
+ *
+ * @param this object
+ * @return built notify_payload_t
+ */
+ notify_payload_t *(*build_notify) (endpoint_notify_t *this);
+
+ /**
+ * @brief Clones an endpoint_notify_t object.
+ *
+ * @param this endpoint_notify_t object to clone
+ * @return cloned object
+ */
+ endpoint_notify_t *(*clone) (endpoint_notify_t *this);
+
+ /**
+ * @brief Destroys an endpoint_notify_t object.
+ *
+ * @param this endpoint_notify_t object to destroy
+ */
+ void (*destroy) (endpoint_notify_t *this);
+};
+
+/**
+ * @brief Creates an empty endpoint_notify_t object.
+ *
+ * @return created endpoint_notify_t object
+ *
+ * @ingroup payloads
+ */
+endpoint_notify_t *endpoint_notify_create(void);
+
+
+/**
+ * @brief Creates an endpoint_notify_t object from a host.
+ *
+ * @param type the endpoint type
+ * @param host host to base the notify on (gets cloned)
+ * @param base base of the endpoint, applies only to reflexive endpoints (gets cloned)
+ * @return created endpoint_notify_t object
+ *
+ * @ingroup payloads
+ */
+endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type, host_t *host, host_t *base);
+
+/**
+ * @brief Creates an endpoint_notify_t object from a notify payload.
+ *
+ * @param notify the notify payload
+ * @return - created endpoint_notify_t object
+ * - NULL if invalid payload
+ * @ingroup payloads
+ */
+endpoint_notify_t *endpoint_notify_create_from_payload(notify_payload_t *notify);
+
+#endif /*ENDPOINT_NOTIFY_H_*/
diff --git a/src/charon/encoding/payloads/id_payload.c b/src/charon/encoding/payloads/id_payload.c
index 74c0ce870..eee5e92db 100644
--- a/src/charon/encoding/payloads/id_payload.c
+++ b/src/charon/encoding/payloads/id_payload.c
@@ -6,6 +6,7 @@
*/
/*
+ * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -41,14 +42,14 @@ struct private_id_payload_t {
id_payload_t public;
/**
- * TRUE if this ID payload is of type IDi, FALSE for IDr.
+ * one of ID_INITIATOR, ID_RESPONDER
*/
- bool is_initiator;
+ payload_type_t payload_type;
/**
* Next payload type.
*/
- u_int8_t next_payload;
+ payload_type_t next_payload;
/**
* Critical flag.
@@ -149,14 +150,7 @@ static void get_encoding_rules(private_id_payload_t *this, encoding_rule_t **rul
*/
static payload_type_t get_payload_type(private_id_payload_t *this)
{
- if (this->is_initiator)
- {
- return ID_INITIATOR;
- }
- else
- {
- return ID_RESPONDER;
- }
+ return this->payload_type;
}
/**
@@ -164,7 +158,7 @@ static payload_type_t get_payload_type(private_id_payload_t *this)
*/
static payload_type_t get_next_type(private_id_payload_t *this)
{
- return (this->next_payload);
+ return this->next_payload;
}
/**
@@ -238,22 +232,6 @@ static chunk_t get_data_clone (private_id_payload_t *this)
}
/**
- * Implementation of id_payload_t.get_initiator.
- */
-static bool get_initiator (private_id_payload_t *this)
-{
- return (this->is_initiator);
-}
-
-/**
- * Implementation of id_payload_t.set_initiator.
- */
-static void set_initiator (private_id_payload_t *this,bool is_initiator)
-{
- this->is_initiator = is_initiator;
-}
-
-/**
* Implementation of id_payload_t.get_identification.
*/
static identification_t *get_identification (private_id_payload_t *this)
@@ -276,7 +254,7 @@ static void destroy(private_id_payload_t *this)
/*
* Described in header.
*/
-id_payload_t *id_payload_create(bool is_initiator)
+id_payload_t *id_payload_create(payload_type_t payload_type)
{
private_id_payload_t *this = malloc_thing(private_id_payload_t);
@@ -297,8 +275,6 @@ id_payload_t *id_payload_create(bool is_initiator)
this->public.get_data = (chunk_t (*) (id_payload_t *)) get_data;
this->public.get_data_clone = (chunk_t (*) (id_payload_t *)) get_data_clone;
- this->public.get_initiator = (bool (*) (id_payload_t *)) get_initiator;
- this->public.set_initiator = (void (*) (id_payload_t *,bool)) set_initiator;
this->public.get_identification = (identification_t * (*) (id_payload_t *this)) get_identification;
/* private variables */
@@ -306,7 +282,7 @@ id_payload_t *id_payload_create(bool is_initiator)
this->next_payload = NO_PAYLOAD;
this->payload_length =ID_PAYLOAD_HEADER_LENGTH;
this->id_data = chunk_empty;
- this->is_initiator = is_initiator;
+ this->payload_type = payload_type;
return (&(this->public));
}
@@ -314,9 +290,9 @@ id_payload_t *id_payload_create(bool is_initiator)
/*
* Described in header.
*/
-id_payload_t *id_payload_create_from_identification(bool is_initiator,identification_t *identification)
+id_payload_t *id_payload_create_from_identification(payload_type_t payload_type, identification_t *identification)
{
- id_payload_t *this= id_payload_create(is_initiator);
+ id_payload_t *this= id_payload_create(payload_type);
this->set_data(this,identification->get_encoding(identification));
this->set_id_type(this,identification->get_type(identification));
return this;
diff --git a/src/charon/encoding/payloads/id_payload.h b/src/charon/encoding/payloads/id_payload.h
index b67d85d2e..8e9322b4a 100644
--- a/src/charon/encoding/payloads/id_payload.h
+++ b/src/charon/encoding/payloads/id_payload.h
@@ -6,6 +6,7 @@
*/
/*
+ * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -112,28 +113,6 @@ struct id_payload_t {
identification_t *(*get_identification) (id_payload_t *this);
/**
- * @brief Get the type of ID payload (IDi or IDr).
- *
- * @param this calling id_payload_t object
- * @return
- * - TRUE if this payload is of type IDi
- * - FALSE if this payload is of type IDr
- *
- */
- bool (*get_initiator) (id_payload_t *this);
-
- /**
- * @brief Set the type of ID payload (IDi or IDr).
- *
- * @param this calling id_payload_t object
- * @param is_initiator
- * - TRUE if this payload is of type IDi
- * - FALSE if this payload is of type IDr
- *
- */
- void (*set_initiator) (id_payload_t *this,bool is_initiator);
-
- /**
* @brief Destroys an id_payload_t object.
*
* @param this id_payload_t object to destroy
@@ -144,28 +123,23 @@ struct id_payload_t {
/**
* @brief Creates an empty id_payload_t object.
*
- * @param is_initiator
- * - TRUE if this payload is of type IDi
- * - FALSE if this payload is of type IDr
- *
+ * @param payload_type one of ID_INITIATOR, ID_RESPONDER
* @return id_payload_t object
*
* @ingroup payloads
*/
-id_payload_t *id_payload_create(bool is_initiator);
+id_payload_t *id_payload_create(payload_type_t payload_type);
/**
* @brief Creates an id_payload_t from an existing identification_t object.
*
- * @param is_initiator
- * - TRUE if this payload is of type IDi
- * - FALSE if this payload is of type IDr
+ * @param payload_type one of ID_INITIATOR, ID_RESPONDER
* @param identification identification_t object
* @return id_payload_t object
*
* @ingroup payloads
*/
-id_payload_t *id_payload_create_from_identification(bool is_initiator,identification_t *identification);
+id_payload_t *id_payload_create_from_identification(payload_type_t payload_type, identification_t *identification);
diff --git a/src/charon/encoding/payloads/ike_header.c b/src/charon/encoding/payloads/ike_header.c
index b1b4fbf87..7253e4f51 100644
--- a/src/charon/encoding/payloads/ike_header.c
+++ b/src/charon/encoding/payloads/ike_header.c
@@ -6,6 +6,7 @@
*/
/*
+ * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -109,7 +110,13 @@ ENUM_NEXT(exchange_type_names, IKE_SA_INIT, INFORMATIONAL, EXCHANGE_TYPE_UNDEFIN
"IKE_AUTH",
"CREATE_CHILD_SA",
"INFORMATIONAL");
+#ifdef P2P
+ENUM_NEXT(exchange_type_names, P2P_CONNECT, P2P_CONNECT, INFORMATIONAL,
+ "P2P_CONNECT");
+ENUM_END(exchange_type_names, P2P_CONNECT);
+#else
ENUM_END(exchange_type_names, INFORMATIONAL);
+#endif /* P2P */
/**
* Encoding rules to parse or generate a IKEv2-Header.
@@ -172,12 +179,23 @@ encoding_rule_t ike_header_encodings[] = {
*/
static status_t verify(private_ike_header_t *this)
{
- if ((this->exchange_type < IKE_SA_INIT) || (this->exchange_type > INFORMATIONAL))
+ if ((this->exchange_type < IKE_SA_INIT) ||
+ ((this->exchange_type > INFORMATIONAL)
+#ifdef P2P
+ && (this->exchange_type != P2P_CONNECT)
+#endif /* P2P */
+ ))
{
/* unsupported exchange type */
return FAILED;
}
- if (this->initiator_spi == 0)
+
+ if (this->initiator_spi == 0
+#ifdef P2P
+ // we allow zero spi for INFORMATIONAL exchanges, to allow P2P connectivity checks
+ && this->exchange_type != INFORMATIONAL
+#endif /* P2P */
+ )
{
/* initiator spi not set */
return FAILED;
diff --git a/src/charon/encoding/payloads/ike_header.h b/src/charon/encoding/payloads/ike_header.h
index 95c20f810..e80964482 100644
--- a/src/charon/encoding/payloads/ike_header.h
+++ b/src/charon/encoding/payloads/ike_header.h
@@ -6,6 +6,7 @@
*/
/*
+ * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -70,7 +71,7 @@ enum exchange_type_t{
/**
* EXCHANGE_TYPE_UNDEFINED. In private space, since not a official message type.
*/
- EXCHANGE_TYPE_UNDEFINED = 240,
+ EXCHANGE_TYPE_UNDEFINED = 255,
/**
* IKE_SA_INIT.
@@ -90,7 +91,13 @@ enum exchange_type_t{
/**
* INFORMATIONAL.
*/
- INFORMATIONAL = 37
+ INFORMATIONAL = 37,
+#ifdef P2P
+ /**
+ * P2P_CONNECT
+ */
+ P2P_CONNECT = 240
+#endif /* P2P */
};
/**
diff --git a/src/charon/encoding/payloads/notify_payload.c b/src/charon/encoding/payloads/notify_payload.c
index e27d3c68f..74a6c3197 100644
--- a/src/charon/encoding/payloads/notify_payload.c
+++ b/src/charon/encoding/payloads/notify_payload.c
@@ -6,7 +6,8 @@
*/
/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -56,7 +57,13 @@ ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, UNEXPECTED_NAT_DETECTED, AUTH
"INVALID_SELECTORS",
"UNACCEPTABLE_ADDRESSES",
"UNEXPECTED_NAT_DETECTED");
+#ifdef P2P
+ENUM_NEXT(notify_type_names, P2P_CONNECT_FAILED, P2P_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED,
+ "P2P_CONNECT_FAILED");
+ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, P2P_CONNECT_FAILED,
+#else
ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETECTED,
+#endif /* P2P */
"INITIAL_CONTACT",
"SET_WINDOW_SIZE",
"ADDITIONAL_TS_POSSIBLE",
@@ -79,7 +86,20 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETE
"AUTH_LIFETIME");
ENUM_NEXT(notify_type_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, AUTH_LIFETIME,
"EAP_ONLY_AUTHENTICATION");
+#ifdef P2P
+ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
+ "USE_BEET_MODE");
+ENUM_NEXT(notify_type_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
+ "P2P_MEDIATION",
+ "P2P_ENDPOINT",
+ "P2P_CALLBACK",
+ "P2P_SESSIONID",
+ "P2P_SESSIONKEY",
+ "P2P_RESPONSE");
+ENUM_END(notify_type_names, P2P_RESPONSE);
+#else
ENUM_END(notify_type_names, EAP_ONLY_AUTHENTICATION);
+#endif /* P2P */
ENUM_BEGIN(notify_type_short_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
@@ -108,7 +128,13 @@ ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, UNEXPECTED_NAT_DETECTED
"INVAL_SEL",
"UNACCEPT_ADDR",
"UNEXPECT_NAT");
+#ifdef P2P
+ENUM_NEXT(notify_type_short_names, P2P_CONNECT_FAILED, P2P_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED,
+ "P2P_CONN_FAIL");
+ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, P2P_CONNECT_FAILED,
+#else
ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETECTED,
+#endif /* P2P */
"INIT_CONTACT",
"SET_WINSIZE",
"ADD_TS_POSS",
@@ -131,7 +157,20 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NA
"AUTH_LFT");
ENUM_NEXT(notify_type_short_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, AUTH_LIFETIME,
"EAP_ONLY");
+#ifdef P2P
+ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
+ "BEET_MODE");
+ENUM_NEXT(notify_type_short_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
+ "P2P_MED",
+ "P2P_EP",
+ "P2P_CB",
+ "P2P_SID",
+ "P2P_SKEY",
+ "P2P_R");
+ENUM_END(notify_type_short_names, P2P_RESPONSE);
+#else
ENUM_END(notify_type_short_names, EAP_ONLY_AUTHENTICATION);
+#endif /* P2P */
typedef struct private_notify_payload_t private_notify_payload_t;
@@ -303,6 +342,7 @@ static status_t verify(private_notify_payload_t *this)
}
break;
}
+ // FIXME: check size of P2P-NAT-T payloads
default:
/* TODO: verify */
break;
diff --git a/src/charon/encoding/payloads/notify_payload.h b/src/charon/encoding/payloads/notify_payload.h
index 231d0408d..4a9ad992b 100644
--- a/src/charon/encoding/payloads/notify_payload.h
+++ b/src/charon/encoding/payloads/notify_payload.h
@@ -6,7 +6,8 @@
*/
/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -67,6 +68,10 @@ enum notify_type_t {
INVALID_SELECTORS = 39,
UNACCEPTABLE_ADDRESSES = 40,
UNEXPECTED_NAT_DETECTED = 41,
+#ifdef P2P
+ /* P2P-NAT-T, private use */
+ P2P_CONNECT_FAILED = 8192,
+#endif /* P2P */
/* notify status messages */
INITIAL_CONTACT = 16384,
SET_WINDOW_SIZE = 16385,
@@ -94,6 +99,15 @@ enum notify_type_t {
EAP_ONLY_AUTHENTICATION = 40960,
/* BEET mode, not even a draft yet. private use */
USE_BEET_MODE = 40961,
+#ifdef P2P
+ /* P2P-NAT-T, private use */
+ P2P_MEDIATION = 40962,
+ P2P_ENDPOINT = 40963,
+ P2P_CALLBACK = 40964,
+ P2P_SESSIONID = 40965,
+ P2P_SESSIONKEY = 40966,
+ P2P_RESPONSE = 40967
+#endif /* P2P */
};
/**
diff --git a/src/charon/encoding/payloads/payload.c b/src/charon/encoding/payloads/payload.c
index 3bd4cdb13..2c51c60de 100644
--- a/src/charon/encoding/payloads/payload.c
+++ b/src/charon/encoding/payloads/payload.c
@@ -7,6 +7,7 @@
*/
/*
+ * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -63,7 +64,13 @@ ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, N
"ENCRYPTED",
"CONFIGURATION",
"EXTENSIBLE_AUTHENTICATION");
+#ifdef P2P
+ENUM_NEXT(payload_type_names, ID_PEER, ID_PEER, EXTENSIBLE_AUTHENTICATION,
+ "ID_PEER");
+ENUM_NEXT(payload_type_names, HEADER, UNKNOWN_PAYLOAD, ID_PEER,
+#else
ENUM_NEXT(payload_type_names, HEADER, UNKNOWN_PAYLOAD, EXTENSIBLE_AUTHENTICATION,
+#endif /* P2P */
"HEADER",
"PROPOSAL_SUBSTRUCTURE",
"TRANSFORM_SUBSTRUCTURE",
@@ -93,7 +100,13 @@ ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICAT
"E",
"CP",
"EAP");
+#ifdef P2P
+ENUM_NEXT(payload_type_short_names, ID_PEER, ID_PEER, EXTENSIBLE_AUTHENTICATION,
+ "IDp");
+ENUM_NEXT(payload_type_short_names, HEADER, UNKNOWN_PAYLOAD, ID_PEER,
+#else
ENUM_NEXT(payload_type_short_names, HEADER, UNKNOWN_PAYLOAD, EXTENSIBLE_AUTHENTICATION,
+#endif /* P2P */
"HDR",
"PROP",
"TRANS",
@@ -123,9 +136,13 @@ payload_t *payload_create(payload_type_t type)
case NONCE:
return (payload_t*)nonce_payload_create();
case ID_INITIATOR:
- return (payload_t*)id_payload_create(TRUE);
+ return (payload_t*)id_payload_create(ID_INITIATOR);
case ID_RESPONDER:
- return (payload_t*)id_payload_create(FALSE);
+ return (payload_t*)id_payload_create(ID_RESPONDER);
+#ifdef P2P
+ case ID_PEER:
+ return (payload_t*)id_payload_create(ID_PEER);
+#endif /* P2P */
case AUTHENTICATION:
return (payload_t*)auth_payload_create();
case CERTIFICATE:
diff --git a/src/charon/encoding/payloads/payload.h b/src/charon/encoding/payloads/payload.h
index 9a8c2f482..ab902d755 100644
--- a/src/charon/encoding/payloads/payload.h
+++ b/src/charon/encoding/payloads/payload.h
@@ -6,6 +6,7 @@
*/
/*
+ * Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -126,10 +127,18 @@ enum payload_type_t{
*/
EXTENSIBLE_AUTHENTICATION = 48,
+#ifdef P2P
+ /**
+ * Identification payload for peers in P2P-NAT-T has a value from
+ * the PRIVATE USE space.
+ */
+ ID_PEER = 128,
+#endif /* P2P */
+
/**
* Header has a value of PRIVATE USE space.
*
- * This payload type is not send over wire and just
+ * This payload type is not sent over wire and just
* used internally to handle IKEv2-Header like a payload.
*/
HEADER = 140,
@@ -137,7 +146,7 @@ enum payload_type_t{
/**
* PROPOSAL_SUBSTRUCTURE has a value of PRIVATE USE space.
*
- * This payload type is not send over wire and just
+ * This payload type is not sent over wire and just
* used internally to handle a proposal substructure like a payload.
*/
PROPOSAL_SUBSTRUCTURE = 141,
@@ -145,7 +154,7 @@ enum payload_type_t{
/**
* TRANSFORM_SUBSTRUCTURE has a value of PRIVATE USE space.
*
- * This payload type is not send over wire and just
+ * This payload type is not sent over wire and just
* used internally to handle a transform substructure like a payload.
*/
TRANSFORM_SUBSTRUCTURE = 142,
@@ -153,7 +162,7 @@ enum payload_type_t{
/**
* TRANSFORM_ATTRIBUTE has a value of PRIVATE USE space.
*
- * This payload type is not send over wire and just
+ * This payload type is not sent over wire and just
* used internally to handle a transform attribute like a payload.
*/
TRANSFORM_ATTRIBUTE = 143,
@@ -161,7 +170,7 @@ enum payload_type_t{
/**
* TRAFFIC_SELECTOR_SUBSTRUCTURE has a value of PRIVATE USE space.
*
- * This payload type is not send over wire and just
+ * This payload type is not sent over wire and just
* used internally to handle a transform selector like a payload.
*/
TRAFFIC_SELECTOR_SUBSTRUCTURE = 144,
@@ -169,7 +178,7 @@ enum payload_type_t{
/**
* CONFIGURATION_ATTRIBUTE has a value of PRIVATE USE space.
*
- * This payload type is not send over wire and just
+ * This payload type is not sent over wire and just
* used internally to handle a transform attribute like a payload.
*/
CONFIGURATION_ATTRIBUTE = 145,
@@ -177,7 +186,7 @@ enum payload_type_t{
/**
* A unknown payload has a value of PRIVATE USE space.
*
- * This payload type is not send over wire and just
+ * This payload type is not sent over wire and just
* used internally to handle a unknown payload.
*/
UNKNOWN_PAYLOAD = 146,
diff --git a/src/charon/encoding/payloads/sa_payload.c b/src/charon/encoding/payloads/sa_payload.c
index e264b2123..304f1b64c 100644
--- a/src/charon/encoding/payloads/sa_payload.c
+++ b/src/charon/encoding/payloads/sa_payload.c
@@ -123,7 +123,7 @@ static status_t verify(private_sa_payload_t *this)
{
if (current_number != (expected_number + 1))
{
- DBG1(DBG_ENC, "proposal number is %d, excepted %d or %d",
+ DBG1(DBG_ENC, "proposal number is %d, expected %d or %d",
current_number, expected_number, expected_number + 1);
status = FAILED;
break;