]> git.ipfire.org Git - thirdparty/strongswan.git/blobdiff - src/libcharon/encoding/parser.c
Spelling fixes
[thirdparty/strongswan.git] / src / libcharon / encoding / parser.c
index 77923e74bd1a271c56fb285c7787a2950350af85..de66ad467748e25aca83759510f32e6bc5ffb8e9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
+ * HSR 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
  */
 
 #include <stdlib.h>
-#include <arpa/inet.h>
 #include <string.h>
 
 #include "parser.h"
 
 #include <library.h>
 #include <daemon.h>
-#include <utils/linked_list.h>
+#include <collections/linked_list.h>
 #include <encoding/payloads/encodings.h>
 #include <encoding/payloads/payload.h>
 #include <encoding/payloads/sa_payload.h>
@@ -33,7 +32,7 @@
 #include <encoding/payloads/nonce_payload.h>
 #include <encoding/payloads/id_payload.h>
 #include <encoding/payloads/notify_payload.h>
-#include <encoding/payloads/encryption_payload.h>
+#include <encoding/payloads/encrypted_payload.h>
 #include <encoding/payloads/auth_payload.h>
 #include <encoding/payloads/cert_payload.h>
 #include <encoding/payloads/certreq_payload.h>
@@ -59,25 +58,30 @@ struct private_parser_t {
         */
        parser_t public;
 
+       /**
+        * major IKE version
+        */
+       uint8_t major_version;
+
        /**
         * Current bit for reading in input data.
         */
-       u_int8_t bit_pos;
+       uint8_t bit_pos;
 
        /**
         * Current byte for reading in input data.
         */
-       u_int8_t *byte_pos;
+       uint8_t *byte_pos;
 
        /**
         * Input data to parse.
         */
-       u_int8_t *input;
+       uint8_t *input;
 
        /**
         * Roof of input, used for length-checking.
         */
-       u_int8_t *input_roof;
+       uint8_t *input_roof;
 
        /**
         * Set of encoding rules for this parsing session.
@@ -109,9 +113,9 @@ static bool bad_bitpos(private_parser_t *this, int number)
  * Parse a 4-Bit unsigned integer from the current parsing position.
  */
 static bool parse_uint4(private_parser_t *this, int rule_number,
-                                               u_int8_t *output_pos)
+                                               uint8_t *output_pos)
 {
-       if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
+       if (this->byte_pos + sizeof(uint8_t) > this->input_roof)
        {
                return short_input(this, rule_number);
        }
@@ -137,7 +141,7 @@ static bool parse_uint4(private_parser_t *this, int rule_number,
        }
        if (output_pos)
        {
-               DBG3(DBG_ENC, "   => %d", *output_pos);
+               DBG3(DBG_ENC, "   => %hhu", *output_pos);
        }
        return TRUE;
 }
@@ -146,9 +150,9 @@ static bool parse_uint4(private_parser_t *this, int rule_number,
  * Parse a 8-Bit unsigned integer from the current parsing position.
  */
 static bool parse_uint8(private_parser_t *this, int rule_number,
-                                               u_int8_t *output_pos)
+                                               uint8_t *output_pos)
 {
-       if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
+       if (this->byte_pos + sizeof(uint8_t) > this->input_roof)
        {
                return short_input(this, rule_number);
        }
@@ -159,7 +163,7 @@ static bool parse_uint8(private_parser_t *this, int rule_number,
        if (output_pos)
        {
                *output_pos = *(this->byte_pos);
-               DBG3(DBG_ENC, "   => %d", *output_pos);
+               DBG3(DBG_ENC, "   => %hhu", *output_pos);
        }
        this->byte_pos++;
        return TRUE;
@@ -169,9 +173,9 @@ static bool parse_uint8(private_parser_t *this, int rule_number,
  * Parse a 15-Bit unsigned integer from the current parsing position.
  */
 static bool parse_uint15(private_parser_t *this, int rule_number,
-                                                u_int16_t *output_pos)
+                                                uint16_t *output_pos)
 {
-       if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
+       if (this->byte_pos + sizeof(uint16_t) > this->input_roof)
        {
                return short_input(this, rule_number);
        }
@@ -181,11 +185,11 @@ static bool parse_uint15(private_parser_t *this, int rule_number,
        }
        if (output_pos)
        {
-               memcpy(output_pos, this->byte_pos, sizeof(u_int16_t));
+               memcpy(output_pos, this->byte_pos, sizeof(uint16_t));
                *output_pos = ntohs(*output_pos) & ~0x8000;
-               DBG3(DBG_ENC, "   => %d", *output_pos);
+               DBG3(DBG_ENC, "   => %hu", *output_pos);
        }
-       this->byte_pos += sizeof(u_int16_t);
+       this->byte_pos += sizeof(uint16_t);
        this->bit_pos = 0;
        return TRUE;
 }
@@ -194,9 +198,9 @@ static bool parse_uint15(private_parser_t *this, int rule_number,
  * Parse a 16-Bit unsigned integer from the current parsing position.
  */
 static bool parse_uint16(private_parser_t *this, int rule_number,
-                                                u_int16_t *output_pos)
+                                                uint16_t *output_pos)
 {
-       if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
+       if (this->byte_pos + sizeof(uint16_t) > this->input_roof)
        {
                return short_input(this, rule_number);
        }
@@ -206,20 +210,20 @@ static bool parse_uint16(private_parser_t *this, int rule_number,
        }
        if (output_pos)
        {
-               memcpy(output_pos, this->byte_pos, sizeof(u_int16_t));
+               memcpy(output_pos, this->byte_pos, sizeof(uint16_t));
                *output_pos = ntohs(*output_pos);
-               DBG3(DBG_ENC, "   => %d", *output_pos);
+               DBG3(DBG_ENC, "   => %hu", *output_pos);
        }
-       this->byte_pos += sizeof(u_int16_t);
+       this->byte_pos += sizeof(uint16_t);
        return TRUE;
 }
 /**
  * Parse a 32-Bit unsigned integer from the current parsing position.
  */
 static bool parse_uint32(private_parser_t *this, int rule_number,
-                                                u_int32_t *output_pos)
+                                                uint32_t *output_pos)
 {
-       if (this->byte_pos + sizeof(u_int32_t) > this->input_roof)
+       if (this->byte_pos + sizeof(uint32_t) > this->input_roof)
        {
                return short_input(this, rule_number);
        }
@@ -229,11 +233,11 @@ static bool parse_uint32(private_parser_t *this, int rule_number,
        }
        if (output_pos)
        {
-               memcpy(output_pos, this->byte_pos, sizeof(u_int32_t));
+               memcpy(output_pos, this->byte_pos, sizeof(uint32_t));
                *output_pos = ntohl(*output_pos);
-               DBG3(DBG_ENC, "   => %d", *output_pos);
+               DBG3(DBG_ENC, "   => %u", *output_pos);
        }
-       this->byte_pos += sizeof(u_int32_t);
+       this->byte_pos += sizeof(uint32_t);
        return TRUE;
 }
 
@@ -241,7 +245,7 @@ static bool parse_uint32(private_parser_t *this, int rule_number,
  * Parse a given amount of bytes and writes them to a specific location
  */
 static bool parse_bytes(private_parser_t *this, int rule_number,
-                                               u_int8_t *output_pos, int bytes)
+                                               uint8_t *output_pos, int bytes)
 {
        if (this->byte_pos + bytes > this->input_roof)
        {
@@ -254,7 +258,7 @@ static bool parse_bytes(private_parser_t *this, int rule_number,
        if (output_pos)
        {
                memcpy(output_pos, this->byte_pos, bytes);
-               DBG3(DBG_ENC, "   => %b", output_pos, bytes);
+               DBG3(DBG_ENC, "   %b", output_pos, bytes);
        }
        this->byte_pos += bytes;
        return TRUE;
@@ -266,13 +270,13 @@ static bool parse_bytes(private_parser_t *this, int rule_number,
 static bool parse_bit(private_parser_t *this, int rule_number,
                                          bool *output_pos)
 {
-       if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
+       if (this->byte_pos + sizeof(uint8_t) > this->input_roof)
        {
                return short_input(this, rule_number);
        }
        if (output_pos)
        {
-               u_int8_t mask;
+               uint8_t mask;
                mask = 0x01 << (7 - this->bit_pos);
                *output_pos = *this->byte_pos & mask;
 
@@ -308,7 +312,7 @@ static bool parse_list(private_parser_t *this, int rule_number,
        }
        while (length > 0)
        {
-               u_int8_t *pos_before = this->byte_pos;
+               uint8_t *pos_before = this->byte_pos;
                payload_t *payload;
 
                DBG2(DBG_ENC, "  %d bytes left, parsing recursively %N",
@@ -352,72 +356,52 @@ static bool parse_chunk(private_parser_t *this, int rule_number,
        {
                *output_pos = chunk_alloc(length);
                memcpy(output_pos->ptr, this->byte_pos, length);
-               DBG3(DBG_ENC, "   => %b", output_pos->ptr, length);
+               DBG3(DBG_ENC, "   %b", output_pos->ptr, length);
        }
        this->byte_pos += length;
        return TRUE;
 }
 
-/**
- * Map a encoding type to a encoded payload
- */
-static payload_type_t map_wrapped_payload(encoding_type_t type)
-{
-       switch (type)
-       {
-               case PROPOSALS:
-                       return PROPOSAL_SUBSTRUCTURE;
-               case PROPOSALS_V1:
-                       return PROPOSAL_SUBSTRUCTURE_V1;
-               case TRANSFORMS:
-                       return TRANSFORM_SUBSTRUCTURE;
-               case TRANSFORMS_V1:
-                       return TRANSFORM_SUBSTRUCTURE_V1;
-               case TRANSFORM_ATTRIBUTES:
-                       return TRANSFORM_ATTRIBUTE;
-               case TRANSFORM_ATTRIBUTES_V1:
-                       return TRANSFORM_ATTRIBUTE_V1;
-               case CONFIGURATION_ATTRIBUTES:
-                       return CONFIGURATION_ATTRIBUTE;
-               case TRAFFIC_SELECTORS:
-                       return TRAFFIC_SELECTOR_SUBSTRUCTURE;
-               default:
-                       return NO_PAYLOAD;
-       }
-}
-
 METHOD(parser_t, parse_payload, status_t,
        private_parser_t *this, payload_type_t payload_type, payload_t **payload)
 {
        payload_t *pld;
        void *output;
        int payload_length = 0, spi_size = 0, attribute_length = 0, header_length;
-       u_int16_t ts_type = 0;
+       uint16_t ts_type = 0;
        bool attribute_format = FALSE;
        int rule_number, rule_count;
        encoding_rule_t *rule;
 
        /* create instance of the payload to parse */
-       pld = payload_create(payload_type);
+       if (payload_is_known(payload_type, this->major_version))
+       {
+               pld = payload_create(payload_type);
+       }
+       else
+       {
+               pld = (payload_t*)unknown_payload_create(payload_type);
+       }
 
        DBG2(DBG_ENC, "parsing %N payload, %d bytes left",
                 payload_type_names, payload_type, this->input_roof - this->byte_pos);
 
        DBG3(DBG_ENC, "parsing payload from %b",
-                this->byte_pos, this->input_roof - this->byte_pos);
+                this->byte_pos, (u_int)(this->input_roof - this->byte_pos));
 
        /* base pointer for output, avoids casting in every rule */
        output = pld;
-
-       header_length = pld->get_header_length(pld);
-       /* parse the payload with its own rulse */
+       /* parse the payload with its own rules */
        rule_count = pld->get_encoding_rules(pld, &this->rules);
        for (rule_number = 0; rule_number < rule_count; rule_number++)
        {
+               /* update header length for each rule, as it is dynamic (SPIs) */
+               header_length = pld->get_header_length(pld);
+
                rule = &(this->rules[rule_number]);
                DBG2(DBG_ENC, "  parsing rule %d %N",
                         rule_number, encoding_type_names, rule->type);
-               switch (rule->type)
+               switch ((int)rule->type)
                {
                        case U_INT_4:
                        {
@@ -484,7 +468,7 @@ METHOD(parser_t, parse_payload, status_t,
                                        return PARSE_ERROR;
                                }
                                /* parsed u_int16 should be aligned */
-                               payload_length = *(u_int16_t*)(output + rule->offset);
+                               payload_length = *(uint16_t*)(output + rule->offset);
                                /* all payloads must have at least 4 bytes header */
                                if (payload_length < 4)
                                {
@@ -500,7 +484,7 @@ METHOD(parser_t, parse_payload, status_t,
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               spi_size = *(u_int8_t*)(output + rule->offset);
+                               spi_size = *(uint8_t*)(output + rule->offset);
                                break;
                        }
                        case SPI:
@@ -513,18 +497,19 @@ METHOD(parser_t, parse_payload, status_t,
                                }
                                break;
                        }
-                       /* lists */
-                       case PROPOSALS:
-                       case PROPOSALS_V1:
-                       case TRANSFORMS:
-                       case TRANSFORMS_V1:
-                       case TRANSFORM_ATTRIBUTES:
-                       case TRANSFORM_ATTRIBUTES_V1:
-                       case TRAFFIC_SELECTORS:
+                       case PAYLOAD_LIST + PLV2_PROPOSAL_SUBSTRUCTURE:
+                       case PAYLOAD_LIST + PLV1_PROPOSAL_SUBSTRUCTURE:
+                       case PAYLOAD_LIST + PLV2_TRANSFORM_SUBSTRUCTURE:
+                       case PAYLOAD_LIST + PLV1_TRANSFORM_SUBSTRUCTURE:
+                       case PAYLOAD_LIST + PLV2_TRANSFORM_ATTRIBUTE:
+                       case PAYLOAD_LIST + PLV1_TRANSFORM_ATTRIBUTE:
+                       case PAYLOAD_LIST + PLV2_CONFIGURATION_ATTRIBUTE:
+                       case PAYLOAD_LIST + PLV1_CONFIGURATION_ATTRIBUTE:
+                       case PAYLOAD_LIST + PLV2_TRAFFIC_SELECTOR_SUBSTRUCTURE:
                        {
                                if (payload_length < header_length ||
                                        !parse_list(this, rule_number, output + rule->offset,
-                                                               map_wrapped_payload(rule->type),
+                                                               rule->type - PAYLOAD_LIST,
                                                                payload_length - header_length))
                                {
                                        pld->destroy(pld);
@@ -532,22 +517,7 @@ METHOD(parser_t, parse_payload, status_t,
                                }
                                break;
                        }
-                       /* chunks */
-                       case NONCE_DATA:
-                       case HASH_DATA:
-                       case ID_DATA:
-                       case AUTH_DATA:
-                       case CERT_DATA:
-                       case CERTREQ_DATA:
-                       case EAP_DATA:
-                       case SPIS:
-                       case VID_DATA:
-                       case CONFIGURATION_ATTRIBUTE_VALUE:
-                       case KEY_EXCHANGE_DATA:
-                       case KEY_EXCHANGE_DATA_V1:
-                       case NOTIFICATION_DATA:
-                       case ENCRYPTED_DATA:
-                       case UNKNOWN_DATA:
+                       case CHUNK_DATA:
                        {
                                if (payload_length < header_length ||
                                        !parse_chunk(this, rule_number, output + rule->offset,
@@ -558,6 +528,16 @@ METHOD(parser_t, parse_payload, status_t,
                                }
                                break;
                        }
+                       case ENCRYPTED_DATA:
+                       {
+                               if (!parse_chunk(this, rule_number, output + rule->offset,
+                                                                this->input_roof - this->byte_pos))
+                               {
+                                       pld->destroy(pld);
+                                       return PARSE_ERROR;
+                               }
+                               break;
+                       }
                        case ATTRIBUTE_FORMAT:
                        {
                                if (!parse_bit(this, rule_number, output + rule->offset))
@@ -577,14 +557,14 @@ METHOD(parser_t, parse_payload, status_t,
                                }
                                break;
                        }
-                       case CONFIGURATION_ATTRIBUTE_LENGTH:
+                       case ATTRIBUTE_LENGTH:
                        {
                                if (!parse_uint16(this, rule_number, output + rule->offset))
                                {
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               attribute_length = *(u_int16_t*)(output + rule->offset);
+                               attribute_length = *(uint16_t*)(output + rule->offset);
                                break;
                        }
                        case ATTRIBUTE_LENGTH_OR_VALUE:
@@ -594,7 +574,7 @@ METHOD(parser_t, parse_payload, status_t,
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               attribute_length = *(u_int16_t*)(output + rule->offset);
+                               attribute_length = *(uint16_t*)(output + rule->offset);
                                break;
                        }
                        case ATTRIBUTE_VALUE:
@@ -615,7 +595,7 @@ METHOD(parser_t, parse_payload, status_t,
                                        pld->destroy(pld);
                                        return PARSE_ERROR;
                                }
-                               ts_type = *(u_int8_t*)(output + rule->offset);
+                               ts_type = *(uint8_t*)(output + rule->offset);
                                break;
                        }
                        case ADDRESS:
@@ -638,7 +618,7 @@ METHOD(parser_t, parse_payload, status_t,
                                return PARSE_ERROR;
                        }
                }
-               /* process next rulue */
+               /* process next rule */
                rule++;
        }
 
@@ -661,6 +641,12 @@ METHOD(parser_t, reset_context, void,
        this->bit_pos = 0;
 }
 
+METHOD(parser_t, set_major_version, void,
+       private_parser_t *this, uint8_t major_version)
+{
+       this->major_version = major_version;
+}
+
 METHOD(parser_t, destroy, void,
        private_parser_t *this)
 {
@@ -678,6 +664,7 @@ parser_t *parser_create(chunk_t data)
                .public = {
                        .parse_payload = _parse_payload,
                        .reset_context = _reset_context,
+                       .set_major_version = _set_major_version,
                        .get_remaining_byte_count = _get_remaining_byte_count,
                        .destroy = _destroy,
                },