2 // $Id: ppp.c,v 1.2 2004/03/05 00:09:03 fred_nerk Exp $
10 #include "constants.h"
14 extern tunnelt
*tunnel
;
15 extern sessiont
*session
;
16 extern radiust
*radius
;
18 extern char hostname
[1000];
19 extern struct Tstats
*_statistics
;
20 extern unsigned long eth_tx
;
21 extern time_t time_now
;
22 extern struct configt
*config
;
24 // Process PAP messages
25 void processpap(tunnelidt t
, sessionidt s
, u8
* p
, u16 l
)
31 STAT(call_processpap
);
33 log_hex(5, "PAP", p
, l
);
36 log(1, 0, s
, t
, "Short PAP %u bytes", l
);
37 STAT(tunnel_rx_errors
);
42 log(1, 0, s
, t
, "Unexpected PAP code %d\n", *p
);
43 STAT(tunnel_rx_errors
);
46 if (ntohs(*(u16
*) (p
+ 2)) > l
)
48 log(1, 0, s
, t
, "Length mismatch PAP %d/%d\n", ntohs(*(u16
*) (p
+ 2)), l
);
49 STAT(tunnel_rx_errors
);
55 if (*b
&& *b
< sizeof(user
))
56 memcpy(user
, b
+ 1, *b
);
59 if (*b
&& *b
< sizeof(pass
))
60 memcpy(pass
, b
+ 1, *b
);
62 log(3, 0, s
, t
, "PAP login %s/%s\n", user
, pass
);
64 if (session
[s
].ip
|| !session
[s
].radius
)
66 // respond now, either no RADIUS available or already authenticated
69 u8
*p
= makeppp(b
, 0, 0, t
, s
, PPPPAP
);
73 *p
= 3; // cant authorise
75 *(u16
*) (p
+ 2) = htons(5); // length
76 p
[4] = 0; // no message
79 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
);
83 log(1, 0, s
, t
, "No radius session available to authenticate session...\n");
85 log(3, 0, s
, t
, "Fallback response to PAP (%s)\n", (session
[s
].ip
) ? "ACK" : "NAK");
86 tunnelsend(b
, 5 + (p
- b
), t
); // send it
89 { // set up RADIUS request
90 u8 r
= session
[s
].radius
;
92 // Run PRE_AUTH plugins
93 struct param_pre_auth packet
= { &tunnel
[t
], &session
[s
], strdup(user
), strdup(pass
), PPPPAP
, 1 };
94 run_plugins(PLUGIN_PRE_AUTH
, &packet
);
95 if (!packet
.continue_auth
)
97 log(3, 0, s
, t
, "A plugin rejected PRE_AUTH\n");
98 if (packet
.username
) free(packet
.username
);
99 if (packet
.password
) free(packet
.password
);
103 strncpy(session
[s
].user
, packet
.username
, sizeof(session
[s
].user
) - 1);
104 strncpy(radius
[r
].pass
, packet
.password
, sizeof(radius
[r
].pass
) - 1);
106 free(packet
.username
);
107 free(packet
.password
);
110 log(3, 0, s
, t
, "Sending login for %s/%s to radius\n", user
, pass
);
111 radiussend(r
, RADIUSAUTH
);
115 // Process CHAP messages
116 void processchap(tunnelidt t
, sessionidt s
, u8
* p
, u16 l
)
122 STAT(call_processchap
);
124 log_hex(5, "CHAP", p
, l
);
125 r
= session
[s
].radius
;
128 log(1, 0, s
, t
, "Unexpected CHAP message\n");
129 STAT(tunnel_rx_errors
);
134 log(1, 0, s
, t
, "Unexpected CHAP response code %d\n", *p
);
135 STAT(tunnel_rx_errors
);
138 if (p
[1] != radius
[r
].id
)
140 log(1, 0, s
, t
, "Wrong CHAP response ID %d (should be %d) (%d)\n", p
[1], radius
[r
].id
, r
);
141 STAT(tunnel_rx_errors
);
144 len
= ntohs(*(u16
*) (p
+ 2));
147 log(1, 0, s
, t
, "Bad CHAP length %d\n", len
);
148 STAT(tunnel_rx_errors
);
153 log(1, 0, s
, t
, "Bad CHAP response length %d\n", p
[4]);
154 STAT(tunnel_rx_errors
);
157 if (len
- 21 >= sizeof(session
[s
].user
))
159 log(1, 0, s
, t
, "CHAP user too long %d\n", len
- 21);
160 STAT(tunnel_rx_errors
);
164 // Run PRE_AUTH plugins
166 struct param_pre_auth packet
= { &tunnel
[t
], &session
[s
], NULL
, NULL
, PPPCHAP
, 1 };
168 packet
.username
= calloc(len
-20, 1);
169 packet
.password
= calloc(16, 1);
170 memcpy(packet
.username
, p
+ 21, len
- 21);
171 memcpy(packet
.password
, p
+ 5, 16);
173 run_plugins(PLUGIN_PRE_AUTH
, &packet
);
174 if (!packet
.continue_auth
)
176 log(3, 0, s
, t
, "A plugin rejected PRE_AUTH\n");
177 if (packet
.username
) free(packet
.username
);
178 if (packet
.password
) free(packet
.password
);
182 strncpy(session
[s
].user
, packet
.username
, sizeof(session
[s
].user
) - 1);
183 memcpy(radius
[r
].pass
, packet
.password
, 16);
185 free(packet
.username
);
186 free(packet
.password
);
190 radiussend(r
, RADIUSAUTH
);
191 log(3, 0, s
, t
, "CHAP login %s\n", session
[s
].user
);
194 char *ppp_lcp_types
[] = {
209 void dumplcp(char *p
, int l
)
211 signed int x
= l
- 3;
214 log_hex(5, "PPP LCP Packet", p
, l
);
215 log(4, 0, 0, 0, "PPP LCP Packet type %d (%s)\n", *p
, ppp_lcp_types
[(int)*p
]);
216 log(4, 0, 0, 0, "Length: %d\n", l
);
217 if (*p
!= ConfigReq
&& *p
!= ConfigRej
&& *p
!= ConfigAck
)
222 int type
= *(u8
*)(o
);
223 int length
= *(u8
*)(o
+ 1);
226 log(4, 0, 0, 0, " Option length is 0...\n");
231 log(4, 0, 0, 0, " Option type is 0...\n");
238 case 1: // Maximum-Receive-Unit
239 log(4, 0, 0, 0, " %s %d\n", lcp_types
[type
], ntohs(*(u16
*)(o
+ 2)));
241 case 3: // Authentication-Protocol
243 int proto
= ntohs(*(u16
*)(o
+ 2));
244 log(4, 0, 0, 0, " %s %s\n", lcp_types
[type
],
245 proto
== 0xC223 ? "CHAP" : "PAP");
248 case 5: // Magic-Number
250 u32 magicno
= ntohl(*(u32
*)(o
+ 2));
251 log(4, 0, 0, 0, " %s %x\n", lcp_types
[type
], magicno
);
254 case 4: // Quality-Protocol
256 u32 qp
= ntohl(*(u32
*)(o
+ 2));
257 log(4, 0, 0, 0, " %s %x\n", lcp_types
[type
], qp
);
260 case 7: // Protocol-Field-Compression
262 u32 pfc
= ntohl(*(u32
*)(o
+ 2));
263 log(4, 0, 0, 0, " %s %x\n", lcp_types
[type
], pfc
);
266 case 8: // Address-And-Control-Field-Compression
268 u32 afc
= ntohl(*(u32
*)(o
+ 2));
269 log(4, 0, 0, 0, " %s %x\n", lcp_types
[type
], afc
);
273 log(2, 0, 0, 0, " Unknown PPP LCP Option type %d\n", type
);
281 // Process LCP messages
282 void processlcp(tunnelidt t
, sessionidt s
, u8
* p
, u16 l
)
288 STAT(call_processlcp
);
290 log_hex(5, "LCP", p
, l
);
293 log(1, session
[s
].ip
, s
, t
, "Short LCP %d bytes", l
);
294 STAT(tunnel_rx_errors
);
299 log(3, session
[s
].ip
, s
, t
, "LCP: Discarding ConfigAck\n");
301 else if (*p
== ConfigReq
)
303 signed int x
= l
- 1;
306 log(3, session
[s
].ip
, s
, t
, "LCP: ConfigReq (%d bytes)...\n", l
);
310 int type
= *(u8
*)(o
);
311 int length
= *(u8
*)(o
+ 1);
312 if (length
== 0 || type
== 0) break;
315 case 1: // Maximum-Receive-Unit
316 session
[s
].mru
= ntohs(*(u16
*)(o
+ 2));
318 case 3: // Authentication-Protocol
320 int proto
= ntohs(*(u16
*)(o
+ 2));
323 log(2, session
[s
].ip
, s
, t
, " Remote end is trying to do CHAP. Rejecting it.\n");
327 q
= makeppp(b
, p
, l
, t
, s
, PPPLCP
);
330 memcpy(q
, o
, length
);
331 *(u16
*)(q
+= 2) = htons(0xC023); // NAK -> Use PAP instead
336 case 5: // Magic-Number
338 // u32 magicno = ntohl(*(u32 *)(o + 2));
341 case 4: // Quality-Protocol
343 // u32 qp = ntohl(*(u32 *)(o + 2));
346 case 7: // Protocol-Field-Compression
348 // u32 pfc = ntohl(*(u32 *)(o + 2));
351 case 8: // Address-And-Control-Field-Compression
353 // u32 afc = ntohl(*(u32 *)(o + 2));
357 log(2, session
[s
].ip
, s
, t
, " Unknown PPP LCP Option type %d\n", type
);
366 // Send back a ConfigAck
367 log(3, session
[s
].ip
, s
, t
, "ConfigReq accepted, sending as Ack\n");
368 q
= makeppp(b
, p
, l
, t
, s
, PPPLCP
);
370 tunnelsend(b
, l
+ (q
- b
), t
);
374 // Already built a ConfigNak... send it
375 log(3, session
[s
].ip
, s
, t
, "Sending ConfigNak\n");
376 tunnelsend(b
, l
+ (q
- b
), t
);
378 log(3, session
[s
].ip
, s
, t
, "Sending ConfigReq, requesting PAP login\n");
379 q
= makeppp(b
, NULL
, 0, t
, s
, PPPLCP
);
383 *(u16
*)(q
+= 2) = htons(0xC023);
384 tunnelsend(b
, l
+ (q
- b
), t
);
387 else if (*p
== ConfigNak
)
389 log(1, session
[s
].ip
, s
, t
, "Remote end sent a ConfigNak. Ignoring\n");
393 else if (*p
== TerminateReq
)
395 *p
= TerminateAck
; // close
396 q
= makeppp(b
, p
, l
, t
, s
, PPPLCP
);
397 log(3, session
[s
].ip
, s
, t
, "LCP: Received TerminateReq. Sending TerminateAck\n");
398 sessionshutdown(s
, "Remote end closed connection.");
399 tunnelsend(b
, l
+ (q
- b
), t
); // send it
401 else if (*p
== TerminateReq
)
403 sessionshutdown(s
, "Remote end closed connection.");
405 else if (*p
== EchoReq
)
407 *p
= EchoReply
; // reply
408 *(u32
*) (p
+ 4) = htonl(session
[s
].magic
); // our magic number
409 q
= makeppp(b
, p
, l
, t
, s
, PPPLCP
);
410 log(4, session
[s
].ip
, s
, t
, "LCP: Received EchoReq. Sending EchoReply\n");
411 tunnelsend(b
, l
+ (q
- b
), t
); // send it
413 else if (*p
== EchoReply
)
415 // Ignore it, last_packet time is set earlier than this.
419 log(1, session
[s
].ip
, s
, t
, "Unexpected LCP code %d\n", *p
);
420 STAT(tunnel_rx_errors
);
425 // Process IPCP messages
426 void processipcp(tunnelidt t
, sessionidt s
, u8
* p
, u16 l
)
429 STAT(call_processipcp
);
431 log_hex(5, "IPCP", p
, l
);
434 log(1, 0, s
, t
, "Short IPCP %d bytes", l
);
435 STAT(tunnel_rx_errors
);
439 { // happy with our IPCP
440 u8 r
= session
[s
].radius
;
441 if ((!r
|| radius
[r
].state
== RADIUSIPCP
) && !session
[s
].servicenet
)
445 radiussend(r
, RADIUSSTART
); // send radius start, having got IPCP at last
450 log(1, 0, s
, t
, "Unexpected IPCP code %d\n", *p
);
451 STAT(tunnel_rx_errors
);
454 if (ntohs(*(u16
*) (p
+ 2)) > l
)
456 log(1, 0, s
, t
, "Length mismatch IPCP %d/%d\n", ntohs(*(u16
*) (p
+ 2)), l
);
457 STAT(tunnel_rx_errors
);
462 log(3, 0, s
, t
, "Waiting on radius reply\n");
463 return ; // have to wait on RADIUS eply
465 // form a config reply quoting the IP in the session
473 while (q
< i
&& q
[1])
475 if (*q
!= 0x81 && *q
!= 0x83 && *q
!= 3)
483 q
= makeppp(b
, p
, l
, t
, s
, PPPIPCP
);
486 while (p
< i
&& p
[1])
488 if (*p
!= 0x81 && *p
!= 0x83 && *p
!= 3)
490 log(2, 0, s
, t
, "IPCP reject %d\n", *p
);
491 memcpy(q
+ n
, p
, p
[1]);
496 *(u16
*) (q
+ 2) = htons(n
);
497 tunnelsend(b
, n
+ (q
- b
), t
); // send it
502 i
= findppp(p
, 0x81); // Primary DNS address
505 if (*(u32
*) (i
+ 2) != htonl(session
[s
].dns1
))
507 *(u32
*) (i
+ 2) = htonl(session
[s
].dns1
);
511 i
= findppp(p
, 0x83); // Secondary DNS address (TBA, is it)
514 if (*(u32
*) (i
+ 2) != htonl(session
[s
].dns2
))
516 *(u32
*) (i
+ 2) = htonl(session
[s
].dns2
);
520 i
= findppp(p
, 3); // IP address
523 log(1, 0, s
, t
, "No IP in IPCP request\n");
524 STAT(tunnel_rx_errors
);
527 if (*(u32
*) (i
+ 2) != htonl(session
[s
].ip
))
529 *(u32
*) (i
+ 2) = htonl(session
[s
].ip
);
532 q
= makeppp(b
, p
, l
, t
, s
, PPPIPCP
);
533 tunnelsend(b
, l
+ (q
- b
), t
); // send it
538 // process IP packet received
539 void processipin(tunnelidt t
, sessionidt s
, u8
* p
, u16 l
)
542 STAT(call_processipin
);
544 log_hex(5, "IP", p
, l
);
548 log(1, *(u32
*)(p
+ 12), s
, t
, "IP packet too long %d\n", l
);
549 STAT(tunnel_rx_errors
);
554 session
[s
].total_cin
+= l
;
558 // Add on the tun header
560 *(u32
*)p
= htonl(0x00000800);
565 struct param_packet_rx packet
= { &tunnel
[t
], &session
[s
], p
, l
};
566 run_plugins(PLUGIN_PACKET_TX
, &packet
);
570 if (write(tapfd
, p
, l
) < 0)
573 log(0, 0, s
, t
, "Error writing %d bytes to TAP device: %s (tapfd=%d, p=%p)\n",
574 l
, strerror(errno
), tapfd
, p
);
577 if (session
[s
].snoop
)
579 // Snooping this session, send it to ASIO
580 snoop_send_packet(p
, l
);
582 STAT(tap_tx_packets
);
583 INC_STAT(tap_tx_bytes
, l
);
586 // Process LCP messages
587 void processccp(tunnelidt t
, sessionidt s
, u8
* p
, u16 l
)
590 STAT(call_processccp
);
592 log_hex(5, "CCP", p
, l
);
593 if (l
< 2 || (*p
!= ConfigReq
&& *p
!= TerminateReq
))
595 log(1, 0, s
, t
, "Unexpecetd CCP request code %d\n", *p
);
596 STAT(tunnel_rx_errors
);
607 *p
= ConfigAck
; // accept no compression
611 *p
= ConfigRej
; // reject
615 *p
= TerminateAck
; // close
616 q
= makeppp(b
, p
, l
, t
, s
, PPPCCP
);
617 tunnelsend(b
, l
+ (q
- b
), t
); // send it
621 // send a CHAP PP packet
622 void sendchap(tunnelidt t
, sessionidt s
)
625 u8 r
= session
[s
].radius
;
632 log(1, 0, s
, t
, "No RADIUS to send challenge\n");
633 STAT(tunnel_tx_errors
);
636 log(1, 0, s
, t
, "Send CHAP challenge\n");
639 for (n
= 0; n
< 15; n
++)
640 radius
[r
].auth
[n
] = rand();
642 radius
[r
].chap
= 1; // CHAP not PAP
644 if (radius
[r
].state
!= RADIUSCHAP
)
646 radius
[r
].state
= RADIUSCHAP
;
647 radius
[r
].retry
= backoff(radius
[r
].try++);
648 if (radius
[r
].try > 5)
650 sessionshutdown(s
, "Timeout CHAP");
651 STAT(tunnel_tx_errors
);
654 q
= makeppp(b
, 0, 0, t
, s
, PPPCHAP
);
656 q
[1] = radius
[r
].id
; // ID
658 memcpy(q
+ 5, radius
[r
].auth
, 16); // challenge
659 strcpy(q
+ 21, hostname
); // our name
660 *(u16
*) (q
+ 2) = htons(strlen(hostname
) + 21); // length
661 tunnelsend(b
, strlen(hostname
) + 21 + (q
- b
), t
); // send it
664 // fill in a L2TP message with a PPP frame,
665 // copies existing PPP message and changes magic number if seen
666 // returns start of PPP frame
667 u8
*makeppp(u8
* b
, u8
* p
, int l
, tunnelidt t
, sessionidt s
, u16 mtype
)
669 *(u16
*) (b
+ 0) = htons(0x0002); // L2TP with no options
670 *(u16
*) (b
+ 2) = htons(tunnel
[t
].far
); // tunnel
671 *(u16
*) (b
+ 4) = htons(session
[s
].far
); // session
673 if (mtype
!= PPPLCP
&& !(session
[s
].flags
& SESSIONACFC
))
675 *(u16
*) b
= htons(0xFF03); // HDLC header
678 if (mtype
< 0x100 && session
[s
].flags
& SESSIONPFC
)
682 *(u16
*) b
= htons(mtype
);
690 // find a PPP option, returns point to option, or 0 if not found
691 u8
*findppp(u8
* b
, u8 mtype
)
693 u16 l
= ntohs(*(u16
*) (b
+ 2));
700 if (l
< b
[1] || !b
[1])
710 // Send initial LCP ConfigReq
711 void initlcp(tunnelidt t
, sessionidt s
)
713 char b
[500] = {0}, *q
;
715 q
= makeppp(b
, NULL
, 0, t
, s
, PPPLCP
);
716 log(4, 0, s
, t
, "Sending LCP ConfigReq for PAP\n");
718 *(u8
*)(q
+ 1) = (time_now
% 255) + 1; // ID
719 *(u16
*)(q
+ 2) = htons(8); // Length
722 *(u16
*)(q
+ 6) = htons(0xC023); // PAP
723 tunnelsend(b
, 12 + 8, t
);