summaryrefslogtreecommitdiffstats
path: root/src/plugins/ikev2/ikev2_payload.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/ikev2/ikev2_payload.c')
-rw-r--r--src/plugins/ikev2/ikev2_payload.c114
1 files changed, 87 insertions, 27 deletions
diff --git a/src/plugins/ikev2/ikev2_payload.c b/src/plugins/ikev2/ikev2_payload.c
index b7d7098605c..c03054aa9cd 100644
--- a/src/plugins/ikev2/ikev2_payload.c
+++ b/src/plugins/ikev2/ikev2_payload.c
@@ -38,13 +38,22 @@ typedef CLIB_PACKED (struct {
/* *INDENT-OFF* */
typedef CLIB_PACKED (struct {
+ ip4_address_t start_addr;
+ ip4_address_t end_addr;
+}) ikev2_ip4_addr_pair_t;
+
+typedef CLIB_PACKED (struct {
+ ip6_address_t start_addr;
+ ip6_address_t end_addr;
+}) ikev2_ip6_addr_pair_t;
+
+typedef CLIB_PACKED (struct {
u8 ts_type;
u8 protocol_id;
u16 selector_len;
u16 start_port;
u16 end_port;
- ip4_address_t start_addr;
- ip4_address_t end_addr;
+ u8 addr_pair[0];
}) ikev2_ts_payload_entry_t;
/* *INDENT-OFF* */
@@ -286,12 +295,46 @@ ikev2_payload_add_auth (ikev2_payload_chain_t * c, ikev2_auth_t * auth)
ikev2_payload_add_data (c, auth->data);
}
+static void
+ikev2_payload_add_ts_entry (u8 ** data, ikev2_ts_t * ts)
+{
+ u8 * tmp;
+ ikev2_ts_payload_entry_t *entry;
+ int len = sizeof (*entry);
+
+ if (ts->ts_type == TS_IPV4_ADDR_RANGE)
+ len += sizeof (ikev2_ip4_addr_pair_t);
+ else
+ len += sizeof (ikev2_ip6_addr_pair_t);
+
+ vec_add2 (data[0], tmp, len);
+ entry = (ikev2_ts_payload_entry_t *) tmp;
+ entry->ts_type = ts->ts_type;
+ entry->protocol_id = ts->protocol_id;
+ entry->selector_len = clib_host_to_net_u16 (len);
+ entry->start_port = clib_host_to_net_u16 (ts->start_port);
+ entry->end_port = clib_host_to_net_u16 (ts->end_port);
+
+ if (ts->ts_type == TS_IPV4_ADDR_RANGE)
+ {
+ ikev2_ip4_addr_pair_t *pair = (ikev2_ip4_addr_pair_t*) entry->addr_pair;
+ ip_address_copy_addr (&pair->start_addr, &ts->start_addr);
+ ip_address_copy_addr (&pair->end_addr, &ts->end_addr);
+ }
+ else
+ {
+ ikev2_ip6_addr_pair_t *pair = (ikev2_ip6_addr_pair_t*) entry->addr_pair;
+ ip_address_copy_addr (&pair->start_addr, &ts->start_addr);
+ ip_address_copy_addr (&pair->end_addr, &ts->end_addr);
+ }
+}
+
void
ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts, u8 type)
{
ike_ts_payload_header_t *tsh;
ikev2_ts_t *ts2;
- u8 *data = 0, *tmp;
+ u8 *data = 0;
tsh =
(ike_ts_payload_header_t *) ikev2_payload_add_hdr (c, type,
@@ -300,17 +343,9 @@ ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts, u8 type)
vec_foreach (ts2, ts)
{
- ASSERT (ts2->ts_type == 7); /*TS_IPV4_ADDR_RANGE */
- ikev2_ts_payload_entry_t *entry;
- vec_add2 (data, tmp, sizeof (*entry));
- entry = (ikev2_ts_payload_entry_t *) tmp;
- entry->ts_type = ts2->ts_type;
- entry->protocol_id = ts2->protocol_id;
- entry->selector_len = clib_host_to_net_u16 (16);
- entry->start_port = clib_host_to_net_u16 (ts2->start_port);
- entry->end_port = clib_host_to_net_u16 (ts2->end_port);
- entry->start_addr.as_u32 = ts2->start_addr.as_u32;
- entry->end_addr.as_u32 = ts2->end_addr.as_u32;
+ ASSERT (ts2->ts_type == TS_IPV4_ADDR_RANGE ||
+ ts2->ts_type == TS_IPV6_ADDR_RANGE);
+ ikev2_payload_add_ts_entry (&data, ts2);
}
ikev2_payload_add_data (c, data);
@@ -413,31 +448,56 @@ ikev2_parse_ts_payload (ike_payload_header_t * ikep, u32 rlen)
{
ike_ts_payload_header_t *tsp = (ike_ts_payload_header_t *) ikep;
ikev2_ts_t *r = 0, *ts;
- u8 i;
+ ikev2_ip4_addr_pair_t *pair4;
+ ikev2_ip6_addr_pair_t *pair6;
+ int p = 0, n_left;
+ ikev2_ts_payload_entry_t *pe;
if (sizeof (*tsp) > rlen)
return 0;
- if (sizeof (*tsp) + tsp->num_ts * sizeof (ikev2_ts_payload_entry_t) > rlen)
- return 0;
+ rlen -= sizeof (*tsp);
+ n_left = tsp->num_ts;
- for (i = 0; i < tsp->num_ts; i++)
+ while (n_left && p + sizeof (*pe) < rlen)
{
- if (tsp->ts[i].ts_type != 7) /* TS_IPV4_ADDR_RANGE */
+ pe = (ikev2_ts_payload_entry_t *) (((u8 *)tsp->ts) + p);
+ p += sizeof (*pe);
+
+ if (pe->ts_type != TS_IPV4_ADDR_RANGE &&
+ pe->ts_type != TS_IPV6_ADDR_RANGE)
{
ikev2_elog_uint (IKEV2_LOG_ERROR,
- "unsupported TS type received (%u)", tsp->ts[i].ts_type);
- continue;
+ "unsupported TS type received (%u)", pe->ts_type);
+ return 0;
}
vec_add2 (r, ts, 1);
- ts->ts_type = tsp->ts[i].ts_type;
- ts->protocol_id = tsp->ts[i].protocol_id;
- ts->start_port = tsp->ts[i].start_port;
- ts->end_port = tsp->ts[i].end_port;
- ts->start_addr.as_u32 = tsp->ts[i].start_addr.as_u32;
- ts->end_addr.as_u32 = tsp->ts[i].end_addr.as_u32;
+ ts->ts_type = pe->ts_type;
+ ts->protocol_id = pe->protocol_id;
+ ts->start_port = pe->start_port;
+ ts->end_port = pe->end_port;
+
+ if (pe->ts_type == TS_IPV4_ADDR_RANGE)
+ {
+ pair4 = (ikev2_ip4_addr_pair_t*) pe->addr_pair;
+ ip_address_set (&ts->start_addr, &pair4->start_addr, AF_IP4);
+ ip_address_set (&ts->end_addr, &pair4->end_addr, AF_IP4);
+ p += sizeof (*pair4);
+ }
+ else
+ {
+ pair6 = (ikev2_ip6_addr_pair_t*) pe->addr_pair;
+ ip_address_set (&ts->start_addr, &pair6->start_addr, AF_IP6);
+ ip_address_set (&ts->end_addr, &pair6->end_addr, AF_IP6);
+ p += sizeof (*pair6);
+ }
+ n_left--;
}
+
+ if (n_left)
+ return 0;
+
return r;
}