Annotation of embedaddon/strongswan/src/libcharon/encoding/parser.c, revision 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>