File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / l2tp_avp.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:39:23 2021 UTC (4 years ago) by misho
Branches: mpd, MAIN
CVS tags: v5_9p16, v5_9, HEAD
mpd 5.9

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

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