Annotation of embedaddon/libpdel/ppp/ppp_l2tp_avp.c, revision 1.1.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>