Annotation of embedaddon/strongswan/src/libcharon/encoding/parser.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2005-2009 Martin Willi
                      3:  * Copyright (C) 2005 Jan Hutter
                      4:  * HSR Hochschule fuer Technik Rapperswil
                      5:  *
                      6:  * This program is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2 of the License, or (at your
                      9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     14:  * for more details.
                     15:  */
                     16: 
                     17: #include <stdlib.h>
                     18: #include <string.h>
                     19: 
                     20: #include "parser.h"
                     21: 
                     22: #include <library.h>
                     23: #include <daemon.h>
                     24: #include <collections/linked_list.h>
                     25: #include <encoding/payloads/encodings.h>
                     26: #include <encoding/payloads/payload.h>
                     27: #include <encoding/payloads/sa_payload.h>
                     28: #include <encoding/payloads/proposal_substructure.h>
                     29: #include <encoding/payloads/transform_substructure.h>
                     30: #include <encoding/payloads/transform_attribute.h>
                     31: #include <encoding/payloads/ke_payload.h>
                     32: #include <encoding/payloads/nonce_payload.h>
                     33: #include <encoding/payloads/id_payload.h>
                     34: #include <encoding/payloads/notify_payload.h>
                     35: #include <encoding/payloads/encrypted_payload.h>
                     36: #include <encoding/payloads/auth_payload.h>
                     37: #include <encoding/payloads/cert_payload.h>
                     38: #include <encoding/payloads/certreq_payload.h>
                     39: #include <encoding/payloads/ts_payload.h>
                     40: #include <encoding/payloads/delete_payload.h>
                     41: #include <encoding/payloads/vendor_id_payload.h>
                     42: #include <encoding/payloads/cp_payload.h>
                     43: #include <encoding/payloads/configuration_attribute.h>
                     44: #include <encoding/payloads/eap_payload.h>
                     45: #include <encoding/payloads/unknown_payload.h>
                     46: 
                     47: 
                     48: typedef struct private_parser_t private_parser_t;
                     49: 
                     50: /**
                     51:  * Private data stored in a context.
                     52:  *
                     53:  * Contains pointers and counters to store current state.
                     54:  */
                     55: struct private_parser_t {
                     56:        /**
                     57:         * Public members, see parser_t.
                     58:         */
                     59:        parser_t public;
                     60: 
                     61:        /**
                     62:         * major IKE version
                     63:         */
                     64:        uint8_t major_version;
                     65: 
                     66:        /**
                     67:         * Current bit for reading in input data.
                     68:         */
                     69:        uint8_t bit_pos;
                     70: 
                     71:        /**
                     72:         * Current byte for reading in input data.
                     73:         */
                     74:        uint8_t *byte_pos;
                     75: 
                     76:        /**
                     77:         * Input data to parse.
                     78:         */
                     79:        uint8_t *input;
                     80: 
                     81:        /**
                     82:         * Roof of input, used for length-checking.
                     83:         */
                     84:        uint8_t *input_roof;
                     85: 
                     86:        /**
                     87:         * Set of encoding rules for this parsing session.
                     88:         */
                     89:        encoding_rule_t *rules;
                     90: };
                     91: 
                     92: /**
                     93:  * Log invalid length error
                     94:  */
                     95: static bool short_input(private_parser_t *this, int number)
                     96: {
                     97:        DBG1(DBG_ENC, "  not enough input to parse rule %d %N",
                     98:                 number, encoding_type_names, this->rules[number].type);
                     99:        return FALSE;
                    100: }
                    101: 
                    102: /**
                    103:  * Log unaligned rules
                    104:  */
                    105: static bool bad_bitpos(private_parser_t *this, int number)
                    106: {
                    107:        DBG1(DBG_ENC, "  found rule %d %N on bitpos %d",
                    108:                 number, encoding_type_names, this->rules[number].type, this->bit_pos);
                    109:        return FALSE;
                    110: }
                    111: 
                    112: /**
                    113:  * Parse a 4-Bit unsigned integer from the current parsing position.
                    114:  */
                    115: static bool parse_uint4(private_parser_t *this, int rule_number,
                    116:                                                uint8_t *output_pos)
                    117: {
                    118:        if (this->byte_pos + sizeof(uint8_t) > this->input_roof)
                    119:        {
                    120:                return short_input(this, rule_number);
                    121:        }
                    122:        switch (this->bit_pos)
                    123:        {
                    124:                case 0:
                    125:                        if (output_pos)
                    126:                        {
                    127:                                *output_pos = *(this->byte_pos) >> 4;
                    128:                        }
                    129:                        this->bit_pos = 4;
                    130:                        break;
                    131:                case 4:
                    132:                        if (output_pos)
                    133:                        {
                    134:                                *output_pos = *(this->byte_pos) & 0x0F;
                    135:                        }
                    136:                        this->bit_pos = 0;
                    137:                        this->byte_pos++;
                    138:                        break;
                    139:                default:
                    140:                        return bad_bitpos(this, rule_number);
                    141:        }
                    142:        if (output_pos)
                    143:        {
                    144:                DBG3(DBG_ENC, "   => %hhu", *output_pos);
                    145:        }
                    146:        return TRUE;
                    147: }
                    148: 
                    149: /**
                    150:  * Parse a 8-Bit unsigned integer from the current parsing position.
                    151:  */
                    152: static bool parse_uint8(private_parser_t *this, int rule_number,
                    153:                                                uint8_t *output_pos)
                    154: {
                    155:        if (this->byte_pos + sizeof(uint8_t) > this->input_roof)
                    156:        {
                    157:                return short_input(this, rule_number);
                    158:        }
                    159:        if (this->bit_pos)
                    160:        {
                    161:                return bad_bitpos(this, rule_number);
                    162:        }
                    163:        if (output_pos)
                    164:        {
                    165:                *output_pos = *(this->byte_pos);
                    166:                DBG3(DBG_ENC, "   => %hhu", *output_pos);
                    167:        }
                    168:        this->byte_pos++;
                    169:        return TRUE;
                    170: }
                    171: 
                    172: /**
                    173:  * Parse a 15-Bit unsigned integer from the current parsing position.
                    174:  */
                    175: static bool parse_uint15(private_parser_t *this, int rule_number,
                    176:                                                 uint16_t *output_pos)
                    177: {
                    178:        if (this->byte_pos + sizeof(uint16_t) > this->input_roof)
                    179:        {
                    180:                return short_input(this, rule_number);
                    181:        }
                    182:        if (this->bit_pos != 1)
                    183:        {
                    184:                return bad_bitpos(this, rule_number);
                    185:        }
                    186:        if (output_pos)
                    187:        {
                    188:                memcpy(output_pos, this->byte_pos, sizeof(uint16_t));
                    189:                *output_pos = ntohs(*output_pos) & ~0x8000;
                    190:                DBG3(DBG_ENC, "   => %hu", *output_pos);
                    191:        }
                    192:        this->byte_pos += sizeof(uint16_t);
                    193:        this->bit_pos = 0;
                    194:        return TRUE;
                    195: }
                    196: 
                    197: /**
                    198:  * Parse a 16-Bit unsigned integer from the current parsing position.
                    199:  */
                    200: static bool parse_uint16(private_parser_t *this, int rule_number,
                    201:                                                 uint16_t *output_pos)
                    202: {
                    203:        if (this->byte_pos + sizeof(uint16_t) > this->input_roof)
                    204:        {
                    205:                return short_input(this, rule_number);
                    206:        }
                    207:        if (this->bit_pos)
                    208:        {
                    209:                return bad_bitpos(this, rule_number);
                    210:        }
                    211:        if (output_pos)
                    212:        {
                    213:                memcpy(output_pos, this->byte_pos, sizeof(uint16_t));
                    214:                *output_pos = ntohs(*output_pos);
                    215:                DBG3(DBG_ENC, "   => %hu", *output_pos);
                    216:        }
                    217:        this->byte_pos += sizeof(uint16_t);
                    218:        return TRUE;
                    219: }
                    220: /**
                    221:  * Parse a 32-Bit unsigned integer from the current parsing position.
                    222:  */
                    223: static bool parse_uint32(private_parser_t *this, int rule_number,
                    224:                                                 uint32_t *output_pos)
                    225: {
                    226:        if (this->byte_pos + sizeof(uint32_t) > this->input_roof)
                    227:        {
                    228:                return short_input(this, rule_number);
                    229:        }
                    230:        if (this->bit_pos)
                    231:        {
                    232:                return bad_bitpos(this, rule_number);
                    233:        }
                    234:        if (output_pos)
                    235:        {
                    236:                memcpy(output_pos, this->byte_pos, sizeof(uint32_t));
                    237:                *output_pos = ntohl(*output_pos);
                    238:                DBG3(DBG_ENC, "   => %u", *output_pos);
                    239:        }
                    240:        this->byte_pos += sizeof(uint32_t);
                    241:        return TRUE;
                    242: }
                    243: 
                    244: /**
                    245:  * Parse a given amount of bytes and writes them to a specific location
                    246:  */
                    247: static bool parse_bytes(private_parser_t *this, int rule_number,
                    248:                                                uint8_t *output_pos, int bytes)
                    249: {
                    250:        if (this->byte_pos + bytes > this->input_roof)
                    251:        {
                    252:                return short_input(this, rule_number);
                    253:        }
                    254:        if (this->bit_pos)
                    255:        {
                    256:                return bad_bitpos(this, rule_number);
                    257:        }
                    258:        if (output_pos)
                    259:        {
                    260:                memcpy(output_pos, this->byte_pos, bytes);
                    261:                DBG3(DBG_ENC, "   %b", output_pos, bytes);
                    262:        }
                    263:        this->byte_pos += bytes;
                    264:        return TRUE;
                    265: }
                    266: 
                    267: /**
                    268:  * Parse a single Bit from the current parsing position
                    269:  */
                    270: static bool parse_bit(private_parser_t *this, int rule_number,
                    271:                                          bool *output_pos)
                    272: {
                    273:        if (this->byte_pos + sizeof(uint8_t) > this->input_roof)
                    274:        {
                    275:                return short_input(this, rule_number);
                    276:        }
                    277:        if (output_pos)
                    278:        {
                    279:                uint8_t mask;
                    280:                mask = 0x01 << (7 - this->bit_pos);
                    281:                *output_pos = *this->byte_pos & mask;
                    282: 
                    283:                if (*output_pos)
                    284:                {       /* set to a "clean", comparable true */
                    285:                        *output_pos = TRUE;
                    286:                }
                    287:                DBG3(DBG_ENC, "   => %d", *output_pos);
                    288:        }
                    289:        this->bit_pos = (this->bit_pos + 1) % 8;
                    290:        if (this->bit_pos == 0)
                    291:        {
                    292:                this->byte_pos++;
                    293:        }
                    294:        return TRUE;
                    295: }
                    296: 
                    297: /**
                    298:  * Parse substructures in a list.
                    299:  */
                    300: static bool parse_list(private_parser_t *this, int rule_number,
                    301:                        linked_list_t **output_pos, payload_type_t payload_type, int length)
                    302: {
                    303:        linked_list_t *list = *output_pos;
                    304: 
                    305:        if (length < 0)
                    306:        {
                    307:                return short_input(this, rule_number);
                    308:        }
                    309:        if (this->bit_pos)
                    310:        {
                    311:                return bad_bitpos(this, rule_number);
                    312:        }
                    313:        while (length > 0)
                    314:        {
                    315:                uint8_t *pos_before = this->byte_pos;
                    316:                payload_t *payload;
                    317: 
                    318:                DBG2(DBG_ENC, "  %d bytes left, parsing recursively %N",
                    319:                         length, payload_type_names, payload_type);
                    320: 
                    321:                if (this->public.parse_payload(&this->public, payload_type,
                    322:                                                                           &payload) != SUCCESS)
                    323:                {
                    324:                        DBG1(DBG_ENC, "  parsing of a %N substructure failed",
                    325:                                 payload_type_names, payload_type);
                    326:                        return FALSE;
                    327:                }
                    328:                list->insert_last(list, payload);
                    329:                length -= this->byte_pos - pos_before;
                    330:        }
                    331:        if (length != 0)
                    332:        {       /* must yield exactly to zero */
                    333:                DBG1(DBG_ENC, "  length of %N substructure list invalid",
                    334:                         payload_type_names, payload_type);
                    335:                return FALSE;
                    336:        }
                    337:        *output_pos = list;
                    338:        return TRUE;
                    339: }
                    340: 
                    341: /**
                    342:  * Parse data from current parsing position in a chunk.
                    343:  */
                    344: static bool parse_chunk(private_parser_t *this, int rule_number,
                    345:                                                chunk_t *output_pos, int length)
                    346: {
                    347:        if (this->byte_pos + length > this->input_roof)
                    348:        {
                    349:                return short_input(this, rule_number);
                    350:        }
                    351:        if (this->bit_pos)
                    352:        {
                    353:                return bad_bitpos(this, rule_number);
                    354:        }
                    355:        if (output_pos)
                    356:        {
                    357:                *output_pos = chunk_alloc(length);
                    358:                memcpy(output_pos->ptr, this->byte_pos, length);
                    359:                DBG3(DBG_ENC, "   %b", output_pos->ptr, length);
                    360:        }
                    361:        this->byte_pos += length;
                    362:        return TRUE;
                    363: }
                    364: 
                    365: METHOD(parser_t, parse_payload, status_t,
                    366:        private_parser_t *this, payload_type_t payload_type, payload_t **payload)
                    367: {
                    368:        payload_t *pld;
                    369:        void *output;
                    370:        int payload_length = 0, spi_size = 0, attribute_length = 0, header_length;
                    371:        uint16_t ts_type = 0;
                    372:        bool attribute_format = FALSE;
                    373:        int rule_number, rule_count;
                    374:        encoding_rule_t *rule;
                    375: 
                    376:        /* create instance of the payload to parse */
                    377:        if (payload_is_known(payload_type, this->major_version))
                    378:        {
                    379:                pld = payload_create(payload_type);
                    380:        }
                    381:        else
                    382:        {
                    383:                pld = (payload_t*)unknown_payload_create(payload_type);
                    384:        }
                    385: 
                    386:        DBG2(DBG_ENC, "parsing %N payload, %d bytes left",
                    387:                 payload_type_names, payload_type, this->input_roof - this->byte_pos);
                    388: 
                    389:        DBG3(DBG_ENC, "parsing payload from %b",
                    390:                 this->byte_pos, (u_int)(this->input_roof - this->byte_pos));
                    391: 
                    392:        /* base pointer for output, avoids casting in every rule */
                    393:        output = pld;
                    394:        /* parse the payload with its own rules */
                    395:        rule_count = pld->get_encoding_rules(pld, &this->rules);
                    396:        for (rule_number = 0; rule_number < rule_count; rule_number++)
                    397:        {
                    398:                /* update header length for each rule, as it is dynamic (SPIs) */
                    399:                header_length = pld->get_header_length(pld);
                    400: 
                    401:                rule = &(this->rules[rule_number]);
                    402:                DBG2(DBG_ENC, "  parsing rule %d %N",
                    403:                         rule_number, encoding_type_names, rule->type);
                    404:                switch ((int)rule->type)
                    405:                {
                    406:                        case U_INT_4:
                    407:                        {
                    408:                                if (!parse_uint4(this, rule_number, output + rule->offset))
                    409:                                {
                    410:                                        pld->destroy(pld);
                    411:                                        return PARSE_ERROR;
                    412:                                }
                    413:                                break;
                    414:                        }
                    415:                        case U_INT_8:
                    416:                        case RESERVED_BYTE:
                    417:                        {
                    418:                                if (!parse_uint8(this, rule_number, output + rule->offset))
                    419:                                {
                    420:                                        pld->destroy(pld);
                    421:                                        return PARSE_ERROR;
                    422:                                }
                    423:                                break;
                    424:                        }
                    425:                        case U_INT_16:
                    426:                        {
                    427:                                if (!parse_uint16(this, rule_number, output + rule->offset))
                    428:                                {
                    429:                                        pld->destroy(pld);
                    430:                                        return PARSE_ERROR;
                    431:                                }
                    432:                                break;
                    433:                        }
                    434:                        case U_INT_32:
                    435:                        case HEADER_LENGTH:
                    436:                        {
                    437:                                if (!parse_uint32(this, rule_number, output + rule->offset))
                    438:                                {
                    439:                                        pld->destroy(pld);
                    440:                                        return PARSE_ERROR;
                    441:                                }
                    442:                                break;
                    443:                        }
                    444:                        case IKE_SPI:
                    445:                        {
                    446:                                if (!parse_bytes(this, rule_number, output + rule->offset, 8))
                    447:                                {
                    448:                                        pld->destroy(pld);
                    449:                                        return PARSE_ERROR;
                    450:                                }
                    451:                                break;
                    452:                        }
                    453:                        case RESERVED_BIT:
                    454:                        case FLAG:
                    455:                        {
                    456:                                if (!parse_bit(this, rule_number, output + rule->offset))
                    457:                                {
                    458:                                        pld->destroy(pld);
                    459:                                        return PARSE_ERROR;
                    460:                                }
                    461:                                break;
                    462:                        }
                    463:                        case PAYLOAD_LENGTH:
                    464:                        {
                    465:                                if (!parse_uint16(this, rule_number, output + rule->offset))
                    466:                                {
                    467:                                        pld->destroy(pld);
                    468:                                        return PARSE_ERROR;
                    469:                                }
                    470:                                /* parsed u_int16 should be aligned */
                    471:                                payload_length = *(uint16_t*)(output + rule->offset);
                    472:                                /* all payloads must have at least 4 bytes header */
                    473:                                if (payload_length < 4)
                    474:                                {
                    475:                                        pld->destroy(pld);
                    476:                                        return PARSE_ERROR;
                    477:                                }
                    478:                                break;
                    479:                        }
                    480:                        case SPI_SIZE:
                    481:                        {
                    482:                                if (!parse_uint8(this, rule_number, output + rule->offset))
                    483:                                {
                    484:                                        pld->destroy(pld);
                    485:                                        return PARSE_ERROR;
                    486:                                }
                    487:                                spi_size = *(uint8_t*)(output + rule->offset);
                    488:                                break;
                    489:                        }
                    490:                        case SPI:
                    491:                        {
                    492:                                if (!parse_chunk(this, rule_number, output + rule->offset,
                    493:                                                                 spi_size))
                    494:                                {
                    495:                                        pld->destroy(pld);
                    496:                                        return PARSE_ERROR;
                    497:                                }
                    498:                                break;
                    499:                        }
                    500:                        case PAYLOAD_LIST + PLV2_PROPOSAL_SUBSTRUCTURE:
                    501:                        case PAYLOAD_LIST + PLV1_PROPOSAL_SUBSTRUCTURE:
                    502:                        case PAYLOAD_LIST + PLV2_TRANSFORM_SUBSTRUCTURE:
                    503:                        case PAYLOAD_LIST + PLV1_TRANSFORM_SUBSTRUCTURE:
                    504:                        case PAYLOAD_LIST + PLV2_TRANSFORM_ATTRIBUTE:
                    505:                        case PAYLOAD_LIST + PLV1_TRANSFORM_ATTRIBUTE:
                    506:                        case PAYLOAD_LIST + PLV2_CONFIGURATION_ATTRIBUTE:
                    507:                        case PAYLOAD_LIST + PLV1_CONFIGURATION_ATTRIBUTE:
                    508:                        case PAYLOAD_LIST + PLV2_TRAFFIC_SELECTOR_SUBSTRUCTURE:
                    509:                        {
                    510:                                if (payload_length < header_length ||
                    511:                                        !parse_list(this, rule_number, output + rule->offset,
                    512:                                                                rule->type - PAYLOAD_LIST,
                    513:                                                                payload_length - header_length))
                    514:                                {
                    515:                                        pld->destroy(pld);
                    516:                                        return PARSE_ERROR;
                    517:                                }
                    518:                                break;
                    519:                        }
                    520:                        case CHUNK_DATA:
                    521:                        {
                    522:                                if (payload_length < header_length ||
                    523:                                        !parse_chunk(this, rule_number, output + rule->offset,
                    524:                                                                 payload_length - header_length))
                    525:                                {
                    526:                                        pld->destroy(pld);
                    527:                                        return PARSE_ERROR;
                    528:                                }
                    529:                                break;
                    530:                        }
                    531:                        case ENCRYPTED_DATA:
                    532:                        {
                    533:                                if (!parse_chunk(this, rule_number, output + rule->offset,
                    534:                                                                 this->input_roof - this->byte_pos))
                    535:                                {
                    536:                                        pld->destroy(pld);
                    537:                                        return PARSE_ERROR;
                    538:                                }
                    539:                                break;
                    540:                        }
                    541:                        case ATTRIBUTE_FORMAT:
                    542:                        {
                    543:                                if (!parse_bit(this, rule_number, output + rule->offset))
                    544:                                {
                    545:                                        pld->destroy(pld);
                    546:                                        return PARSE_ERROR;
                    547:                                }
                    548:                                attribute_format = *(bool*)(output + rule->offset);
                    549:                                break;
                    550:                        }
                    551:                        case ATTRIBUTE_TYPE:
                    552:                        {
                    553:                                if (!parse_uint15(this, rule_number, output + rule->offset))
                    554:                                {
                    555:                                        pld->destroy(pld);
                    556:                                        return PARSE_ERROR;
                    557:                                }
                    558:                                break;
                    559:                        }
                    560:                        case ATTRIBUTE_LENGTH:
                    561:                        {
                    562:                                if (!parse_uint16(this, rule_number, output + rule->offset))
                    563:                                {
                    564:                                        pld->destroy(pld);
                    565:                                        return PARSE_ERROR;
                    566:                                }
                    567:                                attribute_length = *(uint16_t*)(output + rule->offset);
                    568:                                break;
                    569:                        }
                    570:                        case ATTRIBUTE_LENGTH_OR_VALUE:
                    571:                        {
                    572:                                if (!parse_uint16(this, rule_number, output + rule->offset))
                    573:                                {
                    574:                                        pld->destroy(pld);
                    575:                                        return PARSE_ERROR;
                    576:                                }
                    577:                                attribute_length = *(uint16_t*)(output + rule->offset);
                    578:                                break;
                    579:                        }
                    580:                        case ATTRIBUTE_VALUE:
                    581:                        {
                    582:                                if (attribute_format == FALSE &&
                    583:                                        !parse_chunk(this, rule_number, output + rule->offset,
                    584:                                                                 attribute_length))
                    585:                                {
                    586:                                        pld->destroy(pld);
                    587:                                        return PARSE_ERROR;
                    588:                                }
                    589:                                break;
                    590:                        }
                    591:                        case TS_TYPE:
                    592:                        {
                    593:                                if (!parse_uint8(this, rule_number, output + rule->offset))
                    594:                                {
                    595:                                        pld->destroy(pld);
                    596:                                        return PARSE_ERROR;
                    597:                                }
                    598:                                ts_type = *(uint8_t*)(output + rule->offset);
                    599:                                break;
                    600:                        }
                    601:                        case ADDRESS:
                    602:                        {
                    603:                                int address_length = (ts_type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
                    604: 
                    605:                                if (!parse_chunk(this, rule_number, output + rule->offset,
                    606:                                                                 address_length))
                    607:                                {
                    608:                                        pld->destroy(pld);
                    609:                                        return PARSE_ERROR;
                    610:                                }
                    611:                                break;
                    612:                        }
                    613:                        default:
                    614:                        {
                    615:                                DBG1(DBG_ENC, "  no rule to parse rule %d %N",
                    616:                                         rule_number, encoding_type_names, rule->type);
                    617:                                pld->destroy(pld);
                    618:                                return PARSE_ERROR;
                    619:                        }
                    620:                }
                    621:                /* process next rule */
                    622:                rule++;
                    623:        }
                    624: 
                    625:        *payload = pld;
                    626:        DBG2(DBG_ENC, "parsing %N payload finished",
                    627:                 payload_type_names, payload_type);
                    628:        return SUCCESS;
                    629: }
                    630: 
                    631: METHOD(parser_t, get_remaining_byte_count, int,
                    632:        private_parser_t *this)
                    633: {
                    634:        return this->input_roof - this->byte_pos;
                    635: }
                    636: 
                    637: METHOD(parser_t, reset_context, void,
                    638:        private_parser_t *this)
                    639: {
                    640:        this->byte_pos = this->input;
                    641:        this->bit_pos = 0;
                    642: }
                    643: 
                    644: METHOD(parser_t, set_major_version, void,
                    645:        private_parser_t *this, uint8_t major_version)
                    646: {
                    647:        this->major_version = major_version;
                    648: }
                    649: 
                    650: METHOD(parser_t, destroy, void,
                    651:        private_parser_t *this)
                    652: {
                    653:        free(this);
                    654: }
                    655: 
                    656: /*
                    657:  * Described in header.
                    658:  */
                    659: parser_t *parser_create(chunk_t data)
                    660: {
                    661:        private_parser_t *this;
                    662: 
                    663:        INIT(this,
                    664:                .public = {
                    665:                        .parse_payload = _parse_payload,
                    666:                        .reset_context = _reset_context,
                    667:                        .set_major_version = _set_major_version,
                    668:                        .get_remaining_byte_count = _get_remaining_byte_count,
                    669:                        .destroy = _destroy,
                    670:                },
                    671:                .input = data.ptr,
                    672:                .byte_pos = data.ptr,
                    673:                .input_roof = data.ptr + data.len,
                    674:        );
                    675: 
                    676:        return &this->public;
                    677: }
                    678: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>