Line data Source code
1 : /*
2 : * Copyright (c) 2015 Cisco and/or its affiliates.
3 : * Licensed under the Apache License, Version 2.0 (the "License");
4 : * you may not use this file except in compliance with the License.
5 : * You may obtain a copy of the License at:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
9 : * Unless required by applicable law or agreed to in writing, software
10 : * distributed under the License is distributed on an "AS IS" BASIS,
11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : * See the License for the specific language governing permissions and
13 : * limitations under the License.
14 : */
15 :
16 : #include <ctype.h>
17 :
18 : #include <vnet/vnet.h>
19 : #include <vnet/api_errno.h>
20 : #include <vnet/ip/ip.h>
21 : #include <vnet/interface.h>
22 :
23 : #include <vnet/ipsec/ipsec.h>
24 : #include <plugins/ikev2/ikev2.h>
25 : #include <plugins/ikev2/ikev2_priv.h>
26 :
27 : /* *INDENT-OFF* */
28 : typedef CLIB_PACKED (struct {
29 : u8 nextpayload;
30 : u8 flags;
31 : u16 length;
32 : u8 protocol_id;
33 : u8 spi_size;
34 : u16 msg_type;
35 : u8 payload[0];
36 : }) ike_notify_payload_header_t;
37 : /* *INDENT-ON* */
38 :
39 : /* *INDENT-OFF* */
40 : typedef CLIB_PACKED (struct {
41 : ip4_address_t start_addr;
42 : ip4_address_t end_addr;
43 : }) ikev2_ip4_addr_pair_t;
44 :
45 : typedef CLIB_PACKED (struct {
46 : ip6_address_t start_addr;
47 : ip6_address_t end_addr;
48 : }) ikev2_ip6_addr_pair_t;
49 :
50 : typedef CLIB_PACKED (struct {
51 : u8 ts_type;
52 : u8 protocol_id;
53 : u16 selector_len;
54 : u16 start_port;
55 : u16 end_port;
56 : u8 addr_pair[0];
57 : }) ikev2_ts_payload_entry_t;
58 : /* *INDENT-OFF* */
59 :
60 : /* *INDENT-OFF* */
61 : typedef CLIB_PACKED (struct {
62 : u8 nextpayload;
63 : u8 flags;
64 : u16 length;
65 : u8 num_ts;
66 : u8 reserved[3];
67 : ikev2_ts_payload_entry_t ts[0];
68 : }) ike_ts_payload_header_t;
69 : /* *INDENT-OFF* */
70 :
71 : /* *INDENT-OFF* */
72 : typedef CLIB_PACKED (struct {
73 : u8 last_or_more;
74 : u8 reserved;
75 : u16 proposal_len;
76 : u8 proposal_num;
77 : u8 protocol_id;
78 : u8 spi_size;
79 : u8 num_transforms; u32 spi[0];
80 : }) ike_sa_proposal_data_t;
81 : /* *INDENT-OFF* */
82 :
83 : /* *INDENT-OFF* */
84 : typedef CLIB_PACKED (struct {
85 : u8 last_or_more;
86 : u8 reserved;
87 : u16 transform_len;
88 : u8 transform_type;
89 : u8 reserved2;
90 : u16 transform_id;
91 : u8 attributes[0];
92 : }) ike_sa_transform_data_t;
93 : /* *INDENT-OFF* */
94 :
95 : /* *INDENT-OFF* */
96 : typedef CLIB_PACKED (struct {
97 : u8 nextpayload;
98 : u8 flags;
99 : u16 length;
100 : u8 protocol_id;
101 : u8 spi_size;
102 : u16 num_of_spi;
103 : u32 spi[0];
104 : }) ike_delete_payload_header_t;
105 : /* *INDENT-OFF* */
106 :
107 : static ike_payload_header_t *
108 257 : ikev2_payload_add_hdr (ikev2_payload_chain_t * c, u8 payload_type, int len)
109 : {
110 257 : ike_payload_header_t *hdr =
111 257 : (ike_payload_header_t *) & c->data[c->last_hdr_off];
112 : u8 *tmp;
113 :
114 257 : if (c->data)
115 202 : hdr->nextpayload = payload_type;
116 : else
117 55 : c->first_payload_type = payload_type;
118 :
119 257 : c->last_hdr_off = vec_len (c->data);
120 257 : vec_add2 (c->data, tmp, len);
121 257 : hdr = (ike_payload_header_t *) tmp;
122 257 : clib_memset (hdr, 0, len);
123 :
124 257 : hdr->length = clib_host_to_net_u16 (len);
125 :
126 257 : return hdr;
127 : }
128 :
129 : static void
130 298 : ikev2_payload_add_data (ikev2_payload_chain_t * c, u8 * data)
131 : {
132 : u16 len;
133 : ike_payload_header_t *hdr;
134 :
135 298 : vec_append (c->data, data);
136 298 : hdr = (ike_payload_header_t *) & c->data[c->last_hdr_off];
137 298 : len = clib_net_to_host_u16 (hdr->length);
138 298 : hdr->length = clib_host_to_net_u16 (len + vec_len (data));
139 298 : }
140 :
141 : void
142 52 : ikev2_payload_add_notify (ikev2_payload_chain_t * c, u16 msg_type, u8 * data)
143 : {
144 52 : ikev2_payload_add_notify_2(c, msg_type, data, 0);
145 52 : }
146 :
147 : void
148 55 : ikev2_payload_add_notify_2 (ikev2_payload_chain_t * c, u16 msg_type,
149 : u8 * data, ikev2_notify_t * notify)
150 : {
151 : ike_notify_payload_header_t *n;
152 :
153 : n =
154 55 : (ike_notify_payload_header_t *) ikev2_payload_add_hdr (c,
155 : IKEV2_PAYLOAD_NOTIFY,
156 : sizeof (*n));
157 55 : n->msg_type = clib_host_to_net_u16 (msg_type);
158 55 : if (notify)
159 : {
160 3 : n->protocol_id = notify->protocol_id;
161 3 : if (notify->spi)
162 : {
163 3 : n->spi_size = 4;
164 : }
165 : }
166 55 : ikev2_payload_add_data (c, data);
167 55 : }
168 :
169 : void
170 47 : ikev2_payload_add_sa (ikev2_payload_chain_t * c,
171 : ikev2_sa_proposal_t * proposals)
172 : {
173 : ike_payload_header_t *ph;
174 : ike_sa_proposal_data_t *prop;
175 : ike_sa_transform_data_t *tr;
176 : ikev2_sa_proposal_t *p;
177 : ikev2_sa_transform_t *t;
178 :
179 : u8 *tmp;
180 47 : u8 *pr_data = 0;
181 47 : u8 *tr_data = 0;
182 :
183 47 : ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_SA, sizeof (*ph));
184 :
185 94 : vec_foreach (p, proposals)
186 : {
187 47 : int spi_size = (p->protocol_id == IKEV2_PROTOCOL_ESP) ? 4 : 0;
188 47 : pr_data = vec_new (u8, sizeof (ike_sa_proposal_data_t) + spi_size);
189 47 : prop = (ike_sa_proposal_data_t *) pr_data;
190 47 : prop->last_or_more = proposals - p + 1 < vec_len (proposals) ? 2 : 0;
191 47 : prop->protocol_id = p->protocol_id;
192 47 : prop->proposal_num = p->proposal_num;
193 47 : prop->spi_size = spi_size;
194 47 : prop->num_transforms = vec_len (p->transforms);
195 :
196 47 : if (spi_size)
197 28 : prop->spi[0] = clib_host_to_net_u32 (p->spi);
198 :
199 211 : vec_foreach (t, p->transforms)
200 : {
201 164 : vec_add2 (tr_data, tmp, sizeof (*tr) + vec_len (t->attrs));
202 164 : tr = (ike_sa_transform_data_t *) tmp;
203 164 : tr->last_or_more =
204 164 : ((t - p->transforms) + 1 < vec_len (p->transforms)) ? 3 : 0;
205 164 : tr->transform_type = t->type;
206 164 : tr->transform_id = clib_host_to_net_u16 (t->transform_id);
207 164 : tr->transform_len =
208 164 : clib_host_to_net_u16 (sizeof (*tr) + vec_len (t->attrs));
209 :
210 164 : if (vec_len (t->attrs) > 0)
211 47 : clib_memcpy_fast (tr->attributes, t->attrs, vec_len (t->attrs));
212 : }
213 :
214 47 : prop->proposal_len =
215 47 : clib_host_to_net_u16 (vec_len (tr_data) + vec_len (pr_data));
216 47 : ikev2_payload_add_data (c, pr_data);
217 47 : ikev2_payload_add_data (c, tr_data);
218 47 : vec_free (pr_data);
219 47 : vec_free (tr_data);
220 : }
221 47 : }
222 :
223 : void
224 22 : ikev2_payload_add_ke (ikev2_payload_chain_t * c, u16 dh_group, u8 * dh_data)
225 : {
226 : ike_ke_payload_header_t *ke;
227 22 : ke = (ike_ke_payload_header_t *) ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_KE,
228 : sizeof (*ke));
229 :
230 22 : ke->dh_group = clib_host_to_net_u16 (dh_group);
231 22 : ikev2_payload_add_data (c, dh_data);
232 22 : }
233 :
234 : void
235 28 : ikev2_payload_add_nonce (ikev2_payload_chain_t * c, u8 * nonce)
236 : {
237 28 : ikev2_payload_add_hdr (c, IKEV2_PAYLOAD_NONCE,
238 : sizeof (ike_payload_header_t));
239 28 : ikev2_payload_add_data (c, nonce);
240 28 : }
241 :
242 : void
243 24 : ikev2_payload_add_id (ikev2_payload_chain_t * c, ikev2_id_t * id, u8 type)
244 : {
245 : ike_id_payload_header_t *idp;
246 : idp =
247 24 : (ike_id_payload_header_t *) ikev2_payload_add_hdr (c, type,
248 : sizeof (*idp));
249 :
250 24 : idp->id_type = id->type;
251 24 : ikev2_payload_add_data (c, id->data);
252 24 : }
253 :
254 : void
255 6 : ikev2_payload_add_delete (ikev2_payload_chain_t * c, ikev2_delete_t * d)
256 : {
257 : ike_delete_payload_header_t *dp;
258 6 : u16 num_of_spi = vec_len (d);
259 : ikev2_delete_t *d2;
260 : dp =
261 6 : (ike_delete_payload_header_t *) ikev2_payload_add_hdr (c,
262 : IKEV2_PAYLOAD_DELETE,
263 : sizeof (*dp));
264 :
265 6 : if (d[0].protocol_id == IKEV2_PROTOCOL_IKE)
266 : {
267 6 : dp->protocol_id = 1;
268 : }
269 : else
270 : {
271 0 : dp->protocol_id = d[0].protocol_id;
272 0 : dp->spi_size = 4;
273 0 : dp->num_of_spi = clib_host_to_net_u16 (num_of_spi);
274 0 : vec_foreach (d2, d)
275 : {
276 0 : u8 *data = vec_new (u8, 4);
277 0 : u32 spi = clib_host_to_net_u32 (d2->spi);
278 0 : clib_memcpy (data, &spi, 4);
279 0 : ikev2_payload_add_data (c, data);
280 0 : vec_free (data);
281 : }
282 : }
283 6 : }
284 :
285 : void
286 19 : ikev2_payload_add_auth (ikev2_payload_chain_t * c, ikev2_auth_t * auth)
287 : {
288 : ike_auth_payload_header_t *ap;
289 : ap =
290 19 : (ike_auth_payload_header_t *) ikev2_payload_add_hdr (c,
291 : IKEV2_PAYLOAD_AUTH,
292 : sizeof (*ap));
293 :
294 19 : ap->auth_method = auth->method;
295 19 : ikev2_payload_add_data (c, auth->data);
296 19 : }
297 :
298 : static void
299 56 : ikev2_payload_add_ts_entry (u8 ** data, ikev2_ts_t * ts)
300 : {
301 : u8 * tmp;
302 : ikev2_ts_payload_entry_t *entry;
303 56 : int len = sizeof (*entry);
304 :
305 56 : if (ts->ts_type == TS_IPV4_ADDR_RANGE)
306 54 : len += sizeof (ikev2_ip4_addr_pair_t);
307 : else
308 2 : len += sizeof (ikev2_ip6_addr_pair_t);
309 :
310 56 : vec_add2 (data[0], tmp, len);
311 56 : entry = (ikev2_ts_payload_entry_t *) tmp;
312 56 : entry->ts_type = ts->ts_type;
313 56 : entry->protocol_id = ts->protocol_id;
314 56 : entry->selector_len = clib_host_to_net_u16 (len);
315 56 : entry->start_port = clib_host_to_net_u16 (ts->start_port);
316 56 : entry->end_port = clib_host_to_net_u16 (ts->end_port);
317 :
318 56 : if (ts->ts_type == TS_IPV4_ADDR_RANGE)
319 : {
320 54 : ikev2_ip4_addr_pair_t *pair = (ikev2_ip4_addr_pair_t*) entry->addr_pair;
321 54 : ip_address_copy_addr (&pair->start_addr, &ts->start_addr);
322 54 : ip_address_copy_addr (&pair->end_addr, &ts->end_addr);
323 : }
324 : else
325 : {
326 2 : ikev2_ip6_addr_pair_t *pair = (ikev2_ip6_addr_pair_t*) entry->addr_pair;
327 2 : ip_address_copy_addr (&pair->start_addr, &ts->start_addr);
328 2 : ip_address_copy_addr (&pair->end_addr, &ts->end_addr);
329 : }
330 56 : }
331 :
332 : void
333 56 : ikev2_payload_add_ts (ikev2_payload_chain_t * c, ikev2_ts_t * ts, u8 type)
334 : {
335 : ike_ts_payload_header_t *tsh;
336 : ikev2_ts_t *ts2;
337 56 : u8 *data = 0;
338 :
339 : tsh =
340 56 : (ike_ts_payload_header_t *) ikev2_payload_add_hdr (c, type,
341 : sizeof (*tsh));
342 56 : tsh->num_ts = vec_len (ts);
343 :
344 112 : vec_foreach (ts2, ts)
345 : {
346 56 : ASSERT (ts2->ts_type == TS_IPV4_ADDR_RANGE ||
347 : ts2->ts_type == TS_IPV6_ADDR_RANGE);
348 56 : ikev2_payload_add_ts_entry (&data, ts2);
349 : }
350 :
351 56 : ikev2_payload_add_data (c, data);
352 56 : vec_free (data);
353 56 : }
354 :
355 : void
356 51 : ikev2_payload_chain_add_padding (ikev2_payload_chain_t * c, int bs)
357 : {
358 : u8 *tmp __attribute__ ((unused));
359 51 : u8 pad_len = (vec_len (c->data) / bs + 1) * bs - vec_len (c->data);
360 51 : vec_add2 (c->data, tmp, pad_len);
361 51 : c->data[vec_len (c->data) - 1] = pad_len - 1;
362 51 : }
363 :
364 : ikev2_sa_proposal_t *
365 57 : ikev2_parse_sa_payload (ike_payload_header_t * ikep, u32 rlen)
366 : {
367 57 : ikev2_sa_proposal_t *v = 0;
368 : ikev2_sa_proposal_t *proposal;
369 : ikev2_sa_transform_t *transform;
370 :
371 57 : u32 plen = clib_net_to_host_u16 (ikep->length);
372 : ike_sa_proposal_data_t *sap;
373 57 : int proposal_ptr = 0;
374 :
375 57 : if (sizeof (*ikep) > rlen)
376 0 : return 0;
377 :
378 57 : rlen -= sizeof (*ikep);
379 : do
380 : {
381 57 : if (proposal_ptr + sizeof (*sap) > rlen)
382 0 : goto data_corrupted;
383 :
384 57 : sap = (ike_sa_proposal_data_t *) & ikep->payload[proposal_ptr];
385 : int i, transform_ptr;
386 :
387 : /* IKE proposal should not have SPI */
388 57 : if (sap->protocol_id == IKEV2_PROTOCOL_IKE && sap->spi_size != 0)
389 0 : goto data_corrupted;
390 :
391 : /* IKE proposal should not have SPI */
392 57 : if (sap->protocol_id == IKEV2_PROTOCOL_ESP && sap->spi_size != 4)
393 0 : goto data_corrupted;
394 :
395 57 : transform_ptr = proposal_ptr + sizeof (*sap) + sap->spi_size;
396 57 : if (transform_ptr > rlen)
397 4 : goto data_corrupted;
398 :
399 53 : vec_add2 (v, proposal, 1);
400 53 : proposal->proposal_num = sap->proposal_num;
401 53 : proposal->protocol_id = sap->protocol_id;
402 :
403 53 : if (sap->spi_size == 4)
404 : {
405 30 : proposal->spi = clib_net_to_host_u32 (sap->spi[0]);
406 : }
407 :
408 253 : for (i = 0; i < sap->num_transforms; i++)
409 : {
410 204 : ike_sa_transform_data_t *tr =
411 : (ike_sa_transform_data_t *) & ikep->payload[transform_ptr];
412 204 : if (transform_ptr + sizeof (*tr) > rlen)
413 0 : goto data_corrupted;
414 204 : u16 tlen = clib_net_to_host_u16 (tr->transform_len);
415 :
416 204 : if (tlen < sizeof (*tr))
417 0 : goto data_corrupted;
418 :
419 204 : vec_add2 (proposal->transforms, transform, 1);
420 :
421 204 : transform->type = tr->transform_type;
422 204 : transform->transform_id = clib_net_to_host_u16 (tr->transform_id);
423 204 : if (transform_ptr + tlen > rlen)
424 4 : goto data_corrupted;
425 200 : if (tlen > sizeof (*tr))
426 49 : vec_add (transform->attrs, tr->attributes, tlen - sizeof (*tr));
427 200 : transform_ptr += tlen;
428 : }
429 :
430 49 : proposal_ptr += clib_net_to_host_u16 (sap->proposal_len);
431 : }
432 49 : while (proposal_ptr < (plen - sizeof (*ikep)) && sap->last_or_more == 2);
433 :
434 : /* data validation */
435 49 : if (proposal_ptr != (plen - sizeof (*ikep)) || sap->last_or_more)
436 0 : goto data_corrupted;
437 :
438 49 : return v;
439 :
440 8 : data_corrupted:
441 8 : ikev2_elog_detail ("SA payload data corrupted");
442 8 : ikev2_sa_free_proposal_vector (&v);
443 8 : return 0;
444 : }
445 :
446 : ikev2_ts_t *
447 60 : ikev2_parse_ts_payload (ike_payload_header_t * ikep, u32 rlen)
448 : {
449 60 : ike_ts_payload_header_t *tsp = (ike_ts_payload_header_t *) ikep;
450 60 : ikev2_ts_t *r = 0, *ts;
451 : ikev2_ip4_addr_pair_t *pair4;
452 : ikev2_ip6_addr_pair_t *pair6;
453 60 : int p = 0, n_left;
454 : ikev2_ts_payload_entry_t *pe;
455 :
456 60 : if (sizeof (*tsp) > rlen)
457 0 : return 0;
458 :
459 60 : rlen -= sizeof (*tsp);
460 60 : n_left = tsp->num_ts;
461 :
462 120 : while (n_left && p + sizeof (*pe) < rlen)
463 : {
464 60 : pe = (ikev2_ts_payload_entry_t *) (((u8 *)tsp->ts) + p);
465 60 : p += sizeof (*pe);
466 :
467 60 : if (pe->ts_type != TS_IPV4_ADDR_RANGE &&
468 2 : pe->ts_type != TS_IPV6_ADDR_RANGE)
469 : {
470 0 : ikev2_elog_uint (IKEV2_LOG_ERROR,
471 : "unsupported TS type received (%u)", pe->ts_type);
472 0 : return 0;
473 : }
474 :
475 60 : vec_add2 (r, ts, 1);
476 60 : ts->ts_type = pe->ts_type;
477 60 : ts->protocol_id = pe->protocol_id;
478 60 : ts->start_port = pe->start_port;
479 60 : ts->end_port = pe->end_port;
480 :
481 60 : if (pe->ts_type == TS_IPV4_ADDR_RANGE)
482 : {
483 58 : pair4 = (ikev2_ip4_addr_pair_t*) pe->addr_pair;
484 58 : ip_address_set (&ts->start_addr, &pair4->start_addr, AF_IP4);
485 58 : ip_address_set (&ts->end_addr, &pair4->end_addr, AF_IP4);
486 58 : p += sizeof (*pair4);
487 : }
488 : else
489 : {
490 2 : pair6 = (ikev2_ip6_addr_pair_t*) pe->addr_pair;
491 2 : ip_address_set (&ts->start_addr, &pair6->start_addr, AF_IP6);
492 2 : ip_address_set (&ts->end_addr, &pair6->end_addr, AF_IP6);
493 2 : p += sizeof (*pair6);
494 : }
495 60 : n_left--;
496 : }
497 :
498 60 : if (n_left)
499 0 : return 0;
500 :
501 60 : return r;
502 : }
503 :
504 : ikev2_notify_t *
505 74 : ikev2_parse_notify_payload (ike_payload_header_t * ikep, u32 rlen)
506 : {
507 74 : ike_notify_payload_header_t *n = (ike_notify_payload_header_t *) ikep;
508 74 : u32 plen = clib_net_to_host_u16 (n->length);
509 74 : ikev2_notify_t *r = 0;
510 : u32 spi;
511 :
512 74 : if (sizeof (*n) > rlen)
513 0 : return 0;
514 :
515 74 : r = vec_new (ikev2_notify_t, 1);
516 74 : r->msg_type = clib_net_to_host_u16 (n->msg_type);
517 74 : r->protocol_id = n->protocol_id;
518 :
519 74 : if (n->spi_size == 4)
520 : {
521 11 : if (sizeof (spi) + sizeof (*n) > rlen)
522 0 : goto cleanup;
523 :
524 11 : clib_memcpy (&spi, n->payload, n->spi_size);
525 11 : r->spi = clib_net_to_host_u32 (spi);
526 : }
527 63 : else if (n->spi_size == 0)
528 : {
529 63 : r->spi = 0;
530 : }
531 : else
532 : {
533 0 : clib_warning ("invalid SPI Size %d", n->spi_size);
534 0 : goto cleanup;
535 : }
536 :
537 74 : if (plen > (sizeof (*n) + n->spi_size))
538 : {
539 36 : if (plen <= sizeof (*n) + n->spi_size)
540 0 : goto cleanup;
541 :
542 36 : u32 data_len = plen - sizeof (*n) - n->spi_size;
543 36 : vec_add (r->data, n->payload + n->spi_size, data_len);
544 : }
545 74 : return r;
546 :
547 0 : cleanup:
548 0 : vec_free (r);
549 0 : return 0;
550 : }
551 :
552 : void
553 0 : ikev2_parse_vendor_payload (ike_payload_header_t * ikep)
554 : {
555 0 : u32 plen = clib_net_to_host_u16 (ikep->length);
556 0 : ikev2_elog_uint (IKEV2_LOG_DEBUG, "vendor payload skipped, len %d", plen);
557 0 : }
558 :
559 : ikev2_delete_t *
560 12 : ikev2_parse_delete_payload (ike_payload_header_t * ikep, u32 rlen)
561 : {
562 12 : ike_delete_payload_header_t * d = (ike_delete_payload_header_t *) ikep;
563 12 : ikev2_delete_t *r = 0, *del;
564 : u16 i, num_of_spi;
565 :
566 12 : if (rlen < sizeof (*d))
567 0 : return 0;
568 :
569 12 : num_of_spi = clib_net_to_host_u16 (d->num_of_spi);
570 12 : if (d->protocol_id == IKEV2_PROTOCOL_IKE)
571 : {
572 12 : r = vec_new (ikev2_delete_t, 1);
573 12 : r->protocol_id = 1;
574 : }
575 : else
576 : {
577 0 : if (sizeof (*d) + num_of_spi * sizeof (u32) > rlen)
578 0 : return 0;
579 :
580 0 : for (i = 0; i < num_of_spi; i++)
581 : {
582 0 : vec_add2 (r, del, 1);
583 0 : del->protocol_id = d->protocol_id;
584 0 : del->spi = clib_net_to_host_u32 (d->spi[i]);
585 : }
586 : }
587 :
588 12 : return r;
589 : }
590 :
591 : u8 *
592 0 : ikev2_find_ike_notify_payload (ike_header_t * ike, u32 msg_type)
593 : {
594 0 : int p = 0;
595 : ike_notify_payload_header_t *n;
596 : ike_payload_header_t *ikep;
597 0 : u32 payload = ike->nextpayload;
598 :
599 0 : while (payload != IKEV2_PAYLOAD_NONE)
600 : {
601 0 : ikep = (ike_payload_header_t *) & ike->payload[p];
602 0 : if (payload == IKEV2_PAYLOAD_NOTIFY)
603 : {
604 0 : n = (ike_notify_payload_header_t *)ikep;
605 0 : if (n->msg_type == clib_net_to_host_u16 (msg_type))
606 0 : return n->payload;
607 : }
608 0 : u16 plen = clib_net_to_host_u16 (ikep->length);
609 0 : payload = ikep->nextpayload;
610 0 : p += plen;
611 : }
612 0 : return 0;
613 : }
614 :
615 : /*
616 : * fd.io coding-style-patch-verification: ON
617 : *
618 : * Local Variables:
619 : * eval: (c-set-style "gnu")
620 : * End:
621 : */
|