3cc73c284fd5b85c4705f2bb0f28d9c14c52e2bb
2 // $Id: ppp.c,v 1.1 2003/12/16 07:07:39 fred_nerk Exp $
10 #include "constants.h"
15 extern tunnelt
*tunnel
;
16 extern sessiont
*session
;
17 extern radiust
*radius
;
20 extern char hostname
[1000];
21 extern struct Tstats
*_statistics
;
22 extern unsigned long eth_tx
;
23 extern time_t time_now
;
25 // Process PAP messages
26 void processpap(tunnelidt t
, sessionidt s
, u8
* p
, u16 l
)
32 STAT(call_processpap
);
34 log_hex(5, "PAP", p
, l
);
37 log(1, 0, s
, t
, "Short PAP %u bytes", l
);
38 STAT(tunnel_rx_errors
);
43 log(1, 0, s
, t
, "Unexpected PAP code %d\n", *p
);
44 STAT(tunnel_rx_errors
);
47 if (ntohs(*(u16
*) (p
+ 2)) > l
)
49 log(1, 0, s
, t
, "Length mismatch PAP %d/%d\n", ntohs(*(u16
*) (p
+ 2)), l
);
50 STAT(tunnel_rx_errors
);
56 if (*b
&& *b
< sizeof(user
))
57 memcpy(user
, b
+ 1, *b
);
60 if (*b
&& *b
< sizeof(pass
))
61 memcpy(pass
, b
+ 1, *b
);
63 log(3, 0, s
, t
, "PAP login %s/%s\n", user
, pass
);
65 if (session
[s
].ip
|| !session
[s
].radius
)
67 // respond now, either no RADIUS available or already authenticated
70 u8
*p
= makeppp(b
, 0, 0, t
, s
, PPPPAP
);
74 *p
= 3; // cant authorise
76 *(u16
*) (p
+ 2) = htons(5); // length
77 p
[4] = 0; // no message
80 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
);
84 log(1, 0, s
, t
, "No radius session available to authenticate session...\n");
86 log(3, 0, s
, t
, "Fallback response to PAP (%s)\n", (session
[s
].ip
) ? "ACK" : "NAK");
87 tunnelsend(b
, 5 + (p
- b
), t
); // send it
90 { // set up RADIUS request
91 u8 r
= session
[s
].radius
;
93 // Run PRE_AUTH plugins
94 struct param_pre_auth packet
= { &tunnel
[t
], &session
[s
], strdup(user
), strdup(pass
), PPPPAP
, 1 };
95 run_plugins(PLUGIN_PRE_AUTH
, &packet
);
96 if (!packet
.continue_auth
)
98 log(3, 0, s
, t
, "A plugin rejected PRE_AUTH\n");
99 if (packet
.username
) free(packet
.username
);
100 if (packet
.password
) free(packet
.password
);
104 strncpy(session
[s
].user
, packet
.username
, sizeof(session
[s
].user
));
105 strncpy(radius
[r
].pass
, packet
.password
, sizeof(radius
[r
].pass
));
107 free(packet
.username
);
108 free(packet
.password
);
111 log(3, 0, s
, t
, "Sending login for %s/%s to radius\n", user
, pass
);
112 radiussend(r
, RADIUSAUTH
);
116 // Process CHAP messages
117 void processchap(tunnelidt t
, sessionidt s
, u8
* p
, u16 l
)
123 STAT(call_processchap
);
125 log_hex(5, "CHAP", p
, l
);
126 r
= session
[s
].radius
;
129 log(1, 0, s
, t
, "Unexpected CHAP message\n");
130 STAT(tunnel_rx_errors
);
135 log(1, 0, s
, t
, "Unexpected CHAP response code %d\n", *p
);
136 STAT(tunnel_rx_errors
);
139 if (p
[1] != radius
[r
].id
)
141 log(1, 0, s
, t
, "Wrong CHAP response ID %d (should be %d) (%d)\n", p
[1], radius
[r
].id
, r
);
142 STAT(tunnel_rx_errors
);
145 len
= ntohs(*(u16
*) (p
+ 2));
148 log(1, 0, s
, t
, "Bad CHAP length %d\n", len
);
149 STAT(tunnel_rx_errors
);
154 log(1, 0, s
, t
, "Bad CHAP response length %d\n", p
[4]);
155 STAT(tunnel_rx_errors
);
158 if (len
- 21 >= sizeof(session
[s
].user
))
160 log(1, 0, s
, t
, "CHAP user too long %d\n", len
- 21);
161 STAT(tunnel_rx_errors
);
165 // Run PRE_AUTH plugins
167 struct param_pre_auth packet
= { &tunnel
[t
], &session
[s
], NULL
, NULL
, PPPCHAP
, 1 };
169 packet
.username
= calloc(len
-20, 1);
170 packet
.password
= calloc(16, 1);
171 memcpy(packet
.username
, p
+ 21, len
- 21);
172 memcpy(packet
.password
, p
+ 5, 16);
174 run_plugins(PLUGIN_PRE_AUTH
, &packet
);
175 if (!packet
.continue_auth
)
177 log(3, 0, s
, t
, "A plugin rejected PRE_AUTH\n");
178 if (packet
.username
) free(packet
.username
);
179 if (packet
.password
) free(packet
.password
);
183 strncpy(session
[s
].user
, packet
.username
, sizeof(session
[s
].user
));
184 memcpy(radius
[r
].pass
, packet
.password
, 16);
186 free(packet
.username
);
187 free(packet
.password
);
191 radiussend(r
, RADIUSAUTH
);
192 log(3, 0, s
, t
, "CHAP login %s\n", session
[s
].user
);
195 char *ppp_lcp_types
[] = {
210 void dumplcp(char *p
, int l
)
212 signed int x
= l
- 3;
215 log_hex(5, "PPP LCP Packet", p
, l
);
216 log(4, 0, 0, 0, "PPP LCP Packet type %d (%s)\n", *p
, ppp_lcp_types
[(int)*p
]);
217 log(4, 0, 0, 0, "Length: %d\n", l
);
218 if (*p
!= ConfigReq
&& *p
!= ConfigRej
&& *p
!= ConfigAck
)
223 int type
= *(u8
*)(o
);
224 int length
= *(u8
*)(o
+ 1);
227 log(4, 0, 0, 0, " Option length is 0...\n");
232 log(4, 0, 0, 0, " Option type is 0...\n");
239 case 1: // Maximum-Receive-Unit
240 log(4, 0, 0, 0, " %s %d\n", lcp_types
[type
], ntohs(*(u16
*)(o
+ 2)));
242 case 3: // Authentication-Protocol
244 int proto
= ntohs(*(u16
*)(o
+ 2));
245 log(4, 0, 0, 0, " %s %s\n", lcp_types
[type
],
246 proto
== 0xC223 ? "CHAP" : "PAP");
249 case 5: // Magic-Number
251 u32 magicno
= ntohl(*(u32
*)(o
+ 2));
252 log(4, 0, 0, 0, " %s %x\n", lcp_types
[type
], magicno
);
255 case 4: // Quality-Protocol
257 u32 qp
= ntohl(*(u32
*)(o
+ 2));
258 log(4, 0, 0, 0, " %s %x\n", lcp_types
[type
], qp
);
261 case 7: // Protocol-Field-Compression
263 u32 pfc
= ntohl(*(u32
*)(o
+ 2));
264 log(4, 0, 0, 0, " %s %x\n", lcp_types
[type
], pfc
);
267 case 8: // Address-And-Control-Field-Compression
269 u32 afc
= ntohl(*(u32
*)(o
+ 2));
270 log(4, 0, 0, 0, " %s %x\n", lcp_types
[type
], afc
);
274 log(2, 0, 0, 0, " Unknown PPP LCP Option type %d\n", type
);
282 // Process LCP messages
283 void processlcp(tunnelidt t
, sessionidt s
, u8
* p
, u16 l
)
289 STAT(call_processlcp
);
291 log_hex(5, "LCP", p
, l
);
294 log(1, session
[s
].ip
, s
, t
, "Short LCP %d bytes", l
);
295 STAT(tunnel_rx_errors
);
300 log(3, session
[s
].ip
, s
, t
, "LCP: Discarding ConfigAck\n");
302 else if (*p
== ConfigReq
)
304 signed int x
= l
- 1;
307 log(3, session
[s
].ip
, s
, t
, "LCP: ConfigReq (%d bytes)...\n", l
);
311 int type
= *(u8
*)(o
);
312 int length
= *(u8
*)(o
+ 1);
313 if (length
== 0 || type
== 0) break;
316 case 1: // Maximum-Receive-Unit
317 session
[s
].mru
= ntohs(*(u16
*)(o
+ 2));
319 case 3: // Authentication-Protocol
321 int proto
= ntohs(*(u16
*)(o
+ 2));
324 log(2, session
[s
].ip
, s
, t
, " Remote end is trying to do CHAP. Rejecting it.\n");
328 q
= makeppp(b
, p
, l
, t
, s
, PPPLCP
);
331 memcpy(q
, o
, length
);
332 *(u16
*)(q
+= 2) = htons(0xC023); // NAK -> Use PAP instead
337 case 5: // Magic-Number
339 // u32 magicno = ntohl(*(u32 *)(o + 2));
342 case 4: // Quality-Protocol
344 // u32 qp = ntohl(*(u32 *)(o + 2));
347 case 7: // Protocol-Field-Compression
349 // u32 pfc = ntohl(*(u32 *)(o + 2));
352 case 8: // Address-And-Control-Field-Compression
354 // u32 afc = ntohl(*(u32 *)(o + 2));
358 log(2, session
[s
].ip
, s
, t
, " Unknown PPP LCP Option type %d\n", type
);
367 // Send back a ConfigAck
368 log(3, session
[s
].ip
, s
, t
, "ConfigReq accepted, sending as Ack\n");
369 q
= makeppp(b
, p
, l
, t
, s
, PPPLCP
);
371 tunnelsend(b
, l
+ (q
- b
), t
);
375 // Already built a ConfigNak... send it
376 log(3, session
[s
].ip
, s
, t
, "Sending ConfigNak\n");
377 tunnelsend(b
, l
+ (q
- b
), t
);
379 log(3, session
[s
].ip
, s
, t
, "Sending ConfigReq, requesting PAP login\n");
380 q
= makeppp(b
, NULL
, 0, t
, s
, PPPLCP
);
384 *(u16
*)(q
+= 2) = htons(0xC023);
385 tunnelsend(b
, l
+ (q
- b
), t
);
388 else if (*p
== ConfigNak
)
390 log(1, session
[s
].ip
, s
, t
, "Remote end sent a ConfigNak. Ignoring\n");
394 else if (*p
== TerminateReq
)
396 *p
= TerminateAck
; // close
397 q
= makeppp(b
, p
, l
, t
, s
, PPPLCP
);
398 log(3, session
[s
].ip
, s
, t
, "LCP: Received TerminateReq. Sending TerminateAck\n");
399 sessionshutdown(s
, "Remote end closed connection.");
400 tunnelsend(b
, l
+ (q
- b
), t
); // send it
402 else if (*p
== TerminateReq
)
404 sessionshutdown(s
, "Remote end closed connection.");
406 else if (*p
== EchoReq
)
408 *p
= EchoReply
; // reply
409 *(u32
*) (p
+ 4) = htonl(session
[s
].magic
); // our magic number
410 q
= makeppp(b
, p
, l
, t
, s
, PPPLCP
);
411 log(3, session
[s
].ip
, s
, t
, "LCP: Received EchoReq. Sending EchoReply\n");
412 tunnelsend(b
, l
+ (q
- b
), t
); // send it
414 else if (*p
== EchoReply
)
416 // Ignore it, last_packet time is set earlier than this.
420 log(1, session
[s
].ip
, s
, t
, "Unexpected LCP code %d\n", *p
);
421 STAT(tunnel_rx_errors
);
426 // Process IPCP messages
427 void processipcp(tunnelidt t
, sessionidt s
, u8
* p
, u16 l
)
430 STAT(call_processipcp
);
432 log_hex(5, "IPCP", p
, l
);
435 log(1, 0, s
, t
, "Short IPCP %d bytes", l
);
436 STAT(tunnel_rx_errors
);
440 { // happy with our IPCP
441 u8 r
= session
[s
].radius
;
442 if ((!r
|| radius
[r
].state
== RADIUSIPCP
) && !session
[s
].walled_garden
)
446 radiussend(r
, RADIUSSTART
); // send radius start, having got IPCP at last
451 log(1, 0, s
, t
, "Unexpected IPCP code %d\n", *p
);
452 STAT(tunnel_rx_errors
);
455 if (ntohs(*(u16
*) (p
+ 2)) > l
)
457 log(1, 0, s
, t
, "Length mismatch IPCP %d/%d\n", ntohs(*(u16
*) (p
+ 2)), l
);
458 STAT(tunnel_rx_errors
);
463 log(3, 0, s
, t
, "Waiting on radius reply\n");
464 return ; // have to wait on RADIUS eply
466 // form a config reply quoting the IP in the session
474 while (q
< i
&& q
[1])
476 if (*q
!= 0x81 && *q
!= 0x83 && *q
!= 3)
484 q
= makeppp(b
, p
, l
, t
, s
, PPPIPCP
);
487 while (p
< i
&& p
[1])
489 if (*p
!= 0x81 && *p
!= 0x83 && *p
!= 3)
491 log(2, 0, s
, t
, "IPCP reject %d\n", *p
);
492 memcpy(q
+ n
, p
, p
[1]);
497 *(u16
*) (q
+ 2) = htons(n
);
498 tunnelsend(b
, n
+ (q
- b
), t
); // send it
503 i
= findppp(p
, 0x81); // Primary DNS address
506 if (*(u32
*) (i
+ 2) != htonl(session
[s
].dns1
))
508 *(u32
*) (i
+ 2) = htonl(session
[s
].dns1
);
512 i
= findppp(p
, 0x83); // Secondary DNS address (TBA, is it)
515 if (*(u32
*) (i
+ 2) != htonl(session
[s
].dns2
))
517 *(u32
*) (i
+ 2) = htonl(session
[s
].dns2
);
521 i
= findppp(p
, 3); // IP address
524 log(1, 0, s
, t
, "No IP in IPCP request\n");
525 STAT(tunnel_rx_errors
);
528 if (*(u32
*) (i
+ 2) != htonl(session
[s
].ip
))
530 *(u32
*) (i
+ 2) = htonl(session
[s
].ip
);
533 q
= makeppp(b
, p
, l
, t
, s
, PPPIPCP
);
534 tunnelsend(b
, l
+ (q
- b
), t
); // send it
539 // process IP packet received
540 void processipin(tunnelidt t
, sessionidt s
, u8
* p
, u16 l
)
543 STAT(call_processipin
);
545 log_hex(5, "IP", p
, l
);
549 log(1, *(u32
*)(p
+ 12), s
, t
, "IP packet too long %d\n", l
);
550 STAT(tunnel_rx_errors
);
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
);