LCOV - code coverage report
Current view: top level - plugins/ikev2 - ikev2_payload.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 219 271 80.8 %
Date: 2023-10-26 01:39:38 Functions: 17 19 89.5 %

          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           2 :         goto data_corrupted;
     398             : 
     399          55 :       vec_add2 (v, proposal, 1);
     400          55 :       proposal->proposal_num = sap->proposal_num;
     401          55 :       proposal->protocol_id = sap->protocol_id;
     402             : 
     403          55 :       if (sap->spi_size == 4)
     404             :         {
     405          30 :           proposal->spi = clib_net_to_host_u32 (sap->spi[0]);
     406             :         }
     407             : 
     408         255 :       for (i = 0; i < sap->num_transforms; i++)
     409             :         {
     410         206 :           ike_sa_transform_data_t *tr =
     411             :             (ike_sa_transform_data_t *) & ikep->payload[transform_ptr];
     412         206 :           if (transform_ptr + sizeof (*tr) > rlen)
     413           0 :             goto data_corrupted;
     414         206 :           u16 tlen = clib_net_to_host_u16 (tr->transform_len);
     415             : 
     416         206 :           if (tlen < sizeof (*tr))
     417           0 :             goto data_corrupted;
     418             : 
     419         206 :           vec_add2 (proposal->transforms, transform, 1);
     420             : 
     421         206 :           transform->type = tr->transform_type;
     422         206 :           transform->transform_id = clib_net_to_host_u16 (tr->transform_id);
     423         206 :           if (transform_ptr + tlen > rlen)
     424           6 :             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             :  */

Generated by: LCOV version 1.14