Annotation of embedaddon/strongswan/src/libcharon/encoding/generator.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2011 Tobias Brunner
        !             3:  * Copyright (C) 2005-2009 Martin Willi
        !             4:  * Copyright (C) 2005 Jan Hutter
        !             5:  * HSR Hochschule fuer Technik Rapperswil
        !             6:  *
        !             7:  * This program is free software; you can redistribute it and/or modify it
        !             8:  * under the terms of the GNU General Public License as published by the
        !             9:  * Free Software Foundation; either version 2 of the License, or (at your
        !            10:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !            11:  *
        !            12:  * This program is distributed in the hope that it will be useful, but
        !            13:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            14:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            15:  * for more details.
        !            16:  */
        !            17: 
        !            18: #include <stdlib.h>
        !            19: #include <string.h>
        !            20: #include <stdio.h>
        !            21: 
        !            22: #include "generator.h"
        !            23: 
        !            24: #include <library.h>
        !            25: #include <daemon.h>
        !            26: #include <collections/linked_list.h>
        !            27: #include <encoding/payloads/payload.h>
        !            28: #include <encoding/payloads/proposal_substructure.h>
        !            29: #include <encoding/payloads/transform_substructure.h>
        !            30: #include <encoding/payloads/sa_payload.h>
        !            31: #include <encoding/payloads/ke_payload.h>
        !            32: #include <encoding/payloads/notify_payload.h>
        !            33: #include <encoding/payloads/nonce_payload.h>
        !            34: #include <encoding/payloads/id_payload.h>
        !            35: #include <encoding/payloads/auth_payload.h>
        !            36: #include <encoding/payloads/cert_payload.h>
        !            37: #include <encoding/payloads/certreq_payload.h>
        !            38: #include <encoding/payloads/ts_payload.h>
        !            39: #include <encoding/payloads/delete_payload.h>
        !            40: #include <encoding/payloads/vendor_id_payload.h>
        !            41: #include <encoding/payloads/cp_payload.h>
        !            42: #include <encoding/payloads/configuration_attribute.h>
        !            43: #include <encoding/payloads/eap_payload.h>
        !            44: #include <encoding/payloads/unknown_payload.h>
        !            45: 
        !            46: /**
        !            47:  * Generating is done in a data buffer.
        !            48:  * This is the start size of this buffer in bytes.
        !            49:  */
        !            50: #define GENERATOR_DATA_BUFFER_SIZE 500
        !            51: 
        !            52: /**
        !            53:  * Number of bytes to increase the buffer, if it is too small.
        !            54:  */
        !            55: #define GENERATOR_DATA_BUFFER_INCREASE_VALUE 500
        !            56: 
        !            57: typedef struct private_generator_t private_generator_t;
        !            58: 
        !            59: /**
        !            60:  * Private part of a generator_t object.
        !            61:  */
        !            62: struct private_generator_t {
        !            63:        /**
        !            64:         * Public part of a generator_t object.
        !            65:         */
        !            66:         generator_t public;
        !            67: 
        !            68:        /**
        !            69:         * Buffer used to generate the data into.
        !            70:         */
        !            71:        uint8_t *buffer;
        !            72: 
        !            73:        /**
        !            74:         * Current write position in buffer (one byte aligned).
        !            75:         */
        !            76:        uint8_t *out_position;
        !            77: 
        !            78:        /**
        !            79:         * Position of last byte in buffer.
        !            80:         */
        !            81:        uint8_t *roof_position;
        !            82: 
        !            83:        /**
        !            84:         * Current bit writing to in current byte (between 0 and 7).
        !            85:         */
        !            86:        uint8_t current_bit;
        !            87: 
        !            88:        /**
        !            89:         * Associated data struct to read information from.
        !            90:         */
        !            91:        void *data_struct;
        !            92: 
        !            93:        /**
        !            94:         * Offset of the header length field in the buffer.
        !            95:         */
        !            96:        uint32_t header_length_offset;
        !            97: 
        !            98:        /**
        !            99:         * Attribute format of the last generated transform attribute.
        !           100:         *
        !           101:         * Used to check if a variable value field is used or not for
        !           102:         * the transform attribute value.
        !           103:         */
        !           104:        bool attribute_format;
        !           105: 
        !           106:        /**
        !           107:         * Depending on the value of attribute_format this field is used
        !           108:         * to hold the length of the transform attribute in bytes.
        !           109:         */
        !           110:        uint16_t attribute_length;
        !           111: 
        !           112:        /**
        !           113:         * TRUE, if debug messages should be logged during generation.
        !           114:         */
        !           115:        bool debug;
        !           116: };
        !           117: 
        !           118: /**
        !           119:  * Get size of current buffer in bytes.
        !           120:  */
        !           121: static int get_size(private_generator_t *this)
        !           122: {
        !           123:        return this->roof_position - this->buffer;
        !           124: }
        !           125: 
        !           126: /**
        !           127:  * Get free space of current buffer in bytes.
        !           128:  */
        !           129: static int get_space(private_generator_t *this)
        !           130: {
        !           131:        return this->roof_position - this->out_position;
        !           132: }
        !           133: 
        !           134: /**
        !           135:  * Get length of data in buffer (in bytes).
        !           136:  */
        !           137: static int get_length(private_generator_t *this)
        !           138: {
        !           139:        return this->out_position - this->buffer;
        !           140: }
        !           141: 
        !           142: /**
        !           143:  * Get current offset in buffer (in bytes).
        !           144:  */
        !           145: static uint32_t get_offset(private_generator_t *this)
        !           146: {
        !           147:        return this->out_position - this->buffer;
        !           148: }
        !           149: 
        !           150: /**
        !           151:  * Makes sure enough space is available in buffer to store amount of bits.
        !           152:  */
        !           153: static void make_space_available(private_generator_t *this, int bits)
        !           154: {
        !           155:        while ((get_space(this) * 8 - this->current_bit) < bits)
        !           156:        {
        !           157:                int old_buffer_size, new_buffer_size, out_position_offset;
        !           158: 
        !           159:                old_buffer_size = get_size(this);
        !           160:                new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE;
        !           161:                out_position_offset = this->out_position - this->buffer;
        !           162: 
        !           163:                if (this->debug)
        !           164:                {
        !           165:                        DBG2(DBG_ENC, "increasing gen buffer from %d to %d byte",
        !           166:                                 old_buffer_size, new_buffer_size);
        !           167:                }
        !           168: 
        !           169:                this->buffer = realloc(this->buffer,new_buffer_size);
        !           170:                this->out_position = (this->buffer + out_position_offset);
        !           171:                this->roof_position = (this->buffer + new_buffer_size);
        !           172:        }
        !           173: }
        !           174: 
        !           175: /**
        !           176:  * Writes a specific amount of byte into the buffer.
        !           177:  */
        !           178: static void write_bytes_to_buffer(private_generator_t *this, void *bytes,
        !           179:                                                                  int number_of_bytes)
        !           180: {
        !           181:        int i;
        !           182:        uint8_t *read_position = (uint8_t *)bytes;
        !           183: 
        !           184:        make_space_available(this, number_of_bytes * 8);
        !           185: 
        !           186:        for (i = 0; i < number_of_bytes; i++)
        !           187:        {
        !           188:                *(this->out_position) = *(read_position);
        !           189:                read_position++;
        !           190:                this->out_position++;
        !           191:        }
        !           192: }
        !           193: 
        !           194: /**
        !           195:  * Generates a U_INT-Field type and writes it to buffer.
        !           196:  */
        !           197: static void generate_u_int_type(private_generator_t *this,
        !           198:                                                                encoding_type_t int_type,uint32_t offset)
        !           199: {
        !           200:        int number_of_bits = 0;
        !           201: 
        !           202:        /* find out number of bits of each U_INT type to check for enough space */
        !           203:        switch (int_type)
        !           204:        {
        !           205:                case U_INT_4:
        !           206:                        number_of_bits = 4;
        !           207:                        break;
        !           208:                case TS_TYPE:
        !           209:                case RESERVED_BYTE:
        !           210:                case SPI_SIZE:
        !           211:                case U_INT_8:
        !           212:                        number_of_bits = 8;
        !           213:                        break;
        !           214:                case U_INT_16:
        !           215:                case PAYLOAD_LENGTH:
        !           216:                case ATTRIBUTE_LENGTH:
        !           217:                        number_of_bits = 16;
        !           218:                        break;
        !           219:                case U_INT_32:
        !           220:                        number_of_bits = 32;
        !           221:                        break;
        !           222:                case ATTRIBUTE_TYPE:
        !           223:                        number_of_bits = 15;
        !           224:                        break;
        !           225:                case IKE_SPI:
        !           226:                        number_of_bits = 64;
        !           227:                        break;
        !           228:                default:
        !           229:                        DBG1(DBG_ENC, "U_INT Type %N is not supported",
        !           230:                                 encoding_type_names, int_type);
        !           231:                        return;
        !           232:        }
        !           233:        if ((number_of_bits % 8) == 0 && this->current_bit != 0)
        !           234:        {
        !           235:                DBG1(DBG_ENC, "U_INT Type %N is not 8 Bit aligned",
        !           236:                         encoding_type_names, int_type);
        !           237:                return;
        !           238:        }
        !           239: 
        !           240:        make_space_available(this, number_of_bits);
        !           241:        switch (int_type)
        !           242:        {
        !           243:                case U_INT_4:
        !           244:                {
        !           245:                        uint8_t high, low;
        !           246: 
        !           247:                        if (this->current_bit == 0)
        !           248:                        {
        !           249:                                /* high of current byte in buffer has to be set to the new value*/
        !           250:                                high = *((uint8_t *)(this->data_struct + offset)) << 4;
        !           251:                                /* low in buffer is not changed */
        !           252:                                low = *(this->out_position) & 0x0F;
        !           253:                                /* high is set, low_val is not changed */
        !           254:                                *(this->out_position) = high | low;
        !           255:                                if (this->debug)
        !           256:                                {
        !           257:                                        DBG3(DBG_ENC, "   => %hhu", *(this->out_position) >> 4);
        !           258:                                }
        !           259:                                /* write position is not changed, just bit position is moved */
        !           260:                                this->current_bit = 4;
        !           261:                        }
        !           262:                        else if (this->current_bit == 4)
        !           263:                        {
        !           264:                                /* high in buffer is not changed */
        !           265:                                high = *(this->out_position) & 0xF0;
        !           266:                                /* low of current byte in buffer has to be set to the new value*/
        !           267:                                low = *((uint8_t *)(this->data_struct + offset)) & 0x0F;
        !           268:                                *(this->out_position) = high | low;
        !           269:                                if (this->debug)
        !           270:                                {
        !           271:                                        DBG3(DBG_ENC, "   => %hhu", *(this->out_position) & 0x0F);
        !           272:                                }
        !           273:                                this->out_position++;
        !           274:                                this->current_bit = 0;
        !           275:                        }
        !           276:                        else
        !           277:                        {
        !           278:                                DBG1(DBG_ENC, "U_INT_4 Type is not 4 Bit aligned");
        !           279:                                /* 4 Bit integers must have a 4 bit alignment */
        !           280:                                return;
        !           281:                        }
        !           282:                        break;
        !           283:                }
        !           284:                case TS_TYPE:
        !           285:                case RESERVED_BYTE:
        !           286:                case SPI_SIZE:
        !           287:                case U_INT_8:
        !           288:                {
        !           289:                        /* 8 bit values are written as they are */
        !           290:                        *this->out_position = *((uint8_t *)(this->data_struct + offset));
        !           291:                        if (this->debug)
        !           292:                        {
        !           293:                                DBG3(DBG_ENC, "   => %hhu", *(this->out_position));
        !           294:                        }
        !           295:                        this->out_position++;
        !           296:                        break;
        !           297:                }
        !           298:                case ATTRIBUTE_TYPE:
        !           299:                {
        !           300:                        uint8_t attribute_format_flag;
        !           301:                        uint16_t val;
        !           302: 
        !           303:                        /* attribute type must not change first bit of current byte */
        !           304:                        if (this->current_bit != 1)
        !           305:                        {
        !           306:                                DBG1(DBG_ENC, "ATTRIBUTE FORMAT flag is not set");
        !           307:                                return;
        !           308:                        }
        !           309:                        attribute_format_flag = *(this->out_position) & 0x80;
        !           310:                        /* get attribute type value as 16 bit integer*/
        !           311:                        val = *((uint16_t*)(this->data_struct + offset));
        !           312:                        /* unset most significant bit */
        !           313:                        val &= 0x7FFF;
        !           314:                        if (attribute_format_flag)
        !           315:                        {
        !           316:                                val |= 0x8000;
        !           317:                        }
        !           318:                        val = htons(val);
        !           319:                        if (this->debug)
        !           320:                        {
        !           321:                                DBG3(DBG_ENC, "   => %hu", val);
        !           322:                        }
        !           323:                        /* write bytes to buffer (set bit is overwritten) */
        !           324:                        write_bytes_to_buffer(this, &val, sizeof(uint16_t));
        !           325:                        this->current_bit = 0;
        !           326:                        break;
        !           327: 
        !           328:                }
        !           329:                case U_INT_16:
        !           330:                case PAYLOAD_LENGTH:
        !           331:                case ATTRIBUTE_LENGTH:
        !           332:                {
        !           333:                        uint16_t val = htons(*((uint16_t*)(this->data_struct + offset)));
        !           334:                        if (this->debug)
        !           335:                        {
        !           336:                                DBG3(DBG_ENC, "   %b", &val, sizeof(uint16_t));
        !           337:                        }
        !           338:                        write_bytes_to_buffer(this, &val, sizeof(uint16_t));
        !           339:                        break;
        !           340:                }
        !           341:                case U_INT_32:
        !           342:                {
        !           343:                        uint32_t val = htonl(*((uint32_t*)(this->data_struct + offset)));
        !           344:                        if (this->debug)
        !           345:                        {
        !           346:                                DBG3(DBG_ENC, "   %b", &val, sizeof(uint32_t));
        !           347:                        }
        !           348:                        write_bytes_to_buffer(this, &val, sizeof(uint32_t));
        !           349:                        break;
        !           350:                }
        !           351:                case IKE_SPI:
        !           352:                {
        !           353:                        /* 64 bit are written as-is, no host order conversion */
        !           354:                        write_bytes_to_buffer(this, this->data_struct + offset,
        !           355:                                                                  sizeof(uint64_t));
        !           356:                        if (this->debug)
        !           357:                        {
        !           358:                                DBG3(DBG_ENC, "   %b", this->data_struct + offset,
        !           359:                                         sizeof(uint64_t));
        !           360:                        }
        !           361:                        break;
        !           362:                }
        !           363:                default:
        !           364:                {
        !           365:                        DBG1(DBG_ENC, "U_INT Type %N is not supported",
        !           366:                                 encoding_type_names, int_type);
        !           367:                        return;
        !           368:                }
        !           369:        }
        !           370: }
        !           371: 
        !           372: /**
        !           373:  * Generate a FLAG filed
        !           374:  */
        !           375: static void generate_flag(private_generator_t *this, uint32_t offset)
        !           376: {
        !           377:        uint8_t flag_value;
        !           378:        uint8_t flag;
        !           379: 
        !           380:        flag_value = (*((bool *) (this->data_struct + offset))) ? 1 : 0;
        !           381:        /* get flag position */
        !           382:        flag = (flag_value << (7 - this->current_bit));
        !           383: 
        !           384:        /* make sure one bit is available in buffer */
        !           385:        make_space_available(this, 1);
        !           386:        if (this->current_bit == 0)
        !           387:        {
        !           388:                /* memory must be zero */
        !           389:                *(this->out_position) = 0x00;
        !           390:        }
        !           391: 
        !           392:        *(this->out_position) = *(this->out_position) | flag;
        !           393:        if (this->debug)
        !           394:        {
        !           395:                DBG3(DBG_ENC, "   => %hhu", *this->out_position);
        !           396:        }
        !           397: 
        !           398:        this->current_bit++;
        !           399:        if (this->current_bit >= 8)
        !           400:        {
        !           401:                this->current_bit = this->current_bit % 8;
        !           402:                this->out_position++;
        !           403:        }
        !           404: }
        !           405: 
        !           406: /**
        !           407:  * Generates a bytestream from a chunk_t.
        !           408:  */
        !           409: static void generate_from_chunk(private_generator_t *this, uint32_t offset)
        !           410: {
        !           411:        chunk_t *value;
        !           412: 
        !           413:        if (this->current_bit != 0)
        !           414:        {
        !           415:                DBG1(DBG_ENC, "can not generate a chunk at bitpos %hhu",
        !           416:                         this->current_bit);
        !           417:                return ;
        !           418:        }
        !           419: 
        !           420:        value = (chunk_t *)(this->data_struct + offset);
        !           421:        if (this->debug)
        !           422:        {
        !           423:                DBG3(DBG_ENC, "   %B", value);
        !           424:        }
        !           425: 
        !           426:        write_bytes_to_buffer(this, value->ptr, value->len);
        !           427: }
        !           428: 
        !           429: METHOD(generator_t, get_chunk, chunk_t,
        !           430:        private_generator_t *this, uint32_t **lenpos)
        !           431: {
        !           432:        chunk_t data;
        !           433: 
        !           434:        *lenpos = (uint32_t*)(this->buffer + this->header_length_offset);
        !           435:        data = chunk_create(this->buffer, get_length(this));
        !           436:        if (this->debug)
        !           437:        {
        !           438:                DBG3(DBG_ENC, "generated data of this generator %B", &data);
        !           439:        }
        !           440:        return data;
        !           441: }
        !           442: 
        !           443: METHOD(generator_t, generate_payload, void,
        !           444:        private_generator_t *this, payload_t *payload)
        !           445: {
        !           446:        int i, offset_start, rule_count;
        !           447:        encoding_rule_t *rules;
        !           448:        payload_type_t payload_type;
        !           449: 
        !           450:        this->data_struct = payload;
        !           451:        payload_type = payload->get_type(payload);
        !           452: 
        !           453:        offset_start = this->out_position - this->buffer;
        !           454: 
        !           455:        if (this->debug)
        !           456:        {
        !           457:                DBG2(DBG_ENC, "generating payload of type %N",
        !           458:                         payload_type_names, payload_type);
        !           459:        }
        !           460: 
        !           461:        /* each payload has its own encoding rules */
        !           462:        rule_count = payload->get_encoding_rules(payload, &rules);
        !           463: 
        !           464:        for (i = 0; i < rule_count;i++)
        !           465:        {
        !           466:                if (this->debug)
        !           467:                {
        !           468:                        DBG2(DBG_ENC, "  generating rule %d %N",
        !           469:                                 i, encoding_type_names, rules[i].type);
        !           470:                }
        !           471:                switch ((int)rules[i].type)
        !           472:                {
        !           473:                        case U_INT_4:
        !           474:                        case U_INT_8:
        !           475:                        case U_INT_16:
        !           476:                        case U_INT_32:
        !           477:                        case PAYLOAD_LENGTH:
        !           478:                        case IKE_SPI:
        !           479:                        case RESERVED_BYTE:
        !           480:                        case SPI_SIZE:
        !           481:                        case TS_TYPE:
        !           482:                        case ATTRIBUTE_TYPE:
        !           483:                        case ATTRIBUTE_LENGTH:
        !           484:                                generate_u_int_type(this, rules[i].type, rules[i].offset);
        !           485:                                break;
        !           486:                        case RESERVED_BIT:
        !           487:                        case FLAG:
        !           488:                                generate_flag(this, rules[i].offset);
        !           489:                                break;
        !           490:                        case HEADER_LENGTH:
        !           491:                                this->header_length_offset = get_offset(this);
        !           492:                                generate_u_int_type(this, U_INT_32, rules[i].offset);
        !           493:                                break;
        !           494:                        case ADDRESS:
        !           495:                        case SPI:
        !           496:                        case CHUNK_DATA:
        !           497:                        case ENCRYPTED_DATA:
        !           498:                                generate_from_chunk(this, rules[i].offset);
        !           499:                                break;
        !           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:                                linked_list_t *proposals;
        !           511:                                enumerator_t *enumerator;
        !           512:                                payload_t *proposal;
        !           513: 
        !           514:                                proposals = *((linked_list_t **)
        !           515:                                                                                (this->data_struct + rules[i].offset));
        !           516:                                enumerator = proposals->create_enumerator(proposals);
        !           517:                                while (enumerator->enumerate(enumerator, &proposal))
        !           518:                                {
        !           519:                                        generate_payload(this, proposal);
        !           520:                                }
        !           521:                                enumerator->destroy(enumerator);
        !           522:                                break;
        !           523:                        }
        !           524:                        case ATTRIBUTE_FORMAT:
        !           525:                                generate_flag(this, rules[i].offset);
        !           526:                                /* Attribute format is a flag which is stored in context*/
        !           527:                                this->attribute_format =
        !           528:                                                        *((bool *)(this->data_struct + rules[i].offset));
        !           529:                                break;
        !           530:                        case ATTRIBUTE_LENGTH_OR_VALUE:
        !           531:                                if (this->attribute_format)
        !           532:                                {
        !           533:                                        generate_u_int_type(this, U_INT_16, rules[i].offset);
        !           534:                                }
        !           535:                                else
        !           536:                                {
        !           537:                                        generate_u_int_type(this, U_INT_16, rules[i].offset);
        !           538:                                        /* this field hold the length of the attribute */
        !           539:                                        this->attribute_length =
        !           540:                                                *((uint16_t *)(this->data_struct + rules[i].offset));
        !           541:                                }
        !           542:                                break;
        !           543:                        case ATTRIBUTE_VALUE:
        !           544:                        {
        !           545:                                if (!this->attribute_format)
        !           546:                                {
        !           547:                                        if (this->debug)
        !           548:                                        {
        !           549:                                                DBG2(DBG_ENC, "attribute value has not fixed size");
        !           550:                                        }
        !           551:                                        /* the attribute value is generated */
        !           552:                                        generate_from_chunk(this, rules[i].offset);
        !           553:                                }
        !           554:                                break;
        !           555:                        }
        !           556:                        default:
        !           557:                                DBG1(DBG_ENC, "field type %N is not supported",
        !           558:                                         encoding_type_names, rules[i].type);
        !           559:                                return;
        !           560:                }
        !           561:        }
        !           562:        if (this->debug)
        !           563:        {
        !           564:                DBG2(DBG_ENC, "generating %N payload finished",
        !           565:                         payload_type_names, payload_type);
        !           566:                DBG3(DBG_ENC, "generated data for this payload %b",
        !           567:                         this->buffer + offset_start,
        !           568:                         (u_int)(this->out_position - this->buffer - offset_start));
        !           569:        }
        !           570: }
        !           571: 
        !           572: METHOD(generator_t, destroy, void,
        !           573:        private_generator_t *this)
        !           574: {
        !           575:        free(this->buffer);
        !           576:        free(this);
        !           577: }
        !           578: 
        !           579: /*
        !           580:  * Described in header
        !           581:  */
        !           582: generator_t *generator_create()
        !           583: {
        !           584:        private_generator_t *this;
        !           585: 
        !           586:        INIT(this,
        !           587:                .public = {
        !           588:                        .get_chunk = _get_chunk,
        !           589:                        .generate_payload = _generate_payload,
        !           590:                        .destroy = _destroy,
        !           591:                },
        !           592:                .buffer = malloc(GENERATOR_DATA_BUFFER_SIZE),
        !           593:                .debug = TRUE,
        !           594:        );
        !           595: 
        !           596:        this->out_position = this->buffer;
        !           597:        this->roof_position = this->buffer + GENERATOR_DATA_BUFFER_SIZE;
        !           598: 
        !           599:        return &this->public;
        !           600: }
        !           601: 
        !           602: /*
        !           603:  * Described in header
        !           604:  */
        !           605: generator_t *generator_create_no_dbg()
        !           606: {
        !           607:        private_generator_t *this = (private_generator_t*)generator_create();
        !           608: 
        !           609:        this->debug = FALSE;
        !           610: 
        !           611:        return &this->public;
        !           612: }

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