rp-l2tp patches from wl500g.googlecode.com project
[tomato.git] / release / src / router / rp-l2tp / dgram.c
blobf69b55cfe8153b7fd3d8c01d4d4a1b143c31d14b
1 /***********************************************************************
3 * dgram.c
5 * Routines for manipulating L2TP datagrams.
7 * Copyright (C) 2002 by Roaring Penguin Software Inc.
9 * This software may be distributed under the terms of the GNU General
10 * Public License, Version 2, or (at your option) any later version.
12 * LIC: GPL
14 ***********************************************************************/
16 static char const RCSID[] =
17 "$Id: dgram.c,v 1.1.48.1 2005/08/08 12:05:25 honor Exp $";
19 #include "l2tp.h"
20 #include "md5.h"
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <stdio.h>
27 #define PULL_UINT16(buf, cursor, val) \
28 do { \
29 val = ((uint16_t) buf[cursor]) * 256 + (uint16_t) buf[cursor+1]; \
30 cursor += 2; \
31 } while(0)
33 #define PUSH_UINT16(buf, cursor, val) \
34 do { \
35 buf[cursor] = val / 256; \
36 buf[cursor+1] = val & 0xFF; \
37 cursor += 2; \
38 } while (0)
40 #define GET_AVP_LEN(x) ((((x)[0] & 3) * 256) + (x)[1])
42 static int dgram_add_random_vector_avp(l2tp_dgram *dgram);
44 static void dgram_do_hide(uint16_t type,
45 uint16_t len,
46 unsigned char *value,
47 unsigned char const *secret,
48 size_t secret_len,
49 unsigned char const *random,
50 size_t random_len,
51 unsigned char *output);
53 static unsigned char *dgram_do_unhide(uint16_t type,
54 uint16_t *len,
55 unsigned char *value,
56 unsigned char const *secret,
57 size_t secret_len,
58 unsigned char const *random,
59 size_t random_len,
60 unsigned char *output);
62 /* Description of AVP's indexed by AVP type */
63 struct avp_descrip {
64 char const *name; /* AVP name */
65 int can_hide; /* Can AVP be hidden? */
66 uint16_t min_len; /* Minimum PAYLOAD length */
67 uint16_t max_len; /* Maximum PAYLOAD length (9999 = no limit) */
70 static struct avp_descrip avp_table[] = {
71 /* Name can_hide min_len max_len */
72 {"Message Type", 0, 2, 2}, /* 0 */
73 {"Result Code", 0, 2, 9999}, /* 1 */
74 {"Protocol Version", 0, 2, 2}, /* 2 */
75 {"Framing Capabilities", 1, 4, 4}, /* 3 */
76 {"Bearer Capabilities", 1, 4, 4}, /* 4 */
77 {"Tie Breaker", 0, 8, 8}, /* 5 */
78 {"Firmware Revision", 1, 2, 2}, /* 6 */
79 {"Host Name", 0, 0, 9999}, /* 7 */
80 {"Vendor Name", 1, 0, 9999}, /* 8 */
81 {"Assigned Tunnel ID", 1, 2, 2}, /* 9 */
82 {"Receive Window Size", 0, 2, 2}, /* 10 */
83 {"Challenge", 1, 0, 9999}, /* 11 */
84 {"Q.931 Cause Code", 0, 3, 9999}, /* 12 */
85 {"Challenge Response", 1, 16, 16}, /* 13 */
86 {"Assigned Session ID", 1, 2, 2}, /* 14 */
87 {"Call Serial Number", 1, 4, 4}, /* 15 */
88 {"Minimum BPS", 1, 4, 4}, /* 16 */
89 {"Maximum BPS", 1, 4, 4}, /* 17 */
90 {"Bearer Type", 1, 4, 4}, /* 18 */
91 {"Framing Type", 1, 4, 4}, /* 19 */
92 {"Unknown", 0, 0, 9999}, /* 20 */
93 {"Called Number", 1, 0, 9999}, /* 21 */
94 {"Calling Number", 1, 0, 9999}, /* 22 */
95 {"Sub-Address", 1, 0, 9999}, /* 23 */
96 {"TX Connect Speed", 1, 4, 4}, /* 24 */
97 {"Physical Channel ID", 1, 4, 4}, /* 25 */
98 {"Intial Received Confreq", 1, 0, 9999}, /* 26 */
99 {"Last Sent Confreq", 1, 0, 9999}, /* 27 */
100 {"Last Received Confreq", 1, 0, 9999}, /* 28 */
101 {"Proxy Authen Type", 1, 2, 2}, /* 29 */
102 {"Proxy Authen Name", 1, 0, 9999}, /* 30 */
103 {"Proxy Authen Challenge", 1, 0, 9999}, /* 31 */
104 {"Proxy Authen ID", 1, 2, 2}, /* 32 */
105 {"Proxy Authen Response", 1, 0, 9999}, /* 33 */
106 {"Call Errors", 1, 26, 26}, /* 34 */
107 {"ACCM", 1, 10, 10}, /* 35 */
108 {"Random Vector", 0, 0, 9999}, /* 36 */
109 {"Private Group ID", 1, 0, 9999}, /* 37 */
110 {"RX Connect Speed", 1, 4, 4}, /* 38 */
111 {"Sequencing Required", 0, 0, 0} /* 39 */
114 /* A free list of L2TP dgram strucures. Allocation of L2TP dgrams
115 must be fast... */
116 static l2tp_dgram *dgram_free_list = NULL;
118 static void
119 describe_pulled_avp(uint16_t vendor,
120 uint16_t type,
121 uint16_t len,
122 int hidden,
123 int mandatory,
124 void *val)
126 unsigned char *buf = val;
127 uint16_t i;
128 int ascii = 1;
130 fprintf(stderr, "Pulled avp: len=%d ", (int) len);
131 if (vendor == VENDOR_IETF) {
132 fprintf(stderr, "type='%s' ",avp_table[type].name);
133 } else {
134 fprintf(stderr, "type=%d/%d ", (int) vendor, (int) type);
136 fprintf(stderr, "M=%d H=%d ", mandatory ? 1 : 0, hidden ? 1 : 0);
138 fprintf(stderr, "val='");
139 for (i=0; i<len; i++) {
140 if (buf[i] < 32 || buf[i] > 126) {
141 ascii = 0;
142 break;
145 for (i=0; i<len; i++) {
146 if (ascii) {
147 fprintf(stderr, "%c", buf[i]);
148 } else {
149 fprintf(stderr, "%02X ", (unsigned int) buf[i]);
152 fprintf(stderr, "'\n");
155 /**********************************************************************
156 * %FUNCTION: dgram_validate_avp
157 * %ARGUMENTS:
158 * vendor -- vendor code
159 * type -- AVP type
160 * len -- PAYLOAD length
161 * mandatory -- non-zero if mandatory bit is set
162 * %RETURNS:
163 * 1 if len is valid for type, 0 otherwise.
164 ***********************************************************************/
166 l2tp_dgram_validate_avp(uint16_t vendor,
167 uint16_t type,
168 uint16_t len,
169 int mandatory)
171 if (vendor != VENDOR_IETF) {
172 if (mandatory) {
173 l2tp_set_errmsg("Unknown mandatory AVP (vendor %d, type %d)",
174 (int) vendor, (int) type);
175 return 0;
177 /* I suppose... */
178 return 1;
181 if (type > HIGHEST_AVP) {
182 if (mandatory) {
183 l2tp_set_errmsg("Unknown mandatory AVP of type %d",
184 (int) type);
185 return 0;
187 return 1;
190 return (len >= avp_table[type].min_len &&
191 len <= avp_table[type].max_len);
194 /**********************************************************************
195 * %FUNCTION: dgram_new
196 * %ARGUMENTS:
197 * len -- payload length to allocate (not currently used...)
198 * %RETURNS:
199 * A newly-allocated l2tp_dgram structure or NULL
200 * %DESCRIPTION:
201 * Allocates and initializes an datagram structure.
202 ***********************************************************************/
203 l2tp_dgram *
204 l2tp_dgram_new(size_t len)
206 l2tp_dgram *dgram;
208 if (len > MAX_PACKET_LEN) {
209 l2tp_set_errmsg("dgram_new: cannot allocate datagram with payload length %d",
210 (int) len);
211 return NULL;
214 if (dgram_free_list) {
215 dgram = dgram_free_list;
216 dgram_free_list = dgram->next;
217 } else {
218 dgram = malloc(sizeof(l2tp_dgram));
220 if (!dgram) {
221 l2tp_set_errmsg("dgram_new: Out of memory");
222 return NULL;
224 dgram->bits = 0;
225 dgram->version = 2;
226 dgram->length = 0;
227 dgram->tid = 0;
228 dgram->sid = 0;
229 dgram->Ns = 0;
230 dgram->Nr = 0;
231 dgram->off_size = 0;
232 dgram->last_random = 0;
233 dgram->payload_len = 0;
234 dgram->cursor = 0;
236 /* We maintain this in case it becomes dynamic later on */
237 dgram->alloc_len = MAX_PACKET_LEN;
238 dgram->next = NULL;
240 return dgram;
243 /**********************************************************************
244 * %FUNCTION: dgram_new_control
245 * %ARGUMENTS:
246 * msg_type -- message type
247 * tid -- tunnel ID
248 * sid -- session ID
249 * %RETURNS:
250 * A newly-allocated control datagram
251 * %DESCRIPTION:
252 * Allocates datagram; sets tid and sid fields; adds message_type AVP
253 ***********************************************************************/
254 l2tp_dgram *
255 l2tp_dgram_new_control(uint16_t msg_type,
256 uint16_t tid,
257 uint16_t sid)
259 l2tp_dgram *dgram = l2tp_dgram_new(MAX_PACKET_LEN);
260 uint16_t u16;
262 if (!dgram) return NULL;
264 dgram->bits = TYPE_BIT | LENGTH_BIT | SEQUENCE_BIT;
265 dgram->tid = tid;
266 dgram->sid = sid;
267 dgram->msg_type = msg_type;
268 if (msg_type != MESSAGE_ZLB) {
269 u16 = htons(msg_type);
271 l2tp_dgram_add_avp(dgram, NULL, MANDATORY,
272 sizeof(u16), VENDOR_IETF, AVP_MESSAGE_TYPE, &u16);
274 return dgram;
277 /**********************************************************************
278 * %FUNCTION: dgram_free
279 * %ARGUMENTS:
280 * dgram -- datagram to free
281 * %RETURNS:
282 * Nothing
283 * %DESCRIPTION:
284 * Frees a datagram structure.
285 ***********************************************************************/
286 void
287 l2tp_dgram_free(l2tp_dgram *dgram)
289 if (!dgram) return;
290 dgram->next = dgram_free_list;
291 dgram_free_list = dgram;
294 /**********************************************************************
295 * %FUNCTION: dgram_take_from_wire
296 * %ARGUMENTS:
297 * from -- set to address of peer.
298 * %RETURNS:
299 * NULL on error, allocated datagram otherwise.
300 * %DESCRIPTION:
301 * Reads an L2TP datagram off the wire and puts it in dgram. Adjusts
302 * header fields to host byte order. Keeps reading in a loop unless
303 * we hit a control frame or EAGAIN. This is more efficient than
304 * returning to select loop each time if there's lots of traffic.
305 ***********************************************************************/
306 l2tp_dgram *
307 l2tp_dgram_take_from_wire(struct sockaddr_in *from)
309 /* EXTRA_HEADER_ROOM bytes for other headers like PPPoE, etc. */
311 unsigned char inbuf[MAX_PACKET_LEN+EXTRA_HEADER_ROOM];
312 unsigned char *buf;
313 socklen_t len = sizeof(struct sockaddr_in);
314 int cursor;
315 l2tp_dgram *dgram;
316 unsigned char *payload;
317 unsigned char *tidptr;
318 uint16_t tid, sid;
319 uint16_t cache_tid = 0, cache_sid = 0;
320 l2tp_tunnel *tunnel;
321 l2tp_session *ses = NULL;
322 int mandatory, hidden, err;
323 uint16_t vendor, type;
324 unsigned char *msg;
325 int r;
327 /* Limit iterations before bailing back to select look. Otherwise,
328 we have a nice DoS possibility */
329 int iters = 5;
331 uint16_t off;
332 int framelen;
334 /* Active part of buffer */
335 buf = inbuf + EXTRA_HEADER_ROOM;
337 while(1) {
338 if (--iters <= 0) return NULL;
339 framelen = -1;
340 r = recvfrom(Sock, buf, MAX_PACKET_LEN, 0,
341 (struct sockaddr *) from, &len);
342 if (r <= 0) {
343 return NULL;
346 /* Check version; drop frame if not L2TP (ver = 2) */
347 if ((buf[1] & VERSION_MASK) != 2) continue;
349 /* Not a data frame -- break out of loop and handle control frame */
350 if (buf[0] & TYPE_BIT) break;
352 /* If it's a data frame, we need to be FAST, so do not allocate
353 a dgram structure, etc; just call into handler */
354 payload = buf + 6;
355 tidptr = buf + 2;
356 if (buf[0] & LENGTH_BIT) {
357 framelen = (((uint16_t) buf[2]) << 8) + buf[3];
358 payload += 2;
359 tidptr += 2;
361 if (buf[0] & SEQUENCE_BIT) {
362 payload += 4;
364 if (buf[0] & OFFSET_BIT) {
365 payload += 2;
366 off = (((uint16_t) *(payload-2)) << 8) + *(payload-1);
367 payload += off;
369 off = (payload - buf);
370 if (framelen == -1) {
371 framelen = r - off;
372 } else {
373 if (framelen < off || framelen > r) {
374 continue;
376 /* Only count payload length */
377 framelen -= off;
380 /* Forget the 0xFF, 0x03 HDLC markers */
381 payload += 2;
382 framelen -= 2;
384 if (framelen < 0) {
385 continue;
387 /* Get tunnel, session ID */
388 tid = (((uint16_t) tidptr[0]) << 8) + (uint16_t) tidptr[1];
389 sid = (((uint16_t) tidptr[2]) << 8) + (uint16_t) tidptr[3];
391 /* Only do hash lookup if it's not cached */
392 /* TODO: Is this optimization really worthwhile? */
393 if (!ses || tid != cache_tid || sid != cache_sid) {
394 ses = NULL;
395 tunnel = l2tp_tunnel_find_by_my_id(tid);
396 if (!tunnel) {
397 l2tp_set_errmsg("Unknown tunnel %d", (int) tid);
398 continue;
400 if (tunnel->state != TUNNEL_ESTABLISHED) {
401 /* Drop frame if tunnel in wrong state */
402 continue;
404 /* TODO: Verify source address */
405 ses = l2tp_tunnel_find_session(tunnel, sid);
406 if (!ses) {
407 l2tp_set_errmsg("Unknown session %d in tunnel %d",
408 (int) sid, (int) tid);
409 continue;
411 cache_tid = tid;
412 cache_sid = sid;
413 if (ses->state != SESSION_ESTABLISHED) {
414 /* Drop frame if session in wrong state */
415 continue;
418 ses->call_ops->handle_ppp_frame(ses, payload, framelen);
419 /* Snoop, if necessary */
420 if (ses->snooping) {
421 l2tp_session_lcp_snoop(ses, payload, framelen, 1);
426 /* A bit of slop on dgram size */
427 dgram = l2tp_dgram_new(r);
428 if (!dgram) return NULL;
430 dgram->bits = buf[0];
431 dgram->version = buf[1];
432 cursor = 2;
434 if (dgram->bits & LENGTH_BIT) {
435 PULL_UINT16(buf, cursor, dgram->length);
436 if (dgram->length > r) {
437 l2tp_set_errmsg("Invalid length field %d greater than received datagram size %d", (int) dgram->length, r);
438 l2tp_dgram_free(dgram);
439 return NULL;
441 } else {
442 dgram->length = r;
445 PULL_UINT16(buf, cursor, dgram->tid);
446 PULL_UINT16(buf, cursor, dgram->sid);
447 if (dgram->bits & SEQUENCE_BIT) {
448 PULL_UINT16(buf, cursor, dgram->Ns);
449 PULL_UINT16(buf, cursor, dgram->Nr);
450 } else {
451 dgram->Ns = 0;
452 dgram->Nr = 0;
455 if (dgram->bits & OFFSET_BIT) {
456 PULL_UINT16(buf, cursor, dgram->off_size);
457 } else {
458 dgram->off_size = 0;
460 if (cursor > dgram->length) {
461 l2tp_set_errmsg("Invalid length of datagram %d", (int) dgram->length);
462 l2tp_dgram_free(dgram);
463 return NULL;
466 dgram->payload_len = dgram->length - cursor;
467 memcpy(dgram->data, buf+cursor, dgram->payload_len);
469 /* Pull off the message type */
470 if (dgram->bits & OFFSET_BIT) {
471 l2tp_set_errmsg("Invalid control frame: O bit is set");
472 l2tp_dgram_free(dgram);
473 return NULL;
476 /* Handle ZLB */
477 if (dgram->payload_len == 0) {
478 dgram->msg_type = MESSAGE_ZLB;
479 } else {
480 uint16_t avp_len;
481 msg = l2tp_dgram_pull_avp(dgram, NULL, &mandatory, &hidden,
482 &avp_len, &vendor, &type, &err);
483 if (!msg) {
484 l2tp_dgram_free(dgram);
485 return NULL;
487 if (type != AVP_MESSAGE_TYPE || vendor != VENDOR_IETF) {
488 l2tp_set_errmsg("Invalid control message: First AVP must be message type");
489 l2tp_dgram_free(dgram);
490 return NULL;
492 if (avp_len != 2) {
493 l2tp_set_errmsg("Invalid length %d for message-type AVP", (int) avp_len+6);
494 l2tp_dgram_free(dgram);
495 return NULL;
497 if (!mandatory) {
498 l2tp_set_errmsg("Invalid control message: M bit not set on message-type AVP");
499 l2tp_dgram_free(dgram);
500 return NULL;
502 if (hidden) {
503 l2tp_set_errmsg("Invalid control message: H bit set on message-type AVP");
504 l2tp_dgram_free(dgram);
505 return NULL;
508 dgram->msg_type = ((unsigned int) msg[0]) * 256 +
509 (unsigned int) msg[1];
511 DBG(l2tp_db(DBG_XMIT_RCV,
512 "dgram_take_from_wire() -> %s\n",
513 l2tp_debug_describe_dgram(dgram)));
514 return dgram;
517 /**********************************************************************
518 * %FUNCTION: dgram_send_to_wire
519 * %ARGUMENTS:
520 * dgram -- datagram to send
521 * to -- address to send datagram to
522 * %RETURNS:
523 * Whatever sendto returns. 0 on success, -1 on failure.
524 * %DESCRIPTION:
525 * Adjusts header fields from host byte order, then sends datagram
526 ***********************************************************************/
528 l2tp_dgram_send_to_wire(l2tp_dgram const *dgram,
529 struct sockaddr_in const *to)
531 unsigned char buf[MAX_PACKET_LEN+128];
532 socklen_t len = sizeof(struct sockaddr_in);
533 int cursor = 2;
534 size_t total_len;
535 unsigned char *len_ptr = NULL;
537 DBG(l2tp_db(DBG_XMIT_RCV,
538 "dgram_send_to_wire(%s:%d) -> %s\n",
539 inet_ntoa(to->sin_addr), ntohs(to->sin_port),
540 l2tp_debug_describe_dgram(dgram)));
541 buf[0] = dgram->bits;
542 buf[1] = dgram->version;
544 if (dgram->bits & LENGTH_BIT) {
545 len_ptr = buf + cursor;
546 PUSH_UINT16(buf, cursor, dgram->length);
548 PUSH_UINT16(buf, cursor, dgram->tid);
549 PUSH_UINT16(buf, cursor, dgram->sid);
550 if (dgram->bits & SEQUENCE_BIT) {
551 PUSH_UINT16(buf, cursor, dgram->Ns);
552 PUSH_UINT16(buf, cursor, dgram->Nr);
554 if (dgram->bits & OFFSET_BIT) {
555 PUSH_UINT16(buf, cursor, dgram->off_size);
557 total_len = cursor + dgram->payload_len;
558 if (dgram->bits & LENGTH_BIT) {
559 *len_ptr++ = total_len / 256;
560 *len_ptr = total_len & 255;
562 memcpy(buf+cursor, dgram->data, dgram->payload_len);
563 return sendto(Sock, buf, total_len, 0,
564 (struct sockaddr const *) to, len);
567 /**********************************************************************
568 * %FUNCTION: dgram_add_avp
569 * %ARGUMENTS:
570 * dgram -- the L2TP datagram
571 * tunnel -- the tunnel it will be sent on (for secret for hiding)
572 * mandatory -- if true, set the M bit
573 * len -- length of VALUE. NOT length of entire attribute!
574 * vendor -- vendor ID
575 * type -- attribute type
576 * val -- attribute value
577 * %RETURNS:
578 * 0 on success, -1 on failure
579 * %DESCRIPTION:
580 * Adds an AVP to the datagram. If AVP may be hidden, and we have
581 * a secret for it, then hide the AVP.
582 ***********************************************************************/
584 l2tp_dgram_add_avp(l2tp_dgram *dgram,
585 l2tp_tunnel *tunnel,
586 int mandatory,
587 uint16_t len,
588 uint16_t vendor,
589 uint16_t type,
590 void *val)
592 static unsigned char hidden_buffer[1024];
593 unsigned char const *random_data;
594 size_t random_len;
595 int hidden = 0;
597 /* max len is 1023 - 6 */
598 if (len > 1023 - 6) {
599 l2tp_set_errmsg("AVP length of %d too long", (int) len);
600 return -1;
603 /* Do hiding where possible */
604 if (tunnel &&
605 tunnel->peer &&
606 tunnel->peer->hide_avps &&
607 vendor == VENDOR_IETF &&
608 tunnel->peer->secret_len &&
609 len <= 1021 - 6 &&
610 avp_table[type].can_hide) {
611 if (!dgram->last_random) {
612 /* Add a random vector */
613 if (dgram_add_random_vector_avp(dgram) < 0) return -1;
615 /* Get pointer to random data */
616 random_data = dgram->data + dgram->last_random + 6;
617 random_len = GET_AVP_LEN(dgram->data + dgram->last_random) - 6;
619 /* Hide the value into the buffer */
620 dgram_do_hide(type, len, val, (unsigned char *) tunnel->peer->secret,
621 tunnel->peer->secret_len,
622 random_data, random_len, hidden_buffer);
624 /* Length is increased by 2 */
625 len += 2;
626 val = hidden_buffer;
627 hidden = 1;
630 /* Adjust from payload len to actual len */
631 len += 6;
633 /* Does datagram have room? */
634 if (dgram->cursor + len > dgram->alloc_len) {
635 l2tp_set_errmsg("No room for AVP of length %d", (int) len);
636 return -1;
639 dgram->data[dgram->cursor] = 0;
640 if (mandatory) {
641 dgram->data[dgram->cursor] |= AVP_MANDATORY_BIT;
643 if (hidden) {
644 dgram->data[dgram->cursor] |= AVP_HIDDEN_BIT;
647 dgram->data[dgram->cursor] |= (len >> 8);
648 dgram->data[dgram->cursor+1] = (len & 0xFF);
649 dgram->data[dgram->cursor+2] = (vendor >> 8);
650 dgram->data[dgram->cursor+3] = (vendor & 0xFF);
651 dgram->data[dgram->cursor+4] = (type >> 8);
652 dgram->data[dgram->cursor+5] = (type & 0xFF);
654 if (len > 6) {
655 memcpy(dgram->data + dgram->cursor + 6, val, len-6);
657 if (type == AVP_RANDOM_VECTOR) {
658 /* Remember location of random vector */
659 dgram->last_random = dgram->cursor;
661 dgram->cursor += len;
662 dgram->payload_len = dgram->cursor;
663 return 0;
666 /**********************************************************************
667 * %FUNCTION: dgram_pull_avp
668 * %ARGUMENTS:
669 * dgram -- the L2TP datagram
670 * tunnel -- the tunnel it was received on (for secret for hiding)
671 * mandatory -- if set to true, the M bit was set.
672 * hidden -- if set to true, the value was hidden
673 * len -- set to length of value (after unhiding)
674 * vendor -- set to vendor ID
675 * type -- set to attribute type
676 * err -- set to true if an error occurs, false if not.
677 * %RETURNS:
678 * A pointer to a buffer containing the value, or NULL if an
679 * error occurs or there are no more AVPs.
680 * %DESCRIPTION:
681 * Pulls an AVP out of a received datagram.
682 ***********************************************************************/
683 unsigned char *
684 l2tp_dgram_pull_avp(l2tp_dgram *dgram,
685 l2tp_tunnel *tunnel,
686 int *mandatory,
687 int *hidden,
688 uint16_t *len,
689 uint16_t *vendor,
690 uint16_t *type,
691 int *err)
693 static unsigned char val[1024];
694 unsigned char *ans;
695 unsigned char *random_data;
696 size_t random_len;
697 int local_hidden;
698 int local_mandatory;
700 *err = 1;
701 if (dgram->cursor >= dgram->payload_len) {
702 /* EOF */
703 *err = 0;
704 return NULL;
707 /* Get bits */
708 if (!mandatory) {
709 mandatory = &local_mandatory;
711 *mandatory = dgram->data[dgram->cursor] & AVP_MANDATORY_BIT;
713 if (!hidden) {
714 hidden = &local_hidden;
716 *hidden = dgram->data[dgram->cursor] & AVP_HIDDEN_BIT;
717 if (dgram->data[dgram->cursor] & AVP_RESERVED_BITS) {
718 l2tp_set_errmsg("AVP with reserved bits set to non-zero");
719 return NULL;
722 /* Get len */
723 *len = ((unsigned int) (dgram->data[dgram->cursor] & 3)) * 256 +
724 dgram->data[dgram->cursor+1];
725 if (*len < 6) {
726 l2tp_set_errmsg("Received AVP of length %d (too short)", (int) *len);
727 return NULL;
730 if (dgram->cursor + *len > dgram->payload_len) {
731 l2tp_set_errmsg("Received AVP of length %d too long for rest of datagram",
732 (int) *len);
733 return NULL;
735 dgram->cursor += 2;
737 PULL_UINT16(dgram->data, dgram->cursor, *vendor);
738 PULL_UINT16(dgram->data, dgram->cursor, *type);
740 /* If we see a random vector, remember it */
741 if (*vendor == VENDOR_IETF && *type == AVP_RANDOM_VECTOR) {
742 if (*hidden) {
743 l2tp_set_errmsg("Invalid random vector AVP has H bit set");
744 return NULL;
746 dgram->last_random = dgram->cursor - 6;
749 ans = dgram->data + dgram->cursor;
750 dgram->cursor += *len - 6;
751 if (*hidden) {
752 if (!tunnel) {
753 l2tp_set_errmsg("AVP cannot be hidden");
754 return NULL;
756 if (*len < 8) {
757 l2tp_set_errmsg("Received hidden AVP of length %d (too short)",
758 (int) *len);
759 return NULL;
762 if (!tunnel->peer) {
763 l2tp_set_errmsg("No peer??");
764 return NULL;
766 if (!tunnel->peer->secret_len) {
767 l2tp_set_errmsg("No shared secret to unhide AVP");
768 return NULL;
770 if (!dgram->last_random) {
771 l2tp_set_errmsg("Cannot unhide AVP unless Random Vector received first");
772 return NULL;
775 if (*type <= HIGHEST_AVP) {
776 if (!avp_table[*type].can_hide) {
777 l2tp_set_errmsg("AVP of type %s cannot be hidden, but H bit set",
778 avp_table[*type].name);
779 return NULL;
783 /* Get pointer to random data */
784 random_data = dgram->data + dgram->last_random + 6;
785 random_len = GET_AVP_LEN(dgram->data + dgram->last_random) - 6;
787 /* Unhide value */
788 ans = dgram_do_unhide(*type, len, ans,
789 (unsigned char *) tunnel->peer->secret,
790 tunnel->peer->secret_len,
791 random_data, random_len, val);
792 if (!ans) return NULL;
795 /* Set len to length of value only */
796 *len -= 6;
798 *err = 0;
799 /* DBG(describe_pulled_avp(*vendor, *type, *len, *hidden, *mandatory, ans)); */
800 return ans;
804 /**********************************************************************
805 * %FUNCTION: dgram_do_hide
806 * %ARGUMENTS:
807 * type -- attribute type
808 * len -- attribute length
809 * value -- attribute value
810 * secret -- shared tunnel secret
811 * secret_len -- length of secret
812 * random -- random data
813 * random_len -- length of random data
814 * output -- where to put result
815 * %RETURNS:
816 * Nothing
817 * %DESCRIPTION:
818 * Hides AVP into output as described in RFC2661. Does not do
819 * padding (should we?)
820 ***********************************************************************/
821 static void
822 dgram_do_hide(uint16_t type,
823 uint16_t len,
824 unsigned char *value,
825 unsigned char const *secret,
826 size_t secret_len,
827 unsigned char const *random_data,
828 size_t random_len,
829 unsigned char *output)
831 struct MD5Context ctx;
832 unsigned char t[2];
833 unsigned char digest[16];
834 size_t done;
835 size_t todo = len;
837 /* Put type in network byte order */
838 t[0] = type / 256;
839 t[1] = type & 255;
841 /* Compute initial pad */
842 MD5Init(&ctx);
843 MD5Update(&ctx, t, 2);
844 MD5Update(&ctx, secret, secret_len);
845 MD5Update(&ctx, random_data, random_len);
846 MD5Final(digest, &ctx);
848 /* Insert length */
849 output[0] = digest[0] ^ (len / 256);
850 output[1] = digest[1] ^ (len & 255);
851 output += 2;
852 done = 2;
854 /* Insert value */
855 while(todo) {
856 *output = digest[done] ^ *value;
857 ++output;
858 ++value;
859 --todo;
860 ++done;
861 if (done == 16 && todo) {
862 /* Compute new digest */
863 done = 0;
864 MD5Init(&ctx);
865 MD5Update(&ctx, secret, secret_len);
866 MD5Update(&ctx, output-16, 16);
867 MD5Final(digest, &ctx);
872 /**********************************************************************
873 * %FUNCTION: dgram_do_unhide
874 * %ARGUMENTS:
875 * type -- attribute type
876 * len -- attribute length (input = orig len; output = unhidden len)
877 * value -- attribute value (the hidden characters)
878 * secret -- shared tunnel secret
879 * secret_len -- length of secret
880 * random_data -- random data
881 * random_len -- length of random data
882 * output -- where to put result
883 * %RETURNS:
884 * pointer to "output" on success; NULL on failure.
885 * %DESCRIPTION:
886 * Un-hides AVP as in RFC2661
887 ***********************************************************************/
888 static unsigned char *
889 dgram_do_unhide(uint16_t type,
890 uint16_t *len,
891 unsigned char *value,
892 unsigned char const *secret,
893 size_t secret_len,
894 unsigned char const *random_data,
895 size_t random_len,
896 unsigned char *output)
898 struct MD5Context ctx;
899 unsigned char t[2];
900 unsigned char digest[16];
901 uint16_t tmplen;
902 unsigned char *orig_output = output;
903 size_t done, todo;
905 /* Put type in network byte order */
906 t[0] = type / 256;
907 t[1] = type & 255;
909 /* Compute initial pad */
910 MD5Init(&ctx);
911 MD5Update(&ctx, t, 2);
912 MD5Update(&ctx, secret, secret_len);
913 MD5Update(&ctx, random_data, random_len);
914 MD5Final(digest, &ctx);
916 /* Get hidden length */
917 tmplen =
918 ((uint16_t) (digest[0] ^ value[0])) * 256 +
919 (uint16_t) (digest[1] ^ value[1]);
921 value += 2;
923 if (tmplen > *len-8) {
924 l2tp_set_errmsg("Hidden length %d too long in AVP of length %d",
925 (int) tmplen, (int) *len);
926 return NULL;
929 /* Adjust len. Add 6 to compensate for pseudo-header */
930 *len = tmplen + 6;
932 /* Decrypt remainder */
933 done = 2;
934 todo = tmplen;
935 while(todo) {
936 *output = digest[done] ^ *value;
937 ++output;
938 ++value;
939 --todo;
940 ++done;
941 if (done == 16 && todo) {
942 /* Compute new digest */
943 done = 0;
944 MD5Init(&ctx);
945 MD5Update(&ctx, secret, secret_len);
946 MD5Update(&ctx, value-16, 16);
947 MD5Final(digest, &ctx);
950 return orig_output;
953 /**********************************************************************
954 * %FUNCTION: dgram_search_avp
955 * %ARGUMENTS:
956 * dgram -- the datagram
957 * tunnel -- associated tunnel
958 * mandatory -- set to 1 if M bit was set
959 * hidden -- set to 1 if H bit was set
960 * len -- set to length of payload
961 * vendor -- vendor ID we want
962 * type -- AVP type we want
963 * %RETURNS:
964 * A pointer to the AVP value if found, NULL if not
965 * %DESCRIPTION:
966 * Searches dgram for specific AVP type.
967 ***********************************************************************/
968 unsigned char *
969 l2tp_dgram_search_avp(l2tp_dgram *dgram,
970 l2tp_tunnel *tunnel,
971 int *mandatory,
972 int *hidden,
973 uint16_t *len,
974 uint16_t vendor,
975 uint16_t type)
977 uint16_t svend, stype;
978 int err;
979 unsigned char *val;
980 size_t cursor = dgram->cursor;
981 size_t last_random = dgram->last_random;
982 while(1) {
983 val = l2tp_dgram_pull_avp(dgram, tunnel, mandatory, hidden, len,
984 &svend, &stype, &err);
985 if (!val) {
986 if (!err) {
987 l2tp_set_errmsg("AVP of vendor/type (%d, %d) not found",
988 (int) vendor, (int) type);
990 dgram->cursor = cursor;
991 dgram->last_random = last_random;
992 return NULL;
994 if (vendor == svend && type == stype) break;
996 dgram->cursor = cursor;
997 dgram->last_random = last_random;
998 return val;
1001 /**********************************************************************
1002 * %FUNCTION: dgram_send_ppp_frame
1003 * %ARGUMENTS:
1004 * ses -- the session
1005 * buf -- PPP frame. BUF MUST HAVE AT LEAST 16 BYTES OF SPACE AHEAD OF IT!
1006 * len -- length of PPP frame
1007 * %RETURNS:
1008 * Whatever sendto returns
1009 * %DESCRIPTION:
1010 * Sends a PPP frame. TODO: Implement sequence numbers if required.
1011 ***********************************************************************/
1013 l2tp_dgram_send_ppp_frame(l2tp_session *ses,
1014 unsigned char const *buf,
1015 int len)
1017 int r;
1018 unsigned char *real_buf = (unsigned char *) buf - 8;
1019 l2tp_tunnel *tunnel = ses->tunnel;
1021 /* Drop frame if tunnel and/or session in wrong state */
1022 if (!tunnel ||
1023 tunnel->state != TUNNEL_ESTABLISHED ||
1024 ses->state != SESSION_ESTABLISHED) {
1025 return 0;
1028 /* If there is a pending ack on the tunnel, cancel and ack now */
1029 if (tunnel->ack_handler) {
1030 Event_DelHandler(tunnel->es, tunnel->ack_handler);
1031 tunnel->ack_handler = NULL;
1032 tunnel_send_ZLB(tunnel);
1035 real_buf[0] = 0;
1036 real_buf[1] = 2;
1037 real_buf[2] = (tunnel->assigned_id >> 8);
1038 real_buf[3] = tunnel->assigned_id & 0xFF;
1039 real_buf[4] = ses->assigned_id >> 8;
1040 real_buf[5] = ses->assigned_id & 0xFF;
1041 real_buf[6] = 0xFF; /* HDLC address */
1042 real_buf[7] = 0x03; /* HDLC control */
1043 r = sendto(Sock, real_buf, len+8, 0,
1044 (struct sockaddr const *) &tunnel->peer_addr,
1045 sizeof(struct sockaddr_in));
1046 /* Snoop, if necessary */
1047 if (ses->snooping) {
1048 l2tp_session_lcp_snoop(ses, buf, len, 0);
1050 return r;
1053 /**********************************************************************
1054 * %FUNCTION: dgram_add_random_vector_avp
1055 * %ARGUMENTS:
1056 * dgram -- datagram
1057 * %RETURNS:
1058 * 0 on success; -1 on failure
1059 * %DESCRIPTION:
1060 * Adds a random-vector AVP to the datagram
1061 ***********************************************************************/
1062 static int
1063 dgram_add_random_vector_avp(l2tp_dgram *dgram)
1065 unsigned char buf[16];
1067 l2tp_random_fill(buf, sizeof(buf));
1069 return l2tp_dgram_add_avp(dgram, NULL, MANDATORY, sizeof(buf),
1070 VENDOR_IETF, AVP_RANDOM_VECTOR, buf);