Annotation of embedaddon/libpdel/ppp/ppp_l2tp_avp.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 "ppp/ppp_defs.h"
        !            42: #include "ppp/ppp_fsm_option.h"
        !            43: #include "ppp/ppp_auth.h"
        !            44: #include "ppp/ppp_lcp.h"
        !            45: #include "ppp/ppp_l2tp_avp.h"
        !            46: #include "ppp/ppp_util.h"
        !            47: #include <openssl/md5.h>
        !            48: 
        !            49: /* Memory types */
        !            50: #define AVP_MTYPE      "ppp_l2tp_avp"
        !            51: #define AVP_LIST_MTYPE "ppp_l2tp_avp_list"
        !            52: #define AVP_PTRS_MTYPE "ppp_l2tp_avp_ptrs"
        !            53: 
        !            54: /***********************************************************************
        !            55:                        AVP STRUCTURE METHODS
        !            56: ***********************************************************************/
        !            57: 
        !            58: /*
        !            59:  * Create a new AVP structure.
        !            60:  */
        !            61: struct ppp_l2tp_avp *
        !            62: ppp_l2tp_avp_create(int mandatory, u_int16_t vendor,
        !            63:        u_int16_t type, const void *value, size_t vlen)
        !            64: {
        !            65:        struct ppp_l2tp_avp *avp;
        !            66: 
        !            67:        if ((avp = MALLOC(AVP_MTYPE, sizeof(*avp))) == NULL)
        !            68:                return (NULL);
        !            69:        memset(avp, 0, sizeof(*avp));
        !            70:        avp->mandatory = !!mandatory;
        !            71:        avp->vendor = vendor;
        !            72:        avp->type = type;
        !            73:        if (vlen > 0) {
        !            74:                if ((avp->value = MALLOC(AVP_MTYPE, vlen)) == NULL) {
        !            75:                        FREE(AVP_MTYPE, avp);
        !            76:                        return (NULL);
        !            77:                }
        !            78:                memcpy(avp->value, value, vlen);
        !            79:        }
        !            80:        avp->vlen = vlen;
        !            81:        return (avp);
        !            82: }
        !            83: 
        !            84: /*
        !            85:  * Copy an AVP struture.
        !            86:  */
        !            87: struct ppp_l2tp_avp *
        !            88: ppp_l2tp_avp_copy(const struct ppp_l2tp_avp *avp)
        !            89: {
        !            90:        return (ppp_l2tp_avp_create(avp->mandatory, avp->vendor,
        !            91:            avp->type, avp->value, avp->vlen));
        !            92: }
        !            93: 
        !            94: /*
        !            95:  * Destroy an AVP structure.
        !            96:  */
        !            97: void
        !            98: ppp_l2tp_avp_destroy(struct ppp_l2tp_avp **avpp)
        !            99: {
        !           100:        struct ppp_l2tp_avp *const avp = *avpp;
        !           101: 
        !           102:        if (avp == NULL)
        !           103:                return;
        !           104:        *avpp = NULL;
        !           105:        FREE(AVP_MTYPE, avp->value);
        !           106:        FREE(AVP_MTYPE, avp);
        !           107: }
        !           108: 
        !           109: /***********************************************************************
        !           110:                        AVP LIST METHODS
        !           111: ***********************************************************************/
        !           112: 
        !           113: /*
        !           114:  * Create a new AVP list.
        !           115:  */
        !           116: struct ppp_l2tp_avp_list *
        !           117: ppp_l2tp_avp_list_create(void)
        !           118: {
        !           119:        struct ppp_l2tp_avp_list *list;
        !           120: 
        !           121:        if ((list = MALLOC(AVP_LIST_MTYPE, sizeof(*list))) == NULL)
        !           122:                return (NULL);
        !           123:        memset(list, 0, sizeof(*list));
        !           124:        return (list);
        !           125: }
        !           126: 
        !           127: /*
        !           128:  * Insert an AVP into a list.
        !           129:  */
        !           130: int
        !           131: ppp_l2tp_avp_list_insert(struct ppp_l2tp_avp_list *list,
        !           132:        struct ppp_l2tp_avp **avpp, int index)
        !           133: {
        !           134:        struct ppp_l2tp_avp *const avp = *avpp;
        !           135:        void *mem;
        !           136: 
        !           137:        if (avp == NULL || index < 0 || index > list->length) {
        !           138:                errno = EINVAL;
        !           139:                return (-1);
        !           140:        }
        !           141:        if ((mem = REALLOC(AVP_LIST_MTYPE, list->avps,
        !           142:            (list->length + 1) * sizeof(*list->avps))) == NULL)
        !           143:                return (-1);
        !           144:        list->avps = mem;
        !           145:        memmove(list->avps + index + 1, list->avps + index,
        !           146:            (list->length++ - index) * sizeof(*list->avps));
        !           147:        list->avps[index] = *avp;
        !           148:        FREE(AVP_MTYPE, avp);
        !           149:        *avpp = NULL;
        !           150:        return (0);
        !           151: }
        !           152: 
        !           153: /*
        !           154:  * Create a new AVP and add it to the end of the given list.
        !           155:  */
        !           156: int
        !           157: ppp_l2tp_avp_list_append(struct ppp_l2tp_avp_list *list, int mandatory,
        !           158:        u_int16_t vendor, u_int16_t type, const void *value, size_t vlen)
        !           159: {
        !           160:        struct ppp_l2tp_avp *avp;
        !           161: 
        !           162:        if ((avp = ppp_l2tp_avp_create(mandatory,
        !           163:            vendor, type, value, vlen)) == NULL)
        !           164:                return (-1);
        !           165:        if (ppp_l2tp_avp_list_insert(list, &avp, list->length) == -1) {
        !           166:                ppp_l2tp_avp_destroy(&avp);
        !           167:                return (-1);
        !           168:        }
        !           169:        return (0);
        !           170: }
        !           171: 
        !           172: /*
        !           173:  * Extract an AVP from a list.
        !           174:  */
        !           175: struct ppp_l2tp_avp *
        !           176: ppp_l2tp_avp_list_extract(struct ppp_l2tp_avp_list *list, u_int index)
        !           177: {
        !           178:        struct ppp_l2tp_avp *elem;
        !           179:        struct ppp_l2tp_avp *avp;
        !           180: 
        !           181:        if (index < 0 || index >= list->length) {
        !           182:                errno = EINVAL;
        !           183:                return (NULL);
        !           184:        }
        !           185:        elem = &list->avps[index];
        !           186:        if ((avp = ppp_l2tp_avp_create(elem->mandatory, elem->vendor,
        !           187:            elem->type, elem->value, elem->vlen)) == NULL)
        !           188:                return (NULL);
        !           189:        memmove(list->avps + index, list->avps + index + 1,
        !           190:            (--list->length - index) * sizeof(*list->avps));
        !           191:        return (avp);
        !           192: }
        !           193: 
        !           194: /*
        !           195:  * Remove and destroy an AVP from a list.
        !           196:  */
        !           197: int
        !           198: ppp_l2tp_avp_list_remove(struct ppp_l2tp_avp_list *list, u_int index)
        !           199: {
        !           200:        if (index < 0 || index >= list->length) {
        !           201:                errno = EINVAL;
        !           202:                return (-1);
        !           203:        }
        !           204:        FREE(AVP_MTYPE, list->avps[index].value);
        !           205:        memmove(list->avps + index, list->avps + index + 1,
        !           206:            (--list->length - index) * sizeof(*list->avps));
        !           207:        return (0);
        !           208: }
        !           209: 
        !           210: /*
        !           211:  * Find an AVP in a list.
        !           212:  */
        !           213: int
        !           214: ppp_l2tp_avp_list_find(const struct ppp_l2tp_avp_list *list,
        !           215:        u_int16_t vendor, u_int16_t type)
        !           216: {
        !           217:        int i;
        !           218: 
        !           219:        for (i = 0; i < list->length; i++) {
        !           220:                const struct ppp_l2tp_avp *const avp = &list->avps[i];
        !           221: 
        !           222:                if (avp->vendor == vendor && avp->type == type)
        !           223:                        return (i);
        !           224:        }
        !           225:        return (-1);
        !           226: }
        !           227: 
        !           228: /*
        !           229:  * Copy an AVP list.
        !           230:  */
        !           231: struct ppp_l2tp_avp_list *
        !           232: ppp_l2tp_avp_list_copy(const struct ppp_l2tp_avp_list *orig)
        !           233: {
        !           234:        struct ppp_l2tp_avp_list *list;
        !           235:        int i;
        !           236: 
        !           237:        if ((list = ppp_l2tp_avp_list_create()) == NULL)
        !           238:                return (NULL);
        !           239:        for (i = 0; i < orig->length; i++) {
        !           240:                const struct ppp_l2tp_avp *const avp = &orig->avps[i];
        !           241: 
        !           242:                if (ppp_l2tp_avp_list_append(list, avp->mandatory,
        !           243:                    avp->vendor, avp->type, avp->value, avp->vlen) == -1) {
        !           244:                        ppp_l2tp_avp_list_destroy(&list);
        !           245:                        return (NULL);
        !           246:                }
        !           247:        }
        !           248:        return (list);
        !           249: }
        !           250: 
        !           251: /*
        !           252:  * Destroy an AVP list.
        !           253:  */
        !           254: void
        !           255: ppp_l2tp_avp_list_destroy(struct ppp_l2tp_avp_list **listp)
        !           256: {
        !           257:        struct ppp_l2tp_avp_list *const list = *listp;
        !           258:        int i;
        !           259: 
        !           260:        if (list == NULL)
        !           261:                return;
        !           262:        *listp = NULL;
        !           263:        for (i = 0; i < list->length; i++) {
        !           264:                const struct ppp_l2tp_avp *const avp = &list->avps[i];
        !           265: 
        !           266:                FREE(AVP_MTYPE, avp->value);
        !           267:        }
        !           268:        FREE(AVP_LIST_MTYPE, list->avps);
        !           269:        FREE(AVP_LIST_MTYPE, list);
        !           270: }
        !           271: 
        !           272: /*
        !           273:  * Encode a list of AVP's into a single buffer, preserving the order
        !           274:  * of the AVP's.  If a shared secret is supplied, and any of the AVP's
        !           275:  * are hidden, then any required random vector AVP's are created and
        !           276:  * inserted automatically.
        !           277:  */
        !           278: int
        !           279: ppp_l2tp_avp_pack(const struct ppp_l2tp_avp_info *info,
        !           280:        const struct ppp_l2tp_avp_list *list, const u_char *secret,
        !           281:        size_t slen, u_char *buf)
        !           282: {
        !           283:        int len;
        !           284:        int i;
        !           285: 
        !           286:        /* Pack AVP's */
        !           287:        for (len = i = 0; i < list->length; i++) {
        !           288:                const struct ppp_l2tp_avp *const avp = &list->avps[i];
        !           289:                const struct ppp_l2tp_avp_info *desc;
        !           290:                u_int16_t hdr[3];
        !           291:                int hide = 0;
        !           292:                int j;
        !           293: 
        !           294:                /* Find descriptor */
        !           295:                for (desc = info; desc->name != NULL
        !           296:                    && (desc->vendor != avp->vendor || desc->type != avp->type);
        !           297:                    desc++);
        !           298:                if (desc->name == NULL) {
        !           299:                        errno = EILSEQ;
        !           300:                        return (-1);
        !           301:                }
        !           302: 
        !           303:                /* Sanity check AVP */
        !           304:                if (avp->vlen < desc->min_length
        !           305:                    || avp->vlen > desc->max_length
        !           306:                    || avp->vlen > AVP_MAX_VLEN) {
        !           307:                        errno = EILSEQ;
        !           308:                        return (-1);
        !           309:                }
        !           310: 
        !           311:                /* Set header stuff for this AVP */
        !           312:                memset(&hdr, 0, sizeof(hdr));
        !           313:                if (avp->mandatory)
        !           314:                        hdr[0] |= AVP_MANDATORY;
        !           315:                if (secret != NULL && desc->hidden_ok) {
        !           316:                        hdr[0] |= AVP_HIDDEN;
        !           317:                        hide = 1;
        !           318:                }
        !           319:                hdr[0] |= (avp->vlen + 6);
        !           320:                hdr[1] = avp->vendor;
        !           321:                hdr[2] = avp->type;
        !           322:                for (j = 0; j < 3; j++)
        !           323:                        hdr[j] = htons(hdr[j]);
        !           324:                if (buf != NULL)
        !           325:                        memcpy(buf + len, &hdr, 6);
        !           326:                len += 6;
        !           327: 
        !           328:                /* Copy AVP value, optionally hiding it */
        !           329:                if (hide) {
        !           330:                        errno = EOPNOTSUPP;     /* XXX implement hiding */
        !           331:                        return (-1);
        !           332:                } else {
        !           333:                        if (buf != NULL)
        !           334:                                memcpy(buf + len, avp->value, avp->vlen);
        !           335:                        len += avp->vlen;
        !           336:                }
        !           337:        }
        !           338: 
        !           339:        /* Done */
        !           340:        return (len);
        !           341: }
        !           342: 
        !           343: /*
        !           344:  * Decode a packet into an array of unpacked AVP structures, preserving
        !           345:  * the order of the AVP's. Random vector AVP's are automatically removed.
        !           346:  */
        !           347: struct ppp_l2tp_avp_list *
        !           348: ppp_l2tp_avp_unpack(const struct ppp_l2tp_avp_info *info,
        !           349:        const u_char *data, size_t dlen, const u_char *secret, size_t slen)
        !           350: {
        !           351:        struct ppp_l2tp_avp_list *list;
        !           352:        const u_char *randvec = NULL;
        !           353:        u_int16_t hdr[3];
        !           354:        int randvec_len;
        !           355:        int i;
        !           356: 
        !           357:        /* Create list */
        !           358:        if ((list = ppp_l2tp_avp_list_create()) == NULL)
        !           359:                return (NULL);
        !           360: 
        !           361:        /* Unpack AVP's */
        !           362:        while (dlen > 0) {
        !           363:                const struct ppp_l2tp_avp_info *desc;
        !           364:                u_int16_t alen;
        !           365: 
        !           366:                /* Get header */
        !           367:                if (dlen < 6)
        !           368:                        goto bogus;
        !           369:                memcpy(&hdr, data, 6);
        !           370:                for (i = 0; i < 3; i++)
        !           371:                        hdr[i] = ntohs(hdr[i]);
        !           372:                alen = hdr[0] & AVP_LENGTH_MASK;
        !           373:                if (alen < 6 || alen > dlen)
        !           374:                        goto bogus;
        !           375: 
        !           376:                /* Check reserved bits */
        !           377:                if ((hdr[0] & AVP_RESERVED) != 0)
        !           378:                        goto unknown;
        !           379: 
        !           380:                /* Find descriptor for this AVP */
        !           381:                for (desc = info; desc->name != NULL
        !           382:                    && (desc->vendor != hdr[1] || desc->type != hdr[2]);
        !           383:                    desc++);
        !           384:                if (desc->name == NULL) {
        !           385: unknown:               if ((hdr[0] & AVP_MANDATORY) != 0) {
        !           386:                                errno = ENOSYS;
        !           387:                                goto fail;
        !           388:                        }
        !           389:                        goto skip;
        !           390:                }
        !           391: 
        !           392:                /* Remember random vector AVP's as we see them */
        !           393:                if (hdr[1] == htons(0) && hdr[2] == htons(AVP_RANDOM_VECTOR)) {
        !           394:                        randvec = data + 6;
        !           395:                        randvec_len = alen - 6;
        !           396:                        continue;
        !           397:                }
        !           398: 
        !           399:                /* Un-hide AVP if hidden */
        !           400:                if ((hdr[0] & AVP_HIDDEN) != 0) {
        !           401:                        if (randvec == NULL)
        !           402:                                goto bogus;
        !           403:                        if (secret == NULL) {
        !           404:                                errno = EAUTH;
        !           405:                                goto fail;
        !           406:                        }
        !           407:                        errno = EOPNOTSUPP;     /* XXX implement unhiding */
        !           408:                        goto fail;
        !           409:                } else if (ppp_l2tp_avp_list_append(list,
        !           410:                    (hdr[0] & AVP_MANDATORY) != 0, hdr[1], hdr[2],
        !           411:                    data + 6, alen - 6) == -1)
        !           412:                        goto fail;
        !           413: 
        !           414: skip:
        !           415:                /* Continue with next AVP */
        !           416:                data += alen;
        !           417:                dlen -= alen;
        !           418:        }
        !           419: 
        !           420:        /* Done */
        !           421:        return (list);
        !           422: 
        !           423: bogus:
        !           424:        /* Invalid data */
        !           425:        errno = EILSEQ;
        !           426: fail:
        !           427:        ppp_l2tp_avp_list_destroy(&list);
        !           428:        return (NULL);
        !           429: }
        !           430: 
        !           431: /***********************************************************************
        !           432:                        AVP POINTERS METHODS
        !           433: ***********************************************************************/
        !           434: 
        !           435: /*
        !           436:  * Create an AVP pointers structure from an AVP list.
        !           437:  */
        !           438: struct ppp_l2tp_avp_ptrs *
        !           439: ppp_l2tp_avp_list2ptrs(const struct ppp_l2tp_avp_list *list)
        !           440: {
        !           441:        struct ppp_l2tp_avp_ptrs *ptrs;
        !           442:        int i;
        !           443: 
        !           444:        /* Macro to allocate one pointer structure */
        !           445: #define AVP_ALLOC(field)                                               \
        !           446: do {                                                                   \
        !           447:        size_t _size = sizeof(*ptrs->field);                            \
        !           448:                                                                        \
        !           449:        if (_size < avp->vlen)                                          \
        !           450:                _size = avp->vlen;                                      \
        !           451:        _size += 16;                                                    \
        !           452:        FREE(AVP_PTRS_MTYPE, ptrs->field);                              \
        !           453:        if ((ptrs->field = MALLOC(AVP_PTRS_MTYPE, _size)) == NULL)      \
        !           454:                goto fail;                                              \
        !           455:        memset(ptrs->field, 0, _size);                                  \
        !           456: } while (0)
        !           457: 
        !           458:        /* Create new pointers structure */
        !           459:        if ((ptrs = MALLOC(AVP_PTRS_MTYPE, sizeof(*ptrs))) == NULL)
        !           460:                return (NULL);
        !           461:        memset(ptrs, 0, sizeof(*ptrs));
        !           462: 
        !           463:        /* Add recognized AVP's */
        !           464:        for (i = 0; i < list->length; i++) {
        !           465:                const struct ppp_l2tp_avp *const avp = &list->avps[i];
        !           466:                const u_char *const ptr8 = (u_char *)avp->value;
        !           467:                const u_int16_t *const ptr16 = (u_int16_t *)avp->value;
        !           468:                const u_int32_t *const ptr32 = (u_int32_t *)avp->value;
        !           469: 
        !           470:                if (avp->vendor != 0)
        !           471:                        continue;
        !           472:                switch (avp->type) {
        !           473:                case AVP_MESSAGE_TYPE:
        !           474:                        AVP_ALLOC(message);
        !           475:                        ptrs->message->mesgtype = ntohs(ptr16[0]);
        !           476:                        break;
        !           477:                case AVP_RESULT_CODE:
        !           478:                        AVP_ALLOC(errresultcode);
        !           479:                        ptrs->errresultcode->result = ntohs(ptr16[0]);
        !           480:                        if (avp->vlen > 2)
        !           481:                                ptrs->errresultcode->error = ntohs(ptr16[1]);
        !           482:                        if (avp->vlen > 4) {
        !           483:                                memcpy(ptrs->errresultcode->errmsg,
        !           484:                                    (char *)avp->value + 4, avp->vlen - 4);
        !           485:                        }
        !           486:                        break;
        !           487:                case AVP_PROTOCOL_VERSION:
        !           488:                        AVP_ALLOC(protocol);
        !           489:                        ptrs->protocol->version = ptr8[0];
        !           490:                        ptrs->protocol->revision = ptr8[1];
        !           491:                        break;
        !           492:                case AVP_FRAMING_CAPABILITIES:
        !           493:                        AVP_ALLOC(framingcap);
        !           494:                        ptrs->framingcap->sync =
        !           495:                            (ntohl(ptr32[0]) & L2TP_FRAMING_SYNC) != 0;
        !           496:                        ptrs->framingcap->async =
        !           497:                            (ntohl(ptr32[0]) & L2TP_FRAMING_ASYNC) != 0;
        !           498:                        break;
        !           499:                case AVP_BEARER_CAPABILITIES:
        !           500:                        AVP_ALLOC(bearercap);
        !           501:                        ptrs->bearercap->digital =
        !           502:                            (ntohl(ptr32[0]) & L2TP_BEARER_DIGITAL) != 0;
        !           503:                        ptrs->bearercap->analog =
        !           504:                            (ntohl(ptr32[0]) & L2TP_BEARER_ANALOG) != 0;
        !           505:                        break;
        !           506:                case AVP_TIE_BREAKER:
        !           507:                        AVP_ALLOC(tiebreaker);
        !           508:                        memcpy(ptrs->tiebreaker->value, avp->value, 8);
        !           509:                        break;
        !           510:                case AVP_FIRMWARE_REVISION:
        !           511:                        AVP_ALLOC(firmware);
        !           512:                        ptrs->firmware->revision = ntohs(ptr16[0]);
        !           513:                        break;
        !           514:                case AVP_HOST_NAME:
        !           515:                        AVP_ALLOC(hostname);
        !           516:                        memcpy(ptrs->hostname->hostname, avp->value, avp->vlen);
        !           517:                        break;
        !           518:                case AVP_VENDOR_NAME:
        !           519:                        AVP_ALLOC(vendor);
        !           520:                        memcpy(ptrs->vendor->vendorname, avp->value, avp->vlen);
        !           521:                        break;
        !           522:                case AVP_ASSIGNED_TUNNEL_ID:
        !           523:                        AVP_ALLOC(tunnelid);
        !           524:                        ptrs->tunnelid->id = ntohs(ptr16[0]);
        !           525:                        break;
        !           526:                case AVP_RECEIVE_WINDOW_SIZE:
        !           527:                        AVP_ALLOC(winsize);
        !           528:                        ptrs->winsize->size = ntohs(ptr16[0]);
        !           529:                        break;
        !           530:                case AVP_CHALLENGE:
        !           531:                        AVP_ALLOC(challenge);
        !           532:                        ptrs->challenge->length = avp->vlen;
        !           533:                        memcpy(ptrs->challenge->value, avp->value, avp->vlen);
        !           534:                        break;
        !           535:                case AVP_CAUSE_CODE:
        !           536:                        AVP_ALLOC(causecode);
        !           537:                        ptrs->causecode->causecode = ntohs(ptr16[0]);
        !           538:                        ptrs->causecode->causemsg = ptr8[3];
        !           539:                        memcpy(ptrs->causecode->message,
        !           540:                            (char *)avp->value + 3, avp->vlen - 3);
        !           541:                        break;
        !           542:                case AVP_CHALLENGE_RESPONSE:
        !           543:                        AVP_ALLOC(challengresp);
        !           544:                        memcpy(ptrs->challengresp->value,
        !           545:                            avp->value, avp->vlen);
        !           546:                        break;
        !           547:                case AVP_ASSIGNED_SESSION_ID:
        !           548:                        AVP_ALLOC(sessionid);
        !           549:                        ptrs->sessionid->id = ntohs(ptr16[0]);
        !           550:                        break;
        !           551:                case AVP_CALL_SERIAL_NUMBER:
        !           552:                        AVP_ALLOC(serialnum);
        !           553:                        ptrs->serialnum->serialnum = ntohl(ptr32[0]);
        !           554:                        break;
        !           555:                case AVP_MINIMUM_BPS:
        !           556:                        AVP_ALLOC(minbps);
        !           557:                        ptrs->minbps->minbps = ntohl(ptr32[0]);
        !           558:                        break;
        !           559:                case AVP_MAXIMUM_BPS:
        !           560:                        AVP_ALLOC(maxbps);
        !           561:                        ptrs->maxbps->maxbps = ntohl(ptr32[0]);
        !           562:                        break;
        !           563:                case AVP_BEARER_TYPE:
        !           564:                        AVP_ALLOC(bearer);
        !           565:                        ptrs->bearer->digital =
        !           566:                            (ntohl(ptr32[0]) & L2TP_BEARER_DIGITAL) != 0;
        !           567:                        ptrs->bearer->analog =
        !           568:                            (ntohl(ptr32[0]) & L2TP_BEARER_ANALOG) != 0;
        !           569:                        break;
        !           570:                case AVP_FRAMING_TYPE:
        !           571:                        AVP_ALLOC(framing);
        !           572:                        ptrs->framing->sync =
        !           573:                            (ntohl(ptr32[0]) & L2TP_FRAMING_SYNC) != 0;
        !           574:                        ptrs->framing->async =
        !           575:                            (ntohl(ptr32[0]) & L2TP_FRAMING_ASYNC) != 0;
        !           576:                        break;
        !           577:                case AVP_CALLED_NUMBER:
        !           578:                        AVP_ALLOC(callednum);
        !           579:                        memcpy(ptrs->callednum->number, avp->value, avp->vlen);
        !           580:                        break;
        !           581:                case AVP_CALLING_NUMBER:
        !           582:                        AVP_ALLOC(callingnum);
        !           583:                        memcpy(ptrs->callingnum->number, avp->value, avp->vlen);
        !           584:                        break;
        !           585:                case AVP_SUB_ADDRESS:
        !           586:                        AVP_ALLOC(subaddress);
        !           587:                        memcpy(ptrs->subaddress->number, avp->value, avp->vlen);
        !           588:                        break;
        !           589:                case AVP_TX_CONNECT_SPEED:
        !           590:                        AVP_ALLOC(txconnect);
        !           591:                        ptrs->txconnect->bps = ntohl(ptr32[0]);
        !           592:                        break;
        !           593:                case AVP_PHYSICAL_CHANNEL_ID:
        !           594:                        AVP_ALLOC(channelid);
        !           595:                        ptrs->channelid->channel = ntohl(ptr32[0]);
        !           596:                        break;
        !           597:                case AVP_INITIAL_RECV_CONFREQ:
        !           598:                        AVP_ALLOC(recvlcp);
        !           599:                        ptrs->recvlcp->length = avp->vlen;
        !           600:                        memcpy(ptrs->recvlcp->data, avp->value, avp->vlen);
        !           601:                        break;
        !           602:                case AVP_LAST_SENT_CONFREQ:
        !           603:                        AVP_ALLOC(lastsendlcp);
        !           604:                        ptrs->lastsendlcp->length = avp->vlen;
        !           605:                        memcpy(ptrs->lastsendlcp->data, avp->value, avp->vlen);
        !           606:                        break;
        !           607:                case AVP_LAST_RECV_CONFREQ:
        !           608:                        AVP_ALLOC(lastrecvlcp);
        !           609:                        ptrs->lastrecvlcp->length = avp->vlen;
        !           610:                        memcpy(ptrs->lastrecvlcp->data, avp->value, avp->vlen);
        !           611:                        break;
        !           612:                case AVP_PROXY_AUTHEN_TYPE:
        !           613:                        AVP_ALLOC(proxyauth);
        !           614:                        ptrs->proxyauth->type = ntohs(ptr16[0]);
        !           615:                        break;
        !           616:                case AVP_PROXY_AUTHEN_NAME:
        !           617:                        AVP_ALLOC(proxyname);
        !           618:                        ptrs->proxyname->length = avp->vlen;
        !           619:                        memcpy(ptrs->proxyname->data, avp->value, avp->vlen);
        !           620:                        break;
        !           621:                case AVP_PROXY_AUTHEN_CHALLENGE:
        !           622:                        AVP_ALLOC(proxychallenge);
        !           623:                        ptrs->proxychallenge->length = avp->vlen;
        !           624:                        memcpy(ptrs->proxychallenge->data,
        !           625:                            avp->value, avp->vlen);
        !           626:                        break;
        !           627:                case AVP_PROXY_AUTHEN_ID:
        !           628:                        AVP_ALLOC(proxyid);
        !           629:                        ptrs->proxyid->id = ntohs(ptr16[0]);
        !           630:                        break;
        !           631:                case AVP_PROXY_AUTHEN_RESPONSE:
        !           632:                        AVP_ALLOC(proxyres);
        !           633:                        ptrs->proxyres->length = avp->vlen;
        !           634:                        memcpy(ptrs->proxyres->data, avp->value, avp->vlen);
        !           635:                        break;
        !           636:                case AVP_CALL_ERRORS:
        !           637:                    {
        !           638:                        u_int32_t vals[6];
        !           639: 
        !           640:                        memcpy(&vals, &ptr16[1], sizeof(vals));
        !           641:                        AVP_ALLOC(callerror);
        !           642:                        ptrs->callerror->crc = ntohl(vals[0]);
        !           643:                        ptrs->callerror->frame = ntohl(vals[1]);
        !           644:                        ptrs->callerror->overrun = ntohl(vals[2]);
        !           645:                        ptrs->callerror->buffer = ntohl(vals[3]);
        !           646:                        ptrs->callerror->timeout = ntohl(vals[4]);
        !           647:                        ptrs->callerror->alignment = ntohl(vals[5]);
        !           648:                        break;
        !           649:                    }
        !           650:                case AVP_ACCM:
        !           651:                    {
        !           652:                        u_int32_t vals[2];
        !           653: 
        !           654:                        memcpy(&vals, &ptr16[1], sizeof(vals));
        !           655:                        AVP_ALLOC(accm);
        !           656:                        ptrs->accm->xmit = ntohl(vals[0]);
        !           657:                        ptrs->accm->recv = ntohl(vals[1]);
        !           658:                        break;
        !           659:                    }
        !           660:                case AVP_PRIVATE_GROUP_ID:
        !           661:                        AVP_ALLOC(groupid);
        !           662:                        ptrs->groupid->length = avp->vlen;
        !           663:                        memcpy(ptrs->groupid->data, avp->value, avp->vlen);
        !           664:                        break;
        !           665:                case AVP_RX_CONNECT_SPEED:
        !           666:                        AVP_ALLOC(rxconnect);
        !           667:                        ptrs->rxconnect->bps = ntohl(ptr32[0]);
        !           668:                        break;
        !           669:                case AVP_SEQUENCING_REQUIRED:
        !           670:                        AVP_ALLOC(seqrequired);
        !           671:                        break;
        !           672:                default:
        !           673:                        break;
        !           674:                }
        !           675:        }
        !           676: 
        !           677:        /* Done */
        !           678:        return (ptrs);
        !           679: 
        !           680: fail:
        !           681:        /* Clean up after failure */
        !           682:        ppp_l2tp_avp_ptrs_destroy(&ptrs);
        !           683:        return (NULL);
        !           684: }
        !           685: 
        !           686: /*
        !           687:  * Destroy an AVP pointers structure.
        !           688:  */
        !           689: void
        !           690: ppp_l2tp_avp_ptrs_destroy(struct ppp_l2tp_avp_ptrs **ptrsp)
        !           691: {
        !           692:        struct ppp_l2tp_avp_ptrs *const ptrs = *ptrsp;
        !           693: 
        !           694:        if (ptrs == NULL)
        !           695:                return;
        !           696:        FREE(AVP_PTRS_MTYPE, ptrs->message);
        !           697:        FREE(AVP_PTRS_MTYPE, ptrs->errresultcode);
        !           698:        FREE(AVP_PTRS_MTYPE, ptrs->protocol);
        !           699:        FREE(AVP_PTRS_MTYPE, ptrs->framingcap);
        !           700:        FREE(AVP_PTRS_MTYPE, ptrs->bearercap);
        !           701:        FREE(AVP_PTRS_MTYPE, ptrs->tiebreaker);
        !           702:        FREE(AVP_PTRS_MTYPE, ptrs->firmware);
        !           703:        FREE(AVP_PTRS_MTYPE, ptrs->hostname);
        !           704:        FREE(AVP_PTRS_MTYPE, ptrs->vendor);
        !           705:        FREE(AVP_PTRS_MTYPE, ptrs->tunnelid);
        !           706:        FREE(AVP_PTRS_MTYPE, ptrs->sessionid);
        !           707:        FREE(AVP_PTRS_MTYPE, ptrs->winsize);
        !           708:        FREE(AVP_PTRS_MTYPE, ptrs->challenge);
        !           709:        FREE(AVP_PTRS_MTYPE, ptrs->challengresp);
        !           710:        FREE(AVP_PTRS_MTYPE, ptrs->causecode);
        !           711:        FREE(AVP_PTRS_MTYPE, ptrs->serialnum);
        !           712:        FREE(AVP_PTRS_MTYPE, ptrs->maxbps);
        !           713:        FREE(AVP_PTRS_MTYPE, ptrs->bearer);
        !           714:        FREE(AVP_PTRS_MTYPE, ptrs->framing);
        !           715:        FREE(AVP_PTRS_MTYPE, ptrs->callednum);
        !           716:        FREE(AVP_PTRS_MTYPE, ptrs->callingnum);
        !           717:        FREE(AVP_PTRS_MTYPE, ptrs->subaddress);
        !           718:        FREE(AVP_PTRS_MTYPE, ptrs->txconnect);
        !           719:        FREE(AVP_PTRS_MTYPE, ptrs->rxconnect);
        !           720:        FREE(AVP_PTRS_MTYPE, ptrs->channelid);
        !           721:        FREE(AVP_PTRS_MTYPE, ptrs->groupid);
        !           722:        FREE(AVP_PTRS_MTYPE, ptrs->recvlcp);
        !           723:        FREE(AVP_PTRS_MTYPE, ptrs->lastsendlcp);
        !           724:        FREE(AVP_PTRS_MTYPE, ptrs->lastrecvlcp);
        !           725:        FREE(AVP_PTRS_MTYPE, ptrs->proxyauth);
        !           726:        FREE(AVP_PTRS_MTYPE, ptrs->proxyname);
        !           727:        FREE(AVP_PTRS_MTYPE, ptrs->proxychallenge);
        !           728:        FREE(AVP_PTRS_MTYPE, ptrs->proxyid);
        !           729:        FREE(AVP_PTRS_MTYPE, ptrs->proxyres);
        !           730:        FREE(AVP_PTRS_MTYPE, ptrs->callerror);
        !           731:        FREE(AVP_PTRS_MTYPE, ptrs->accm);
        !           732:        FREE(AVP_PTRS_MTYPE, ptrs->seqrequired);
        !           733:        FREE(AVP_PTRS_MTYPE, ptrs);
        !           734:        *ptrsp = NULL;
        !           735: }
        !           736: 
        !           737: /***********************************************************************
        !           738:                        AVP DECODERS
        !           739: ***********************************************************************/
        !           740: 
        !           741: #define DECODE_INITIAL(t)                                              \
        !           742: void                                                                   \
        !           743: ppp_l2tp_avp_decode_ ## t(const struct ppp_l2tp_avp_info *info,                \
        !           744:        const struct ppp_l2tp_avp *avp, char *buf, size_t bmax)         \
        !           745: {                                                                      \
        !           746:        const struct ppp_l2tp_avp_list list                             \
        !           747:            = { 1, (struct ppp_l2tp_avp *)avp };                        \
        !           748:        struct ppp_l2tp_avp_ptrs *ptrs;                                 \
        !           749:                                                                        \
        !           750:        if ((ptrs = ppp_l2tp_avp_list2ptrs(&list)) == NULL) {           \
        !           751:                snprintf(buf, bmax,                                     \
        !           752:                    "decode failed: %s", strerror(errno));              \
        !           753:                goto done;                                              \
        !           754:        }                                                               \
        !           755:        strlcpy(buf, "", bmax);
        !           756: 
        !           757: #define DECODE_FINAL                                                   \
        !           758: done:                                                                  \
        !           759:        ppp_l2tp_avp_ptrs_destroy(&ptrs);                               \
        !           760: }
        !           761: 
        !           762: #define DECODE_BYTES(p, len)                                           \
        !           763:        do {                                                            \
        !           764:                int _i;                                                 \
        !           765:                                                                        \
        !           766:                for (_i = 0; _i < len; _i++) {                          \
        !           767:                        snprintf(buf + strlen(buf),                     \
        !           768:                            bmax - strlen(buf), "%02x",                 \
        !           769:                            ((u_char *)p)[_i]);                         \
        !           770:                }                                                       \
        !           771:        } while (0);
        !           772: 
        !           773: DECODE_INITIAL(MESSAGE_TYPE)
        !           774:        {
        !           775:                static const char *names[] = {
        !           776:                    "?0?", "SCCRQ", "SCCRP", "SCCCN", "StopCCN", "?5?",
        !           777:                    "HELLO", "OCRQ", "OCRP", "OCCN", "ICRQ", "ICRP",
        !           778:                    "ICCN", "?13?", "CDN", "WEN", "SLI",
        !           779:                };
        !           780: 
        !           781:                if (ptrs->message->mesgtype > sizeof(names) / sizeof(*names)) {
        !           782:                        snprintf(buf, bmax, "?%u?", ptrs->message->mesgtype);
        !           783:                        goto done;
        !           784:                }
        !           785:                strlcpy(buf, names[ptrs->message->mesgtype], bmax);
        !           786:        }
        !           787: DECODE_FINAL
        !           788: 
        !           789: DECODE_INITIAL(RESULT_CODE)
        !           790:        snprintf(buf, bmax, "result=%u error=%u errmsg=\"",
        !           791:            ptrs->errresultcode->result, ptrs->errresultcode->error);
        !           792:        ppp_util_ascify(buf + strlen(buf), bmax - strlen(buf),
        !           793:            ptrs->errresultcode->errmsg, strlen(ptrs->errresultcode->errmsg));
        !           794:        strlcat(buf, "\"", bmax);
        !           795: DECODE_FINAL
        !           796: 
        !           797: DECODE_INITIAL(PROTOCOL_VERSION)
        !           798:        snprintf(buf, bmax, "%u.%u",
        !           799:            ptrs->protocol->version, ptrs->protocol->revision);
        !           800: DECODE_FINAL
        !           801: 
        !           802: DECODE_INITIAL(FRAMING_CAPABILITIES)
        !           803:        snprintf(buf, bmax, "sync=%u async=%u",
        !           804:            ptrs->framingcap->sync, ptrs->framingcap->async);
        !           805: DECODE_FINAL
        !           806: 
        !           807: DECODE_INITIAL(BEARER_CAPABILITIES)
        !           808:        snprintf(buf, bmax, "digital=%u analog=%u",
        !           809:            ptrs->bearercap->digital, ptrs->bearercap->analog);
        !           810: DECODE_FINAL
        !           811: 
        !           812: DECODE_INITIAL(TIE_BREAKER)
        !           813:        snprintf(buf, bmax, "%02x%02x%02x%02x%02x%02x%02x%02x",
        !           814:            ((u_char *)ptrs->tiebreaker->value)[0],
        !           815:            ((u_char *)ptrs->tiebreaker->value)[1],
        !           816:            ((u_char *)ptrs->tiebreaker->value)[2],
        !           817:            ((u_char *)ptrs->tiebreaker->value)[3],
        !           818:            ((u_char *)ptrs->tiebreaker->value)[4],
        !           819:            ((u_char *)ptrs->tiebreaker->value)[5],
        !           820:            ((u_char *)ptrs->tiebreaker->value)[6],
        !           821:            ((u_char *)ptrs->tiebreaker->value)[7]);
        !           822: DECODE_FINAL
        !           823: 
        !           824: DECODE_INITIAL(FIRMWARE_REVISION)
        !           825:        snprintf(buf, bmax, "0x%04x", ptrs->firmware->revision);
        !           826: DECODE_FINAL
        !           827: 
        !           828: DECODE_INITIAL(HOST_NAME)
        !           829:        strlcpy(buf, "\"", bmax);
        !           830:        ppp_util_ascify(buf + strlen(buf), bmax - strlen(buf),
        !           831:            ptrs->hostname->hostname, strlen(ptrs->hostname->hostname));
        !           832:        strlcat(buf, "\"", bmax);
        !           833: DECODE_FINAL
        !           834: 
        !           835: DECODE_INITIAL(VENDOR_NAME)
        !           836:        strlcpy(buf, "\"", bmax);
        !           837:        ppp_util_ascify(buf + strlen(buf), bmax - strlen(buf),
        !           838:            ptrs->vendor->vendorname, strlen(ptrs->vendor->vendorname));
        !           839:        strlcat(buf, "\"", bmax);
        !           840: DECODE_FINAL
        !           841: 
        !           842: DECODE_INITIAL(ASSIGNED_TUNNEL_ID)
        !           843:        snprintf(buf, bmax, "0x%04x", ptrs->tunnelid->id);
        !           844: DECODE_FINAL
        !           845: 
        !           846: DECODE_INITIAL(RECEIVE_WINDOW_SIZE)
        !           847:        snprintf(buf, bmax, "%u", ptrs->winsize->size);
        !           848: DECODE_FINAL
        !           849: 
        !           850: DECODE_INITIAL(CHALLENGE)
        !           851: DECODE_BYTES(ptrs->challenge->value, ptrs->challenge->length)
        !           852: DECODE_FINAL
        !           853: 
        !           854: DECODE_INITIAL(CAUSE_CODE)
        !           855:        snprintf(buf, bmax, "causecode=0x%04x causemsg=0x%02x msg=\"",
        !           856:            ptrs->causecode->causecode, ptrs->causecode->causemsg);
        !           857:        ppp_util_ascify(buf + strlen(buf), bmax - strlen(buf),
        !           858:            ptrs->causecode->message, strlen(ptrs->causecode->message));
        !           859:        strlcat(buf, "\"", bmax);
        !           860: DECODE_FINAL
        !           861: 
        !           862: DECODE_INITIAL(CHALLENGE_RESPONSE)
        !           863: DECODE_BYTES(ptrs->challengresp->value, 16)
        !           864: DECODE_FINAL
        !           865: 
        !           866: DECODE_INITIAL(ASSIGNED_SESSION_ID)
        !           867:        snprintf(buf, bmax, "0x%04x", ptrs->sessionid->id);
        !           868: DECODE_FINAL
        !           869: 
        !           870: DECODE_INITIAL(CALL_SERIAL_NUMBER)
        !           871:        snprintf(buf, bmax, "%u", ptrs->serialnum->serialnum);
        !           872: DECODE_FINAL
        !           873: 
        !           874: DECODE_INITIAL(MINIMUM_BPS)
        !           875:        snprintf(buf, bmax, "%u", ptrs->minbps->minbps);
        !           876: DECODE_FINAL
        !           877: 
        !           878: DECODE_INITIAL(MAXIMUM_BPS)
        !           879:        snprintf(buf, bmax, "%u", ptrs->maxbps->maxbps);
        !           880: DECODE_FINAL
        !           881: 
        !           882: DECODE_INITIAL(BEARER_TYPE)
        !           883:        snprintf(buf, bmax, "digital=%u analog=%u",
        !           884:            ptrs->bearer->digital, ptrs->bearer->analog);
        !           885: DECODE_FINAL
        !           886: 
        !           887: DECODE_INITIAL(FRAMING_TYPE)
        !           888:        snprintf(buf, bmax, "sync=%u async=%u",
        !           889:            ptrs->framing->sync, ptrs->framing->async);
        !           890: DECODE_FINAL
        !           891: 
        !           892: DECODE_INITIAL(CALLED_NUMBER)
        !           893:        strlcpy(buf, "\"", bmax);
        !           894:        ppp_util_ascify(buf + strlen(buf), bmax - strlen(buf),
        !           895:            ptrs->callednum->number, strlen(ptrs->callednum->number));
        !           896:        strlcat(buf, "\"", bmax);
        !           897: DECODE_FINAL
        !           898: 
        !           899: DECODE_INITIAL(CALLING_NUMBER)
        !           900:        strlcpy(buf, "\"", bmax);
        !           901:        ppp_util_ascify(buf + strlen(buf), bmax - strlen(buf),
        !           902:            ptrs->callingnum->number, strlen(ptrs->callingnum->number));
        !           903:        strlcat(buf, "\"", bmax);
        !           904: DECODE_FINAL
        !           905: 
        !           906: DECODE_INITIAL(SUB_ADDRESS)
        !           907:        strlcpy(buf, "\"", bmax);
        !           908:        ppp_util_ascify(buf + strlen(buf), bmax - strlen(buf),
        !           909:            ptrs->subaddress->number, strlen(ptrs->subaddress->number));
        !           910:        strlcat(buf, "\"", bmax);
        !           911: DECODE_FINAL
        !           912: 
        !           913: DECODE_INITIAL(TX_CONNECT_SPEED)
        !           914:        snprintf(buf, bmax, "%u", ptrs->txconnect->bps);
        !           915: DECODE_FINAL
        !           916: 
        !           917: DECODE_INITIAL(PHYSICAL_CHANNEL_ID)
        !           918:        snprintf(buf, bmax, "0x%08x", ptrs->channelid->channel);
        !           919: DECODE_FINAL
        !           920: 
        !           921: DECODE_INITIAL(INITIAL_RECV_CONFREQ)
        !           922:        ppp_fsm_options_decode(lcp_opt_desc,
        !           923:            ptrs->recvlcp->data, ptrs->recvlcp->length, buf, bmax);
        !           924: DECODE_FINAL
        !           925: 
        !           926: DECODE_INITIAL(LAST_SENT_CONFREQ)
        !           927:        ppp_fsm_options_decode(lcp_opt_desc,
        !           928:            ptrs->lastsendlcp->data, ptrs->lastsendlcp->length, buf, bmax);
        !           929: DECODE_FINAL
        !           930: 
        !           931: DECODE_INITIAL(LAST_RECV_CONFREQ)
        !           932:        ppp_fsm_options_decode(lcp_opt_desc,
        !           933:            ptrs->lastrecvlcp->data, ptrs->lastrecvlcp->length, buf, bmax);
        !           934: DECODE_FINAL
        !           935: 
        !           936: DECODE_INITIAL(PROXY_AUTHEN_TYPE)
        !           937:        snprintf(buf, bmax, "%u", ptrs->proxyauth->type);
        !           938: DECODE_FINAL
        !           939: 
        !           940: DECODE_INITIAL(PROXY_AUTHEN_NAME)
        !           941:        strlcpy(buf, "\"", bmax);
        !           942:        ppp_util_ascify(buf + strlen(buf), bmax - strlen(buf),
        !           943:            ptrs->proxyname->data, strlen(ptrs->proxyname->data));
        !           944:        strlcat(buf, "\"", bmax);
        !           945: DECODE_FINAL
        !           946: 
        !           947: DECODE_INITIAL(PROXY_AUTHEN_CHALLENGE)
        !           948: DECODE_BYTES(ptrs->proxychallenge->data, ptrs->proxychallenge->length)
        !           949: DECODE_FINAL
        !           950: 
        !           951: DECODE_INITIAL(PROXY_AUTHEN_ID)
        !           952:        snprintf(buf, bmax, "%u", ptrs->proxyid->id);
        !           953: DECODE_FINAL
        !           954: 
        !           955: DECODE_INITIAL(PROXY_AUTHEN_RESPONSE)
        !           956: DECODE_BYTES(ptrs->proxyres->data, ptrs->proxyres->length)
        !           957: DECODE_FINAL
        !           958: 
        !           959: DECODE_INITIAL(CALL_ERRORS)
        !           960:        snprintf(buf, bmax, "crc=%u frame=%u overrun=%u"
        !           961:            "buffer=%u timeout=%u alignment=%u",
        !           962:            ptrs->callerror->crc, ptrs->callerror->frame,
        !           963:            ptrs->callerror->overrun, ptrs->callerror->buffer,
        !           964:            ptrs->callerror->timeout, ptrs->callerror->alignment);
        !           965: DECODE_FINAL
        !           966: 
        !           967: DECODE_INITIAL(ACCM)
        !           968:        snprintf(buf, bmax, "xmit=0x%08x recv=0x%08x",
        !           969:            ptrs->accm->xmit, ptrs->accm->recv);
        !           970: DECODE_FINAL
        !           971: 
        !           972: DECODE_INITIAL(RANDOM_VECTOR)
        !           973: DECODE_BYTES(avp->value, avp->vlen)
        !           974: DECODE_FINAL
        !           975: 
        !           976: DECODE_INITIAL(PRIVATE_GROUP_ID)
        !           977: DECODE_BYTES(ptrs->groupid->data, ptrs->groupid->length)
        !           978: DECODE_FINAL
        !           979: 
        !           980: DECODE_INITIAL(RX_CONNECT_SPEED)
        !           981:        snprintf(buf, bmax, "%u", ptrs->rxconnect->bps);
        !           982: DECODE_FINAL
        !           983: 
        !           984: DECODE_INITIAL(SEQUENCING_REQUIRED)
        !           985: DECODE_FINAL
        !           986: 
        !           987: 

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