Annotation of embedaddon/mpd/src/l2tp_avp.c, revision 1.1.1.2
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.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,
1.1.1.2 ! misho 118: struct ppp_l2tp_avp **avpp, unsigned index)
1.1 misho 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: {
1.1.1.2 ! misho 202: unsigned i;
1.1 misho 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;
1.1.1.2 ! misho 220: unsigned i;
1.1 misho 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;
1.1.1.2 ! misho 242: unsigned i;
1.1 misho 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;
1.1.1.2 ! misho 269: int len = 0;
! 270: unsigned i;
1.1 misho 271:
272: /* Pack AVP's */
1.1.1.2 ! misho 273: for (i = 0; i < list->length; i++) {
1.1 misho 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;
1.1.1.2 ! misho 519: unsigned i;
1.1 misho 520:
1.1.1.2 ! misho 521: /* Macro to allocate one pointer structure. Malloc zeroes area. */
1.1 misho 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:
1.1.1.2 ! misho 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:
1.1 misho 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);
1.1.1.2 ! misho 572: AVP_STORE16(message->mesgtype, 0);
1.1 misho 573: break;
574: case AVP_RESULT_CODE:
575: AVP_ALLOC(errresultcode);
1.1.1.2 ! misho 576: AVP_STORE16(errresultcode->result, 0);
! 577: AVP_STORE16(errresultcode->error, 1);
! 578: AVP_MEMCPY_OFF(errresultcode->errmsg, 4);
1.1 misho 579: break;
580: case AVP_PROTOCOL_VERSION:
581: AVP_ALLOC(protocol);
1.1.1.2 ! misho 582: AVP_STORE8(protocol->version, 0);
! 583: AVP_STORE8(protocol->revision, 1);
1.1 misho 584: break;
585: case AVP_FRAMING_CAPABILITIES:
586: AVP_ALLOC(framingcap);
1.1.1.2 ! misho 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: }
1.1 misho 593: break;
594: case AVP_BEARER_CAPABILITIES:
595: AVP_ALLOC(bearercap);
1.1.1.2 ! misho 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: }
1.1 misho 602: break;
603: case AVP_TIE_BREAKER:
604: AVP_ALLOC(tiebreaker);
1.1.1.2 ! misho 605: if (avp->vlen >= 8)
! 606: memcpy(ptrs->tiebreaker->value,
! 607: (char *)avp->value, 8);
1.1 misho 608: break;
609: case AVP_FIRMWARE_REVISION:
610: AVP_ALLOC(firmware);
1.1.1.2 ! misho 611: AVP_STORE16(firmware->revision, 0);
1.1 misho 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);
1.1.1.2 ! misho 623: AVP_STORE16(tunnelid->id, 0);
1.1 misho 624: break;
625: case AVP_RECEIVE_WINDOW_SIZE:
626: AVP_ALLOC(winsize);
1.1.1.2 ! misho 627: AVP_STORE16(winsize->size, 0);
1.1 misho 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);
1.1.1.2 ! misho 636: AVP_STORE16(causecode->causecode, 0);
! 637: AVP_STORE8(causecode->causemsg, 3);
! 638: AVP_MEMCPY_OFF(causecode->message, 4);
1.1 misho 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);
1.1.1.2 ! misho 647: AVP_STORE16(sessionid->id, 0);
1.1 misho 648: break;
649: case AVP_CALL_SERIAL_NUMBER:
650: AVP_ALLOC(serialnum);
1.1.1.2 ! misho 651: AVP_STORE32(serialnum->serialnum);
1.1 misho 652: break;
653: case AVP_MINIMUM_BPS:
654: AVP_ALLOC(minbps);
1.1.1.2 ! misho 655: AVP_STORE32(minbps->minbps);
1.1 misho 656: break;
657: case AVP_MAXIMUM_BPS:
658: AVP_ALLOC(maxbps);
1.1.1.2 ! misho 659: AVP_STORE32(maxbps->maxbps);
1.1 misho 660: break;
661: case AVP_BEARER_TYPE:
662: AVP_ALLOC(bearer);
1.1.1.2 ! misho 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: }
1.1 misho 669: break;
670: case AVP_FRAMING_TYPE:
671: AVP_ALLOC(framing);
1.1.1.2 ! misho 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: }
1.1 misho 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);
1.1.1.2 ! misho 693: AVP_STORE32(txconnect->bps);
1.1 misho 694: break;
695: case AVP_PHYSICAL_CHANNEL_ID:
696: AVP_ALLOC(channelid);
1.1.1.2 ! misho 697: AVP_STORE32(channelid->channel);
1.1 misho 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);
1.1.1.2 ! misho 716: AVP_STORE16(proxyauth->type, 0);
1.1 misho 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);
1.1.1.2 ! misho 731: AVP_STORE16(proxyid->id, 0);
1.1 misho 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);
1.1.1.2 ! misho 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: }
1.1 misho 752: break;
753: case AVP_ACCM:
754: AVP_ALLOC(accm);
1.1.1.2 ! misho 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: }
1.1 misho 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);
1.1.1.2 ! misho 771: AVP_STORE32(rxconnect->bps);
1.1 misho 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, \
1.1.1.2 ! misho 844: struct ppp_l2tp_avp *avp, char *buf, size_t bmax) \
1.1 misho 845: { \
846: const struct ppp_l2tp_avp_list list \
847: = { 1, (struct ppp_l2tp_avp *)avp }; \
848: struct ppp_l2tp_avp_ptrs *ptrs; \
849: \
1.1.1.2 ! misho 850: (void)info; \
1.1 misho 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 { \
1.1.1.2 ! misho 865: u_int _i; \
1.1 misho 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>