Annotation of embedaddon/libpdel/structs/type/structs_type_data.c, revision 1.1

1.1     ! misho       1: 
        !             2: /*
        !             3:  * Copyright (c) 2001-2002 Packet Design, LLC.
        !             4:  * All rights reserved.
        !             5:  * 
        !             6:  * Subject to the following obligations and disclaimer of warranty,
        !             7:  * use and redistribution of this software, in source or object code
        !             8:  * forms, with or without modifications are expressly permitted by
        !             9:  * Packet Design; provided, however, that:
        !            10:  * 
        !            11:  *    (i)  Any and all reproductions of the source or object code
        !            12:  *         must include the copyright notice above and the following
        !            13:  *         disclaimer of warranties; and
        !            14:  *    (ii) No rights are granted, in any manner or form, to use
        !            15:  *         Packet Design trademarks, including the mark "PACKET DESIGN"
        !            16:  *         on advertising, endorsements, or otherwise except as such
        !            17:  *         appears in the above copyright notice or in the software.
        !            18:  * 
        !            19:  * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
        !            20:  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
        !            21:  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
        !            22:  * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
        !            23:  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
        !            24:  * OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
        !            25:  * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
        !            26:  * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
        !            27:  * RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
        !            28:  * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
        !            29:  * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
        !            30:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
        !            31:  * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
        !            32:  * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
        !            33:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            34:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
        !            35:  * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
        !            36:  * THE POSSIBILITY OF SUCH DAMAGE.
        !            37:  *
        !            38:  * Author: Archie Cobbs <archie@freebsd.org>
        !            39:  */
        !            40: 
        !            41: #include <sys/types.h>
        !            42: #include <sys/socket.h>
        !            43: #include <netinet/in.h>
        !            44: #include <arpa/inet.h>
        !            45: #include <net/ethernet.h>
        !            46: 
        !            47: #include <stdlib.h>
        !            48: #include <stdio.h>
        !            49: #include <stdarg.h>
        !            50: #include <string.h>
        !            51: #include <limits.h>
        !            52: #include <assert.h>
        !            53: #include <ctype.h>
        !            54: #include <errno.h>
        !            55: #include <time.h>
        !            56: 
        !            57: #include "structs/structs.h"
        !            58: #include "structs/type/array.h"
        !            59: #include "structs/type/data.h"
        !            60: #include "io/filter.h"
        !            61: #include "io/base64.h"
        !            62: #include "util/typed_mem.h"
        !            63: 
        !            64: #define HEXVAL(c)      (isdigit(c) ? (c) - '0' : tolower(c) - 'a' + 10)
        !            65: 
        !            66: static const char hexchars[] = "0123456789abcdef";
        !            67: 
        !            68: /*********************************************************************
        !            69:                        BINARY DATA TYPE
        !            70: *********************************************************************/
        !            71: 
        !            72: int
        !            73: structs_data_copy(const struct structs_type *type, const void *from, void *to)
        !            74: {
        !            75:        const char *const mtype = type->args[1].v;
        !            76:        const struct structs_data *const fdata = from;
        !            77:        struct structs_data *const tdata = to;
        !            78:        u_char *copy;
        !            79: 
        !            80:        if (fdata->length == 0) {
        !            81:                memset(tdata, 0, sizeof(*tdata));
        !            82:                return (0);
        !            83:        }
        !            84:        if ((copy = MALLOC(mtype, fdata->length)) == NULL)
        !            85:                return (-1);
        !            86:        memcpy(copy, fdata->data, fdata->length);
        !            87:        tdata->data = copy;
        !            88:        tdata->length = fdata->length;
        !            89:        return (0);
        !            90: }
        !            91: 
        !            92: int
        !            93: structs_data_equal(const struct structs_type *type,
        !            94:        const void *v1, const void *v2)
        !            95: {
        !            96:        const struct structs_data *const d1 = v1;
        !            97:        const struct structs_data *const d2 = v2;
        !            98: 
        !            99:        return (d1->length == d2->length
        !           100:            && memcmp(d1->data, d2->data, d1->length) == 0);
        !           101: }
        !           102: 
        !           103: char *
        !           104: structs_data_ascify(const struct structs_type *type,
        !           105:        const char *mtype, const void *data)
        !           106: {
        !           107:        const char *const charmap = type->args[0].v;
        !           108:        const struct structs_data *const d = data;
        !           109:        struct filter *encoder;
        !           110:        char *edata;
        !           111:        int elen;
        !           112:        int i;
        !           113: 
        !           114:        /* Handle hex encoding */
        !           115:        if (charmap != NULL && *charmap == '\0') {
        !           116:                if ((edata = MALLOC(mtype, d->length * 2 + 1)) == NULL)
        !           117:                        return (NULL);
        !           118:                for (i = 0; i < d->length; i++) {
        !           119:                        edata[i * 2] = hexchars[(d->data[i] >> 4) & 0x0f];
        !           120:                        edata[i * 2 + 1] = hexchars[d->data[i] & 0x0f];
        !           121:                }
        !           122:                edata[i * 2] = '\0';
        !           123:                return (edata);
        !           124:        }
        !           125: 
        !           126:        /* Get encoding filter */
        !           127:        if ((encoder = b64_encoder_create(charmap)) == NULL)
        !           128:                return (NULL);
        !           129: 
        !           130:        /* Encode data */
        !           131:        elen = filter_process(encoder, d->data,
        !           132:            d->length, 1, (u_char **)&edata, mtype);
        !           133:        filter_destroy(&encoder);
        !           134:        if (elen == -1)
        !           135:                return (NULL);
        !           136: 
        !           137:        /* Return encoded data as a string */
        !           138:        edata[elen] = '\0';
        !           139:        return (edata);
        !           140: }
        !           141: 
        !           142: int
        !           143: structs_data_binify(const struct structs_type *type,
        !           144:        const char *ascii, void *data, char *ebuf, size_t emax)
        !           145: {
        !           146:        const char *const charmap = type->args[0].v;
        !           147:        const char *const mtype = type->args[1].v;
        !           148:        struct structs_data *const d = data;
        !           149:        struct filter *decoder;
        !           150:        u_char *bdata;
        !           151:        int blen;
        !           152:        int i;
        !           153: 
        !           154:        /* Handle hex encoding */
        !           155:        if (charmap != NULL && *charmap == '\0') {
        !           156:                if ((bdata = MALLOC(mtype, (strlen(ascii) + 1) / 2)) == NULL)
        !           157:                        return (-1);
        !           158:                for (blen = 0; *ascii != '\0'; blen++) {
        !           159:                        while (isspace(*ascii))
        !           160:                                ascii++;
        !           161:                        if (*ascii == '\0')
        !           162:                                break;
        !           163:                        bdata[blen] = 0;
        !           164:                        for (i = 4; i >= 0; i -= 4) {
        !           165:                                if (!isxdigit(*ascii)) {
        !           166:                                        strlcpy(ebuf, *ascii == '\0' ?
        !           167:                                            "odd length hex sequence" :
        !           168:                                            "non-hex character seen", emax);
        !           169:                                        FREE(mtype, bdata);
        !           170:                                        return (-1);
        !           171:                                }
        !           172:                                bdata[blen] |= HEXVAL(*ascii) << i;
        !           173:                                ascii++;
        !           174:                        }
        !           175:                }
        !           176:                goto done;
        !           177:        }
        !           178: 
        !           179:        /* Get decoding filter */
        !           180:        if ((decoder = b64_decoder_create(charmap, 1)) == NULL)
        !           181:                return (-1);
        !           182: 
        !           183:        /* Decode data */
        !           184:        blen = filter_process(decoder, ascii, strlen(ascii), 1, &bdata, mtype);
        !           185:        filter_destroy(&decoder);
        !           186:        if (blen == -1) {
        !           187:                strlcpy(ebuf, "invalid encoded binary data", emax);
        !           188:                return (-1);
        !           189:        }
        !           190: 
        !           191: done:
        !           192:        /* Fill in structure */
        !           193:        d->length = blen;
        !           194:        d->data = bdata;
        !           195:        return (0);
        !           196: }
        !           197: 
        !           198: void
        !           199: structs_data_free(const struct structs_type *type, void *data)
        !           200: {
        !           201:        const char *const mtype = type->args[1].v;
        !           202:        struct structs_data *const d = data;
        !           203: 
        !           204:        FREE(mtype, d->data);
        !           205:        memset(d, 0, sizeof(*d));
        !           206: }
        !           207: 
        !           208: int
        !           209: structs_data_encode(const struct structs_type *type, const char *mtype,
        !           210:        struct structs_data *code, const void *data)
        !           211: {
        !           212:        const struct structs_data *const d = data;
        !           213:        u_int32_t elength;
        !           214: 
        !           215:        if ((code->data = MALLOC(mtype, 4 + d->length)) == NULL)
        !           216:                return (-1);
        !           217:        elength = htonl(d->length);
        !           218:        memcpy(code->data, &elength, 4);
        !           219:        memcpy(code->data + 4, d->data, d->length);
        !           220:        code->length = 4 + d->length;
        !           221:        return (0);
        !           222: }
        !           223: 
        !           224: int
        !           225: structs_data_decode(const struct structs_type *type, const u_char *code,
        !           226:        size_t cmax, void *data, char *ebuf, size_t emax)
        !           227: {
        !           228:        const char *const mtype = type->args[1].v;
        !           229:        struct structs_data *const d = data;
        !           230:        u_int32_t elength;
        !           231: 
        !           232:        if (cmax < 4)
        !           233:                goto bogus;
        !           234:        memcpy(&elength, code, 4);
        !           235:        d->length = ntohl(elength);
        !           236:        if (cmax < d->length) {
        !           237: bogus:         strlcpy(ebuf, "encoded data is corrupted", emax);
        !           238:                errno = EINVAL;
        !           239:                return (-1);
        !           240:        }
        !           241:        if ((d->data = MALLOC(mtype, d->length)) == NULL)
        !           242:                return (-1);
        !           243:        memcpy(d->data, code + 4, d->length);
        !           244:        return (4 + d->length);
        !           245: }
        !           246: 
        !           247: const struct structs_type structs_type_data =
        !           248:        STRUCTS_DATA_TYPE(NULL, STRUCTS_DATA_MEMTYPE);
        !           249: 
        !           250: const struct structs_type structs_type_hexdata =
        !           251:        STRUCTS_DATA_TYPE("", STRUCTS_DATA_MEMTYPE);
        !           252: 
        !           253: /*********************************************************************
        !           254:                    FIXED LENGTH BINARY DATA TYPE
        !           255: *********************************************************************/
        !           256: 
        !           257: char *
        !           258: structs_fixeddata_ascify(const struct structs_type *type,
        !           259:        const char *mtype, const void *data)
        !           260: {
        !           261:        const u_char *bytes = data;
        !           262:        char *s;
        !           263:        int i;
        !           264: 
        !           265:        if ((s = MALLOC(mtype, type->size * 2 + 1)) == NULL)
        !           266:                return (NULL);
        !           267:        for (i = 0; i < type->size; i++) {
        !           268:                s[i * 2] = hexchars[(bytes[i] >> 4) & 0x0f];
        !           269:                s[i * 2 + 1] = hexchars[bytes[i] & 0x0f];
        !           270:        }
        !           271:        s[i * 2] = '\0';
        !           272:        return (s);
        !           273: }
        !           274: 
        !           275: int
        !           276: structs_fixeddata_binify(const struct structs_type *type,
        !           277:        const char *ascii, void *data, char *ebuf, size_t emax)
        !           278: {
        !           279:        u_char *bytes = data;
        !           280:        int i;
        !           281:        int j;
        !           282: 
        !           283:        for (i = 0; i < type->size; i++) {
        !           284:                bytes[i] = 0;
        !           285:                for (j = 4; j >= 0; j -= 4) {
        !           286:                        while (isspace(*ascii))
        !           287:                                ascii++;
        !           288:                        if (!isxdigit(*ascii)) {
        !           289:                                strlcpy(ebuf, *ascii == '\0' ?
        !           290:                                    "hex string is too short" :
        !           291:                                    "non-hex character seen", emax);
        !           292:                                goto fail;
        !           293:                        }
        !           294:                        bytes[i] |= HEXVAL(*ascii) << j;
        !           295:                        ascii++;
        !           296:                }
        !           297:        }
        !           298:        while (isspace(*ascii))
        !           299:                ascii++;
        !           300:        if (*ascii != '\0') {
        !           301:                strlcpy(ebuf, "hex string is too long", emax);
        !           302: fail:          errno = EINVAL;
        !           303:                return (-1);
        !           304:        }
        !           305:        return (0);
        !           306: }
        !           307: 
        !           308: int
        !           309: structs_fixeddata_encode(const struct structs_type *type, const char *mtype,
        !           310:        struct structs_data *code, const void *data)
        !           311: {
        !           312:        if ((code->data = MALLOC(mtype, type->size)) == NULL)
        !           313:                return (-1);
        !           314:        memcpy(code->data, data, type->size);
        !           315:        code->length = type->size;
        !           316:        return (0);
        !           317: }
        !           318: 
        !           319: int
        !           320: structs_fixeddata_decode(const struct structs_type *type, const u_char *code,
        !           321:        size_t cmax, void *data, char *ebuf, size_t emax)
        !           322: {
        !           323:        if (cmax < type->size) {
        !           324:                strlcpy(ebuf, "encoded data is truncated", emax);
        !           325:                errno = EINVAL;
        !           326:                return (-1);
        !           327:        }
        !           328:        memcpy(data, code, type->size);
        !           329:        return (type->size);
        !           330: }
        !           331: 

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