fix for -v from Juergen Kammer
[l2tpns.git] / ppp.c
1 // L2TPNS PPP Stuff
2
3 char const *cvs_id_ppp = "$Id: ppp.c,v 1.8 2004/07/11 07:57:35 bodea Exp $";
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <stdlib.h>
10 #include "l2tpns.h"
11 #include "constants.h"
12 #include "plugin.h"
13 #include "util.h"
14 #include "tbf.h"
15 #include "cluster.h"
16
17 extern tunnelt *tunnel;
18 extern sessiont *session;
19 extern radiust *radius;
20 extern int tunfd;
21 extern char hostname[];
22 extern u32 eth_tx;
23 extern time_t time_now;
24 extern struct configt *config;
25
26 // Process PAP messages
27 void processpap(tunnelidt t, sessionidt s, u8 * p, u16 l)
28 {
29 char user[129];
30 char pass[129];
31
32
33 CSTAT(call_processpap);
34
35 log_hex(5, "PAP", p, l);
36 if (l < 4)
37 {
38 log(1, 0, s, t, "Short PAP %u bytes\n", l);
39 STAT(tunnel_rx_errors);
40 return ;
41 }
42 if (*p != 1)
43 {
44 log(1, 0, s, t, "Unexpected PAP code %d\n", *p);
45 STAT(tunnel_rx_errors);
46 return ;
47 }
48 if (ntohs(*(u16 *) (p + 2)) > l)
49 {
50 log(1, 0, s, t, "Length mismatch PAP %d/%d\n", ntohs(*(u16 *) (p + 2)), l);
51 STAT(tunnel_rx_errors);
52 return ;
53 }
54 {
55 u8 *b = p;
56 b += 4;
57 if (*b && *b < sizeof(user))
58 memcpy(user, b + 1, *b);
59 user[*b] = 0;
60 b += 1 + *b;
61 if (*b && *b < sizeof(pass))
62 memcpy(pass, b + 1, *b);
63 pass[*b] = 0;
64 log(3, 0, s, t, "PAP login %s/%s\n", user, pass);
65 }
66 if (session[s].ip || !session[s].radius)
67 {
68 // respond now, either no RADIUS available or already authenticated
69 u8 b[MAXCONTROL];
70 u8 id = p[1];
71 u8 *p = makeppp(b, sizeof(b), 0, 0, t, s, PPPPAP);
72 if (!p) { // Failed to make ppp header!
73 log(1,0,0,0, "Failed to make PPP header in process pap!\n");
74 return;
75 }
76 if (session[s].ip)
77 *p = 2; // ACK
78 else
79 *p = 3; // cant authorise
80 p[1] = id;
81 *(u16 *) (p + 2) = htons(5); // length
82 p[4] = 0; // no message
83 if (session[s].ip)
84 {
85 log(3, session[s].ip, s, t, "%d Already an IP allocated: %s (%d)\n", getpid(), inet_toa(htonl(session[s].ip)), session[s].ip_pool_index);
86 }
87 else
88 {
89 log(1, 0, s, t, "No radius session available to authenticate session...\n");
90 }
91 log(3, 0, s, t, "Fallback response to PAP (%s)\n", (session[s].ip) ? "ACK" : "NAK");
92 tunnelsend(b, 5 + (p - b), t); // send it
93 }
94 else
95 { // set up RADIUS request
96 u16 r = session[s].radius;
97
98 // Run PRE_AUTH plugins
99 struct param_pre_auth packet = { &tunnel[t], &session[s], strdup(user), strdup(pass), PPPPAP, 1 };
100 run_plugins(PLUGIN_PRE_AUTH, &packet);
101 if (!packet.continue_auth)
102 {
103 log(3, 0, s, t, "A plugin rejected PRE_AUTH\n");
104 if (packet.username) free(packet.username);
105 if (packet.password) free(packet.password);
106 return;
107 }
108
109 strncpy(session[s].user, packet.username, sizeof(session[s].user) - 1);
110 strncpy(radius[r].pass, packet.password, sizeof(radius[r].pass) - 1);
111
112 free(packet.username);
113 free(packet.password);
114
115 radius[r].id = p[1];
116 log(3, 0, s, t, "Sending login for %s/%s to radius\n", user, pass);
117 radiussend(r, RADIUSAUTH);
118 }
119 }
120
121 // Process CHAP messages
122 void processchap(tunnelidt t, sessionidt s, u8 * p, u16 l)
123 {
124 u16 r;
125 u16 len;
126
127
128 CSTAT(call_processchap);
129
130 log_hex(5, "CHAP", p, l);
131 r = session[s].radius;
132 if (!r)
133 {
134 log(1, 0, s, t, "Unexpected CHAP message\n");
135
136 // FIXME: Need to drop the session here.
137
138 STAT(tunnel_rx_errors);
139 return;
140 }
141 if (*p != 2)
142 {
143 log(1, 0, s, t, "Unexpected CHAP response code %d\n", *p);
144 STAT(tunnel_rx_errors);
145 return;
146 }
147 if (p[1] != radius[r].id)
148 {
149 log(1, 0, s, t, "Wrong CHAP response ID %d (should be %d) (%d)\n", p[1], radius[r].id, r);
150 STAT(tunnel_rx_errors);
151 return ;
152 }
153 len = ntohs(*(u16 *) (p + 2));
154 if (len > l)
155 {
156 log(1, 0, s, t, "Bad CHAP length %d\n", len);
157 STAT(tunnel_rx_errors);
158 return ;
159 }
160 if (p[4] != 16)
161 {
162 log(1, 0, s, t, "Bad CHAP response length %d\n", p[4]);
163 STAT(tunnel_rx_errors);
164 return ;
165 }
166 if (len - 21 >= sizeof(session[s].user))
167 {
168 log(1, 0, s, t, "CHAP user too long %d\n", len - 21);
169 STAT(tunnel_rx_errors);
170 return ;
171 }
172
173 // Run PRE_AUTH plugins
174 {
175 struct param_pre_auth packet = { &tunnel[t], &session[s], NULL, NULL, PPPCHAP, 1 };
176
177 packet.username = calloc(len-20, 1);
178 packet.password = calloc(16, 1);
179 memcpy(packet.username, p + 21, len - 21);
180 memcpy(packet.password, p + 5, 16);
181
182 run_plugins(PLUGIN_PRE_AUTH, &packet);
183 if (!packet.continue_auth)
184 {
185 log(3, 0, s, t, "A plugin rejected PRE_AUTH\n");
186 if (packet.username) free(packet.username);
187 if (packet.password) free(packet.password);
188 return;
189 }
190
191 strncpy(session[s].user, packet.username, sizeof(session[s].user) - 1);
192 memcpy(radius[r].pass, packet.password, 16);
193
194 free(packet.username);
195 free(packet.password);
196 }
197
198 radius[r].chap = 1;
199 log(3, 0, s, t, "CHAP login %s\n", session[s].user);
200 radiussend(r, RADIUSAUTH);
201 }
202
203 char *ppp_lcp_types[] = {
204 NULL,
205 "ConfigReq",
206 "ConfigAck",
207 "ConfigNak",
208 "ConfigRej",
209 "TerminateReq",
210 "TerminateAck",
211 "CodeRej",
212 "ProtocolRej",
213 "EchoReq",
214 "EchoReply",
215 "DiscardRequest",
216 };
217
218 void dumplcp(u8 *p, int l)
219 {
220 signed int x = l - 4;
221 u8 *o = (p + 4);
222
223 log_hex(5, "PPP LCP Packet", p, l);
224 log(4, 0, 0, 0, "PPP LCP Packet type %d (%s len %d)\n", *p, ppp_lcp_types[(int)*p], ntohs( ((u16 *) p)[1]) );
225 log(4, 0, 0, 0, "Length: %d\n", l);
226 if (*p != ConfigReq && *p != ConfigRej && *p != ConfigAck)
227 return;
228
229 while (x > 2)
230 {
231 int type = o[0];
232 int length = o[1];
233 if (length == 0)
234 {
235 log(4, 0, 0, 0, " Option length is 0...\n");
236 break;
237 }
238 if (type == 0)
239 {
240 log(4, 0, 0, 0, " Option type is 0...\n");
241 x -= length;
242 o += length;
243 continue;
244 }
245 switch (type)
246 {
247 case 1: // Maximum-Receive-Unit
248 log(4, 0, 0, 0, " %s %d\n", lcp_types[type], ntohs(*(u16 *)(o + 2)));
249 break;
250 case 3: // Authentication-Protocol
251 {
252 int proto = ntohs(*(u16 *)(o + 2));
253 log(4, 0, 0, 0, " %s %s\n", lcp_types[type],
254 proto == 0xC223 ? "CHAP" : "PAP");
255 break;
256 }
257 case 4: // Quality-Protocol
258 {
259 u32 qp = ntohl(*(u32 *)(o + 2));
260 log(4, 0, 0, 0, " %s %x\n", lcp_types[type], qp);
261 break;
262 }
263 case 5: // Magic-Number
264 {
265 u32 magicno = ntohl(*(u32 *)(o + 2));
266 log(4, 0, 0, 0, " %s %x\n", lcp_types[type], magicno);
267 break;
268 }
269 case 7: // Protocol-Field-Compression
270 {
271 u32 pfc = ntohl(*(u32 *)(o + 2));
272 log(4, 0, 0, 0, " %s %x\n", lcp_types[type], pfc);
273 break;
274 }
275 case 8: // Address-And-Control-Field-Compression
276 {
277 u32 afc = ntohl(*(u32 *)(o + 2));
278 log(4, 0, 0, 0, " %s %x\n", lcp_types[type], afc);
279 break;
280 }
281 default:
282 log(2, 0, 0, 0, " Unknown PPP LCP Option type %d\n", type);
283 break;
284 }
285 x -= length;
286 o += length;
287 }
288 }
289
290 // Process LCP messages
291 void processlcp(tunnelidt t, sessionidt s, u8 * p, u16 l)
292 {
293 u8 b[MAXCONTROL];
294 u8 *q = NULL;
295
296
297 CSTAT(call_processlcp);
298
299 log_hex(5, "LCP", p, l);
300 if (l < 4)
301 {
302 log(1, session[s].ip, s, t, "Short LCP %d bytes\n", l);
303 STAT(tunnel_rx_errors);
304 return ;
305 }
306 if (*p == ConfigAck)
307 {
308 log(3, session[s].ip, s, t, "LCP: Discarding ConfigAck\n");
309 }
310 else if (*p == ConfigReq)
311 {
312 signed int x = l - 4;
313 u8 *o = (p + 4);
314
315 log(3, session[s].ip, s, t, "LCP: ConfigReq (%d bytes)...\n", l);
316 dumplcp(p, l);
317
318 while (x > 2)
319 {
320 int type = o[0];
321 int length = o[1];
322 if (length == 0 || type == 0) break;
323 switch (type)
324 {
325 case 1: // Maximum-Receive-Unit
326 session[s].mru = ntohs(*(u16 *)(o + 2));
327 break;
328 case 3: // Authentication-Protocol
329 {
330 int proto = ntohs(*(u16 *)(o + 2));
331 if (proto == 0xC223)
332 {
333 log(2, session[s].ip, s, t, " Remote end is trying to do CHAP. Rejecting it.\n");
334
335 if (!q)
336 {
337 q = makeppp(b, sizeof(b), p, l, t, s, PPPLCP);
338 if (!q) {
339 log(2, session[s].ip, s, t, " Failed to send packet.\n");
340 break;
341 }
342 *q++ = ConfigNak;
343 }
344 memcpy(q, o, length);
345 *(u16 *)(q += 2) = htons(0xC023); // NAK -> Use PAP instead
346 q += length;
347 }
348 break;
349 }
350 case 5: // Magic-Number
351 {
352 // u32 magicno = ntohl(*(u32 *)(o + 2));
353 break;
354 }
355 case 4: // Quality-Protocol
356 {
357 // u32 qp = ntohl(*(u32 *)(o + 2));
358 break;
359 }
360 case 7: // Protocol-Field-Compression
361 {
362 // u32 pfc = ntohl(*(u32 *)(o + 2));
363 break;
364 }
365 case 8: // Address-And-Control-Field-Compression
366 {
367 // u32 afc = ntohl(*(u32 *)(o + 2));
368 break;
369 }
370 default:
371 log(2, session[s].ip, s, t, " Unknown PPP LCP Option type %d\n", type);
372 break;
373 }
374 x -= length;
375 o += length;
376 }
377
378 if (!q)
379 {
380 // Send back a ConfigAck
381 log(3, session[s].ip, s, t, "ConfigReq accepted, sending as Ack\n");
382 q = makeppp(b, sizeof(b), p, l, t, s, PPPLCP);
383 if (!q) {
384 log(3, session[s].ip, s, t, " failed to create packet.\n");
385 return;
386 }
387 *q = ConfigAck;
388 tunnelsend(b, l + (q - b), t);
389 }
390 else
391 {
392 // Already built a ConfigNak... send it
393 log(3, session[s].ip, s, t, "Sending ConfigNak\n");
394 tunnelsend(b, l + (q - b), t);
395
396 log(3, session[s].ip, s, t, "Sending ConfigReq, requesting PAP login\n");
397 q = makeppp(b, sizeof(b), NULL, 0, t, s, PPPLCP);
398 *q++ = ConfigReq;
399 *(u8 *)(q++) = 3;
400 *(u8 *)(q++) = 4;
401 *(u16 *)(q += 2) = htons(0xC023);
402 tunnelsend(b, l + (q - b), t);
403 }
404 }
405 else if (*p == ConfigNak)
406 {
407 log(1, session[s].ip, s, t, "Remote end sent a ConfigNak. Ignoring\n");
408 dumplcp(p, l);
409 return ;
410 }
411 else if (*p == TerminateReq)
412 {
413 *p = TerminateAck; // close
414 q = makeppp(b, sizeof(b), p, l, t, s, PPPLCP);
415 if (!q) {
416 log(3, session[s].ip, s, t, "Failed to create PPP packet in processlcp.\n");
417 return;
418 }
419 log(3, session[s].ip, s, t, "LCP: Received TerminateReq. Sending TerminateAck\n");
420 sessionshutdown(s, "Remote end closed connection.");
421 tunnelsend(b, l + (q - b), t); // send it
422 }
423 else if (*p == TerminateAck)
424 {
425 sessionshutdown(s, "Connection closed.");
426 }
427 else if (*p == EchoReq)
428 {
429 *p = EchoReply; // reply
430 *(u32 *) (p + 4) = htonl(session[s].magic); // our magic number
431 q = makeppp(b, sizeof(b), p, l, t, s, PPPLCP);
432 if (!q) {
433 log(3, session[s].ip, s, t, " failed to send EchoReply.\n");
434 return;
435 }
436 log(5, session[s].ip, s, t, "LCP: Received EchoReq. Sending EchoReply\n");
437 tunnelsend(b, l + (q - b), t); // send it
438 }
439 else if (*p == EchoReply)
440 {
441 // Ignore it, last_packet time is set earlier than this.
442 }
443 else
444 {
445 log(1, session[s].ip, s, t, "Unexpected LCP code %d\n", *p);
446 STAT(tunnel_rx_errors);
447 return ;
448 }
449 }
450
451 // Process IPCP messages
452 void processipcp(tunnelidt t, sessionidt s, u8 * p, u16 l)
453 {
454
455 CSTAT(call_processipcp);
456
457 log_hex(5, "IPCP", p, l);
458 if (l < 5)
459 {
460 log(1, 0, s, t, "Short IPCP %d bytes\n", l);
461 STAT(tunnel_rx_errors);
462 return ;
463 }
464 if (*p == ConfigAck)
465 { // happy with our IPCP
466 u16 r = session[s].radius;
467 if ((!r || radius[r].state == RADIUSIPCP) && !session[s].walled_garden) {
468 if (!r)
469 r = radiusnew(s);
470 if (r)
471 radiussend(r, RADIUSSTART); // send radius start, having got IPCP at last
472 }
473 session[s].flags |= SF_IPCP_ACKED;
474
475 return ; // done
476 }
477 if (*p != ConfigReq)
478 {
479 log(1, 0, s, t, "Unexpected IPCP code %d\n", *p);
480 STAT(tunnel_rx_errors);
481 return ;
482 }
483 if (ntohs(*(u16 *) (p + 2)) > l)
484 {
485 log(1, 0, s, t, "Length mismatch IPCP %d/%d\n", ntohs(*(u16 *) (p + 2)), l);
486 STAT(tunnel_rx_errors);
487 return ;
488 }
489 if (!session[s].ip)
490 {
491 log(3, 0, s, t, "Waiting on radius reply\n");
492 return ; // have to wait on RADIUS reply
493 }
494 // form a config reply quoting the IP in the session
495 {
496 u8 b[MAXCONTROL];
497 u8 *i,
498 *q;
499
500 q = p + 4;
501 i = p + l;
502 while (q < i && q[1])
503 {
504 if (*q != 0x81 && *q != 0x83 && *q != 3)
505 break;
506 q += q[1];
507 }
508 if (q < i)
509 { // reject
510 u16 n = 4;
511 i = p + l;
512 q = makeppp(b, sizeof(b), p, l, t, s, PPPIPCP);
513 if (!q) {
514 log(2, 0, s, t, "Failed to send IPCP.\n");
515 return;
516 }
517 *q = ConfigRej;
518 p += 4;
519 while (p < i && p[1])
520 {
521 if (*p != 0x81 && *p != 0x83 && *p != 3)
522 {
523 log(2, 0, s, t, "IPCP reject %d\n", *p);
524 memcpy(q + n, p, p[1]);
525 n += p[1];
526 }
527 p += p[1];
528 }
529 *(u16 *) (q + 2) = htons(n);
530 tunnelsend(b, n + (q - b), t); // send it
531 }
532 else
533 {
534 *p = ConfigAck;
535 i = findppp(p, 0x81); // Primary DNS address
536 if (i)
537 {
538 if (*(u32 *) (i + 2) != htonl(session[s].dns1))
539 {
540 *(u32 *) (i + 2) = htonl(session[s].dns1);
541 *p = ConfigNak;
542 }
543 }
544 i = findppp(p, 0x83); // Secondary DNS address (TBA, is it)
545 if (i)
546 {
547 if (*(u32 *) (i + 2) != htonl(session[s].dns2))
548 {
549 *(u32 *) (i + 2) = htonl(session[s].dns2);
550 *p = ConfigNak;
551 }
552 }
553 i = findppp(p, 3); // IP address
554 if (!i || i[1] != 6)
555 {
556 log(1, 0, s, t, "No IP in IPCP request\n");
557 STAT(tunnel_rx_errors);
558 return ;
559 }
560 if (*(u32 *) (i + 2) != htonl(session[s].ip))
561 {
562 *(u32 *) (i + 2) = htonl(session[s].ip);
563 *p = ConfigNak;
564 }
565 q = makeppp(b, sizeof(b), p, l, t, s, PPPIPCP);
566 if (!q) {
567 log(2, 0, s, t, " Failed to send IPCP packet.\n");
568 return;
569 }
570 tunnelsend(b, l + (q - b), t); // send it
571 }
572 }
573 }
574
575 // process IP packet received
576 //
577 // This MUST be called with at least 4 byte behind 'p'.
578 // (i.e. this routine writes to p[-4]).
579 void processipin(tunnelidt t, sessionidt s, u8 * p, u16 l)
580 {
581 ipt ip;
582
583
584 CSTAT(call_processipin);
585
586 log_hex(5, "IP", p, l);
587
588 ip = ntohl(*(u32 *)(p + 12));
589
590 if (l > MAXETHER)
591 {
592 log(1, ip, s, t, "IP packet too long %d\n", l);
593 STAT(tunnel_rx_errors);
594 return ;
595 }
596
597 // no spoof (do sessionbyip to handled statically routed subnets)
598 if (ip != session[s].ip && sessionbyip(htonl(ip)) != s)
599 {
600 log(5, ip, s, t, "Dropping packet with spoofed IP %s\n", inet_toa(htonl(ip)));
601 return;
602 }
603
604 // Add on the tun header
605 p -= 4;
606 *(u32 *)p = htonl(0x00000800);
607 l += 4;
608
609 if (session[s].tbf_in && !config->cluster_iam_master) { // Are we throttled and a slave?
610 master_throttle_packet(session[s].tbf_in, p, l); // Pass it to the master for handling.
611 return;
612 }
613
614 session[s].cin += l - 4;
615 session[s].total_cin += l - 4;
616 sess_count[s].cin += l - 4;
617
618 session[s].pin++;
619 eth_tx += l - 4;
620
621 if (session[s].snoop_ip && session[s].snoop_port)
622 {
623 // Snooping this session, send it to ASIO
624 snoop_send_packet(p, l, session[s].snoop_ip, session[s].snoop_port);
625 }
626 STAT(tun_tx_packets);
627 INC_STAT(tun_tx_bytes, l);
628
629 if (session[s].tbf_in && config->cluster_iam_master) { // Are we throttled and a master?? actually handle the throttled packets.
630 tbf_queue_packet(session[s].tbf_in, p, l);
631 return;
632 }
633
634 // send to ethernet
635 if (tun_write(p, l) < 0)
636 {
637 STAT(tun_tx_errors);
638 log(0, 0, s, t, "Error writing %d bytes to TUN device: %s (tunfd=%d, p=%p)\n",
639 l, strerror(errno), tunfd, p);
640 }
641
642 }
643
644 //
645 // Helper routine for the TBF filters.
646 // Used to send queued data in from the user.
647 //
648 void send_ipin(sessionidt s, u8 *buf, int len)
649 {
650 log_hex(5, "IP in throttled", buf, len);
651 if (write(tunfd, buf, len) < 0)
652 {
653 STAT(tun_tx_errors);
654 log(0, 0, 0, 0, "Error writing %d bytes to TUN device: %s (tunfd=%d, p=%p)\n",
655 len, strerror(errno), tunfd, buf);
656 }
657
658 // Increment packet counters
659 session[s].cin += len - 4;
660 session[s].total_cin += len - 4;
661 sess_count[s].cin += len - 4;
662
663 session[s].pin++;
664 eth_tx += len - 4;
665 }
666
667
668 // Process LCP messages
669 void processccp(tunnelidt t, sessionidt s, u8 * p, u16 l)
670 {
671
672 CSTAT(call_processccp);
673
674 log_hex(5, "CCP", p, l);
675 if (l < 2 || (*p != ConfigReq && *p != TerminateReq))
676 {
677 log(1, 0, s, t, "Unexpecetd CCP request code %d\n", *p);
678 STAT(tunnel_rx_errors);
679 return ;
680 }
681 // reject
682 {
683 u8 b[MAXCONTROL];
684 u8 *q;
685 if (*p == ConfigReq)
686 {
687 if (l < 6)
688 {
689 *p = ConfigAck; // accept no compression
690 }
691 else
692 {
693 *p = ConfigRej; // reject
694 }
695 }
696 else
697 *p = TerminateAck; // close
698 q = makeppp(b, sizeof(b), p, l, t, s, PPPCCP);
699 if (!q) {
700 log(1,0,0,0, "Failed to send CCP packet.\n");
701 return;
702 }
703 tunnelsend(b, l + (q - b), t); // send it
704 }
705 }
706
707 // send a CHAP PP packet
708 void sendchap(tunnelidt t, sessionidt s)
709 {
710 u8 b[MAXCONTROL];
711 u16 r = session[s].radius;
712 u8 *q;
713
714 CSTAT(call_sendchap);
715
716 if (!r)
717 {
718 log(1, 0, s, t, "No RADIUS to send challenge\n");
719 STAT(tunnel_tx_errors);
720 return ;
721 }
722 log(1, 0, s, t, "Send CHAP challenge\n");
723 { // new challenge
724 int n;
725 for (n = 0; n < 15; n++)
726 radius[r].auth[n] = rand();
727 }
728 radius[r].chap = 1; // CHAP not PAP
729 radius[r].id++;
730 if (radius[r].state != RADIUSCHAP)
731 radius[r].try = 0;
732 radius[r].state = RADIUSCHAP;
733 radius[r].retry = backoff(radius[r].try++);
734 if (radius[r].try > 5)
735 {
736 sessionshutdown(s, "Timeout CHAP");
737 STAT(tunnel_tx_errors);
738 return ;
739 }
740 q = makeppp(b, sizeof(b), 0, 0, t, s, PPPCHAP);
741 if (!q) {
742 log(1, 0, s, t, "failed to send CHAP challenge.\n");
743 return;
744 }
745 *q = 1; // challenhe
746 q[1] = radius[r].id; // ID
747 q[4] = 16; // length
748 memcpy(q + 5, radius[r].auth, 16); // challenge
749 strcpy(q + 21, hostname); // our name
750 *(u16 *) (q + 2) = htons(strlen(hostname) + 21); // length
751 tunnelsend(b, strlen(hostname) + 21 + (q - b), t); // send it
752 }
753
754 // fill in a L2TP message with a PPP frame,
755 // copies existing PPP message and changes magic number if seen
756 // returns start of PPP frame
757 u8 *makeppp(u8 * b, int size, u8 * p, int l, tunnelidt t, sessionidt s, u16 mtype)
758 {
759
760 if (size < 12)
761 return NULL; // Need more space than this!!
762
763 *(u16 *) (b + 0) = htons(0x0002); // L2TP with no options
764 *(u16 *) (b + 2) = htons(tunnel[t].far); // tunnel
765 *(u16 *) (b + 4) = htons(session[s].far); // session
766 b += 6;
767 if (mtype != PPPLCP && !(session[s].l2tp_flags & SESSIONACFC))
768 {
769 *(u16 *) b = htons(0xFF03); // HDLC header
770 b += 2;
771 }
772 if (mtype < 0x100 && session[s].l2tp_flags & SESSIONPFC)
773 *b++ = mtype;
774 else
775 {
776 *(u16 *) b = htons(mtype);
777 b += 2;
778 }
779
780 if (l + 12 > size) {
781 log(3,0,0,0, "Would have overflowed the buffer in makeppp: size %d, len %d.\n", size, l);
782 return NULL; // Run out of room to hold the packet!
783 }
784 if (p && l)
785 memcpy(b, p, l);
786 return b;
787 }
788
789 // find a PPP option, returns point to option, or 0 if not found
790 u8 *findppp(u8 * b, u8 mtype)
791 {
792 u16 l = ntohs(*(u16 *) (b + 2));
793 if (l < 4)
794 return 0;
795 b += 4;
796 l -= 4;
797 while (l)
798 {
799 if (l < b[1] || !b[1])
800 return 0; // faulty
801 if (*b == mtype)
802 return b;
803 l -= b[1];
804 b += b[1];
805 }
806 return 0;
807 }
808
809 // Send initial LCP ConfigReq
810 void initlcp(tunnelidt t, sessionidt s)
811 {
812 char b[500] = {0}, *q;
813
814 q = makeppp(b, sizeof(b), NULL, 0, t, s, PPPLCP);
815 if (!q) {
816 log(1, 0, s, t, "Failed to send LCP ConfigReq.\n");
817 return;
818 }
819 log(4, 0, s, t, "Sending LCP ConfigReq for PAP\n");
820 *q = ConfigReq;
821 *(u8 *)(q + 1) = (time_now % 255) + 1; // ID
822 *(u16 *)(q + 2) = htons(8); // Length
823 *(u8 *)(q + 4) = 3;
824 *(u8 *)(q + 5) = 4;
825 *(u16 *)(q + 6) = htons(0xC023); // PAP
826 tunnelsend(b, 12 + 8, t);
827 }
828