Tomato 1.28
[tomato/tomato-null.git] / release / src / router / rp-l2tp / dgram.c
blobcf352eefaa4930471ff912394340eb487c71e800
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, cache_sid;
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\n",
539 l2tp_debug_describe_dgram(dgram)));
540 buf[0] = dgram->bits;
541 buf[1] = dgram->version;
543 if (dgram->bits & LENGTH_BIT) {
544 len_ptr = buf + cursor;
545 PUSH_UINT16(buf, cursor, dgram->length);
547 PUSH_UINT16(buf, cursor, dgram->tid);
548 PUSH_UINT16(buf, cursor, dgram->sid);
549 if (dgram->bits & SEQUENCE_BIT) {
550 PUSH_UINT16(buf, cursor, dgram->Ns);
551 PUSH_UINT16(buf, cursor, dgram->Nr);
553 if (dgram->bits & OFFSET_BIT) {
554 PUSH_UINT16(buf, cursor, dgram->off_size);
556 total_len = cursor + dgram->payload_len;
557 if (dgram->bits & LENGTH_BIT) {
558 *len_ptr++ = total_len / 256;
559 *len_ptr = total_len & 255;
561 memcpy(buf+cursor, dgram->data, dgram->payload_len);
562 return sendto(Sock, buf, total_len, 0,
563 (struct sockaddr const *) to, len);
566 /**********************************************************************
567 * %FUNCTION: dgram_add_avp
568 * %ARGUMENTS:
569 * dgram -- the L2TP datagram
570 * tunnel -- the tunnel it will be sent on (for secret for hiding)
571 * mandatory -- if true, set the M bit
572 * len -- length of VALUE. NOT length of entire attribute!
573 * vendor -- vendor ID
574 * type -- attribute type
575 * val -- attribute value
576 * %RETURNS:
577 * 0 on success, -1 on failure
578 * %DESCRIPTION:
579 * Adds an AVP to the datagram. If AVP may be hidden, and we have
580 * a secret for it, then hide the AVP.
581 ***********************************************************************/
583 l2tp_dgram_add_avp(l2tp_dgram *dgram,
584 l2tp_tunnel *tunnel,
585 int mandatory,
586 uint16_t len,
587 uint16_t vendor,
588 uint16_t type,
589 void *val)
591 static unsigned char hidden_buffer[1024];
592 unsigned char const *random_data;
593 size_t random_len;
594 int hidden = 0;
596 /* max len is 1023 - 6 */
597 if (len > 1023 - 6) {
598 l2tp_set_errmsg("AVP length of %d too long", (int) len);
599 return -1;
602 /* Do hiding where possible */
603 if (tunnel &&
604 tunnel->peer &&
605 tunnel->peer->hide_avps &&
606 vendor == VENDOR_IETF &&
607 tunnel->peer->secret_len &&
608 len <= 1021 - 6 &&
609 avp_table[type].can_hide) {
610 if (!dgram->last_random) {
611 /* Add a random vector */
612 if (dgram_add_random_vector_avp(dgram) < 0) return -1;
614 /* Get pointer to random data */
615 random_data = dgram->data + dgram->last_random + 6;
616 random_len = GET_AVP_LEN(dgram->data + dgram->last_random) - 6;
618 /* Hide the value into the buffer */
619 dgram_do_hide(type, len, val, (unsigned char *) tunnel->peer->secret,
620 tunnel->peer->secret_len,
621 random_data, random_len, hidden_buffer);
623 /* Length is increased by 2 */
624 len += 2;
625 val = hidden_buffer;
626 hidden = 1;
629 /* Adjust from payload len to actual len */
630 len += 6;
632 /* Does datagram have room? */
633 if (dgram->cursor + len > dgram->alloc_len) {
634 l2tp_set_errmsg("No room for AVP of length %d", (int) len);
635 return -1;
638 dgram->data[dgram->cursor] = 0;
639 if (mandatory) {
640 dgram->data[dgram->cursor] |= AVP_MANDATORY_BIT;
642 if (hidden) {
643 dgram->data[dgram->cursor] |= AVP_HIDDEN_BIT;
646 dgram->data[dgram->cursor] |= (len >> 8);
647 dgram->data[dgram->cursor+1] = (len & 0xFF);
648 dgram->data[dgram->cursor+2] = (vendor >> 8);
649 dgram->data[dgram->cursor+3] = (vendor & 0xFF);
650 dgram->data[dgram->cursor+4] = (type >> 8);
651 dgram->data[dgram->cursor+5] = (type & 0xFF);
653 if (len > 6) {
654 memcpy(dgram->data + dgram->cursor + 6, val, len-6);
656 if (type == AVP_RANDOM_VECTOR) {
657 /* Remember location of random vector */
658 dgram->last_random = dgram->cursor;
660 dgram->cursor += len;
661 dgram->payload_len = dgram->cursor;
662 return 0;
665 /**********************************************************************
666 * %FUNCTION: dgram_pull_avp
667 * %ARGUMENTS:
668 * dgram -- the L2TP datagram
669 * tunnel -- the tunnel it was received on (for secret for hiding)
670 * mandatory -- if set to true, the M bit was set.
671 * hidden -- if set to true, the value was hidden
672 * len -- set to length of value (after unhiding)
673 * vendor -- set to vendor ID
674 * type -- set to attribute type
675 * err -- set to true if an error occurs, false if not.
676 * %RETURNS:
677 * A pointer to a buffer containing the value, or NULL if an
678 * error occurs or there are no more AVPs.
679 * %DESCRIPTION:
680 * Pulls an AVP out of a received datagram.
681 ***********************************************************************/
682 unsigned char *
683 l2tp_dgram_pull_avp(l2tp_dgram *dgram,
684 l2tp_tunnel *tunnel,
685 int *mandatory,
686 int *hidden,
687 uint16_t *len,
688 uint16_t *vendor,
689 uint16_t *type,
690 int *err)
692 static unsigned char val[1024];
693 unsigned char *ans;
694 unsigned char *random_data;
695 size_t random_len;
696 int local_hidden;
697 int local_mandatory;
699 *err = 1;
700 if (dgram->cursor >= dgram->payload_len) {
701 /* EOF */
702 *err = 0;
703 return NULL;
706 /* Get bits */
707 if (!mandatory) {
708 mandatory = &local_mandatory;
710 *mandatory = dgram->data[dgram->cursor] & AVP_MANDATORY_BIT;
712 if (!hidden) {
713 hidden = &local_hidden;
715 *hidden = dgram->data[dgram->cursor] & AVP_HIDDEN_BIT;
716 if (dgram->data[dgram->cursor] & AVP_RESERVED_BITS) {
717 l2tp_set_errmsg("AVP with reserved bits set to non-zero");
718 return NULL;
721 /* Get len */
722 *len = ((unsigned int) (dgram->data[dgram->cursor] & 3)) * 256 +
723 dgram->data[dgram->cursor+1];
724 if (*len < 6) {
725 l2tp_set_errmsg("Received AVP of length %d (too short)", (int) *len);
726 return NULL;
729 if (dgram->cursor + *len > dgram->payload_len) {
730 l2tp_set_errmsg("Received AVP of length %d too long for rest of datagram",
731 (int) *len);
732 return NULL;
734 dgram->cursor += 2;
736 PULL_UINT16(dgram->data, dgram->cursor, *vendor);
737 PULL_UINT16(dgram->data, dgram->cursor, *type);
739 /* If we see a random vector, remember it */
740 if (*vendor == VENDOR_IETF && *type == AVP_RANDOM_VECTOR) {
741 if (*hidden) {
742 l2tp_set_errmsg("Invalid random vector AVP has H bit set");
743 return NULL;
745 dgram->last_random = dgram->cursor - 6;
748 ans = dgram->data + dgram->cursor;
749 dgram->cursor += *len - 6;
750 if (*hidden) {
751 if (!tunnel) {
752 l2tp_set_errmsg("AVP cannot be hidden");
753 return NULL;
755 if (*len < 8) {
756 l2tp_set_errmsg("Received hidden AVP of length %d (too short)",
757 (int) *len);
758 return NULL;
761 if (!tunnel->peer) {
762 l2tp_set_errmsg("No peer??");
763 return NULL;
765 if (!tunnel->peer->secret_len) {
766 l2tp_set_errmsg("No shared secret to unhide AVP");
767 return NULL;
769 if (!dgram->last_random) {
770 l2tp_set_errmsg("Cannot unhide AVP unless Random Vector received first");
771 return NULL;
774 if (*type <= HIGHEST_AVP) {
775 if (!avp_table[*type].can_hide) {
776 l2tp_set_errmsg("AVP of type %s cannot be hidden, but H bit set",
777 avp_table[*type].name);
778 return NULL;
782 /* Get pointer to random data */
783 random_data = dgram->data + dgram->last_random + 6;
784 random_len = GET_AVP_LEN(dgram->data + dgram->last_random) - 6;
786 /* Unhide value */
787 ans = dgram_do_unhide(*type, len, ans,
788 (unsigned char *) tunnel->peer->secret,
789 tunnel->peer->secret_len,
790 random_data, random_len, val);
791 if (!ans) return NULL;
794 /* Set len to length of value only */
795 *len -= 6;
797 *err = 0;
798 /* DBG(describe_pulled_avp(*vendor, *type, *len, *hidden, *mandatory, ans)); */
799 return ans;
803 /**********************************************************************
804 * %FUNCTION: dgram_do_hide
805 * %ARGUMENTS:
806 * type -- attribute type
807 * len -- attribute length
808 * value -- attribute value
809 * secret -- shared tunnel secret
810 * secret_len -- length of secret
811 * random -- random data
812 * random_len -- length of random data
813 * output -- where to put result
814 * %RETURNS:
815 * Nothing
816 * %DESCRIPTION:
817 * Hides AVP into output as described in RFC2661. Does not do
818 * padding (should we?)
819 ***********************************************************************/
820 static void
821 dgram_do_hide(uint16_t type,
822 uint16_t len,
823 unsigned char *value,
824 unsigned char const *secret,
825 size_t secret_len,
826 unsigned char const *random_data,
827 size_t random_len,
828 unsigned char *output)
830 struct MD5Context ctx;
831 unsigned char t[2];
832 unsigned char digest[16];
833 size_t done;
834 size_t todo = len;
836 /* Put type in network byte order */
837 t[0] = type / 256;
838 t[1] = type & 255;
840 /* Compute initial pad */
841 MD5Init(&ctx);
842 MD5Update(&ctx, t, 2);
843 MD5Update(&ctx, secret, secret_len);
844 MD5Update(&ctx, random_data, random_len);
845 MD5Final(digest, &ctx);
847 /* Insert length */
848 output[0] = digest[0] ^ (len / 256);
849 output[1] = digest[1] ^ (len & 255);
850 output += 2;
851 done = 2;
853 /* Insert value */
854 while(todo) {
855 *output = digest[done] ^ *value;
856 ++output;
857 ++value;
858 --todo;
859 ++done;
860 if (done == 16 && todo) {
861 /* Compute new digest */
862 done = 0;
863 MD5Init(&ctx);
864 MD5Update(&ctx, secret, secret_len);
865 MD5Update(&ctx, output-16, 16);
866 MD5Final(digest, &ctx);
871 /**********************************************************************
872 * %FUNCTION: dgram_do_unhide
873 * %ARGUMENTS:
874 * type -- attribute type
875 * len -- attribute length (input = orig len; output = unhidden len)
876 * value -- attribute value (the hidden characters)
877 * secret -- shared tunnel secret
878 * secret_len -- length of secret
879 * random_data -- random data
880 * random_len -- length of random data
881 * output -- where to put result
882 * %RETURNS:
883 * pointer to "output" on success; NULL on failure.
884 * %DESCRIPTION:
885 * Un-hides AVP as in RFC2661
886 ***********************************************************************/
887 static unsigned char *
888 dgram_do_unhide(uint16_t type,
889 uint16_t *len,
890 unsigned char *value,
891 unsigned char const *secret,
892 size_t secret_len,
893 unsigned char const *random_data,
894 size_t random_len,
895 unsigned char *output)
897 struct MD5Context ctx;
898 unsigned char t[2];
899 unsigned char digest[16];
900 uint16_t tmplen;
901 unsigned char *orig_output = output;
902 size_t done, todo;
904 /* Put type in network byte order */
905 t[0] = type / 256;
906 t[1] = type & 255;
908 /* Compute initial pad */
909 MD5Init(&ctx);
910 MD5Update(&ctx, t, 2);
911 MD5Update(&ctx, secret, secret_len);
912 MD5Update(&ctx, random_data, random_len);
913 MD5Final(digest, &ctx);
915 /* Get hidden length */
916 tmplen =
917 ((uint16_t) (digest[0] ^ value[0])) * 256 +
918 (uint16_t) (digest[1] ^ value[1]);
920 value += 2;
922 if (tmplen > *len-8) {
923 l2tp_set_errmsg("Hidden length %d too long in AVP of length %d",
924 (int) tmplen, (int) *len);
925 return NULL;
928 /* Adjust len. Add 6 to compensate for pseudo-header */
929 *len = tmplen + 6;
931 /* Decrypt remainder */
932 done = 2;
933 todo = tmplen;
934 while(todo) {
935 *output = digest[done] ^ *value;
936 ++output;
937 ++value;
938 --todo;
939 ++done;
940 if (done == 16 && todo) {
941 /* Compute new digest */
942 done = 0;
943 MD5Init(&ctx);
944 MD5Update(&ctx, secret, secret_len);
945 MD5Update(&ctx, value-16, 16);
946 MD5Final(digest, &ctx);
949 return orig_output;
952 /**********************************************************************
953 * %FUNCTION: dgram_search_avp
954 * %ARGUMENTS:
955 * dgram -- the datagram
956 * tunnel -- associated tunnel
957 * mandatory -- set to 1 if M bit was set
958 * hidden -- set to 1 if H bit was set
959 * len -- set to length of payload
960 * vendor -- vendor ID we want
961 * type -- AVP type we want
962 * %RETURNS:
963 * A pointer to the AVP value if found, NULL if not
964 * %DESCRIPTION:
965 * Searches dgram for specific AVP type.
966 ***********************************************************************/
967 unsigned char *
968 l2tp_dgram_search_avp(l2tp_dgram *dgram,
969 l2tp_tunnel *tunnel,
970 int *mandatory,
971 int *hidden,
972 uint16_t *len,
973 uint16_t vendor,
974 uint16_t type)
976 uint16_t svend, stype;
977 int err;
978 unsigned char *val;
979 size_t cursor = dgram->cursor;
980 size_t last_random = dgram->last_random;
981 while(1) {
982 val = l2tp_dgram_pull_avp(dgram, tunnel, mandatory, hidden, len,
983 &svend, &stype, &err);
984 if (!val) {
985 if (!err) {
986 l2tp_set_errmsg("AVP of vendor/type (%d, %d) not found",
987 (int) vendor, (int) type);
989 dgram->cursor = cursor;
990 dgram->last_random = last_random;
991 return NULL;
993 if (vendor == svend && type == stype) break;
995 dgram->cursor = cursor;
996 dgram->last_random = last_random;
997 return val;
1000 /**********************************************************************
1001 * %FUNCTION: dgram_send_ppp_frame
1002 * %ARGUMENTS:
1003 * ses -- the session
1004 * buf -- PPP frame. BUF MUST HAVE AT LEAST 16 BYTES OF SPACE AHEAD OF IT!
1005 * len -- length of PPP frame
1006 * %RETURNS:
1007 * Whatever sendto returns
1008 * %DESCRIPTION:
1009 * Sends a PPP frame. TODO: Implement sequence numbers if required.
1010 ***********************************************************************/
1012 l2tp_dgram_send_ppp_frame(l2tp_session *ses,
1013 unsigned char const *buf,
1014 int len)
1016 int r;
1017 unsigned char *real_buf = (unsigned char *) buf - 8;
1018 l2tp_tunnel *tunnel = ses->tunnel;
1020 /* Drop frame if tunnel and/or session in wrong state */
1021 if (!tunnel ||
1022 tunnel->state != TUNNEL_ESTABLISHED ||
1023 ses->state != SESSION_ESTABLISHED) {
1024 return 0;
1027 /* If there is a pending ack on the tunnel, cancel and ack now */
1028 if (tunnel->ack_handler) {
1029 Event_DelHandler(tunnel->es, tunnel->ack_handler);
1030 tunnel->ack_handler = NULL;
1031 tunnel_send_ZLB(tunnel);
1034 real_buf[0] = 0;
1035 real_buf[1] = 2;
1036 real_buf[2] = (tunnel->assigned_id >> 8);
1037 real_buf[3] = tunnel->assigned_id & 0xFF;
1038 real_buf[4] = ses->assigned_id >> 8;
1039 real_buf[5] = ses->assigned_id & 0xFF;
1040 real_buf[6] = 0xFF; /* HDLC address */
1041 real_buf[7] = 0x03; /* HDLC control */
1042 r = sendto(Sock, real_buf, len+8, 0,
1043 (struct sockaddr const *) &tunnel->peer_addr,
1044 sizeof(struct sockaddr_in));
1045 /* Snoop, if necessary */
1046 if (ses->snooping) {
1047 l2tp_session_lcp_snoop(ses, buf, len, 0);
1049 return r;
1052 /**********************************************************************
1053 * %FUNCTION: dgram_add_random_vector_avp
1054 * %ARGUMENTS:
1055 * dgram -- datagram
1056 * %RETURNS:
1057 * 0 on success; -1 on failure
1058 * %DESCRIPTION:
1059 * Adds a random-vector AVP to the datagram
1060 ***********************************************************************/
1061 static int
1062 dgram_add_random_vector_avp(l2tp_dgram *dgram)
1064 unsigned char buf[16];
1066 l2tp_random_fill(buf, sizeof(buf));
1068 return l2tp_dgram_add_avp(dgram, NULL, MANDATORY, sizeof(buf),
1069 VENDOR_IETF, AVP_RANDOM_VECTOR, buf);