X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/93e40637fa82dd01d06f7af29bd0e8366af3adcc..71f264277463b492bea5dadee35255f837301499:/ppp.c diff --git a/ppp.c b/ppp.c index 4fe4f6a..49f0858 100644 --- a/ppp.c +++ b/ppp.c @@ -1,6 +1,6 @@ // L2TPNS PPP Stuff -char const *cvs_id_ppp = "$Id: ppp.c,v 1.96 2006-02-17 15:05:14 bodea Exp $"; +char const *cvs_id_ppp = "$Id: ppp.c,v 1.99 2006-04-18 06:00:08 bodea Exp $"; #include #include @@ -40,7 +40,7 @@ void processpap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { LOG(1, s, t, "Short PAP %u bytes\n", l); STAT(tunnel_rx_errors); - sessionshutdown(s, "Short PAP packet.", 3, 0); + sessionshutdown(s, "Short PAP packet.", CDN_ADMIN_DISC, TERM_USER_ERROR); return; } @@ -48,7 +48,7 @@ void processpap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { LOG(1, s, t, "Length mismatch PAP %u/%u\n", hl, l); STAT(tunnel_rx_errors); - sessionshutdown(s, "PAP length mismatch.", 3, 0); + sessionshutdown(s, "PAP length mismatch.", CDN_ADMIN_DISC, TERM_USER_ERROR); return; } l = hl; @@ -57,7 +57,7 @@ void processpap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { LOG(1, s, t, "Unexpected PAP code %d\n", *p); STAT(tunnel_rx_errors); - sessionshutdown(s, "Unexpected PAP code.", 3, 0); + sessionshutdown(s, "Unexpected PAP code.", CDN_ADMIN_DISC, TERM_USER_ERROR); return; } @@ -110,7 +110,7 @@ void processpap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) else { LOG(1, s, t, "No RADIUS session available to authenticate session...\n"); - sessionshutdown(s, "No free RADIUS sessions.", 4, 0); + sessionshutdown(s, "No free RADIUS sessions.", CDN_UNAVAILABLE, TERM_SERVICE_UNAVAILABLE); } } else @@ -152,7 +152,7 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { LOG(1, s, t, "Short CHAP %u bytes\n", l); STAT(tunnel_rx_errors); - sessionshutdown(s, "Short CHAP packet.", 3, 0); + sessionshutdown(s, "Short CHAP packet.", CDN_ADMIN_DISC, TERM_USER_ERROR); return; } @@ -160,7 +160,7 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { LOG(1, s, t, "Length mismatch CHAP %u/%u\n", hl, l); STAT(tunnel_rx_errors); - sessionshutdown(s, "CHAP length mismatch.", 3, 0); + sessionshutdown(s, "CHAP length mismatch.", CDN_ADMIN_DISC, TERM_USER_ERROR); return; } l = hl; @@ -169,7 +169,7 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { LOG(1, s, t, "Unexpected CHAP response code %d\n", *p); STAT(tunnel_rx_errors); - sessionshutdown(s, "CHAP length mismatch.", 3, 0); + sessionshutdown(s, "CHAP length mismatch.", CDN_ADMIN_DISC, TERM_USER_ERROR); return; } @@ -190,7 +190,7 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { LOG(1, s, t, "Wrong CHAP response ID %d (should be %d) (%d)\n", p[1], radius[r].id, r); STAT(tunnel_rx_errors); - sessionshutdown(s, "Unexpected CHAP response ID.", 3, 0); + sessionshutdown(s, "Unexpected CHAP response ID.", CDN_ADMIN_DISC, TERM_USER_ERROR); return; } @@ -198,7 +198,7 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { LOG(1, s, t, "Bad CHAP response length %d\n", l < 5 ? -1 : p[4]); STAT(tunnel_rx_errors); - sessionshutdown(s, "Bad CHAP response length.", 3, 0); + sessionshutdown(s, "Bad CHAP response length.", CDN_ADMIN_DISC, TERM_USER_ERROR); return; } @@ -208,7 +208,7 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { LOG(1, s, t, "CHAP user too long %d\n", l - 16); STAT(tunnel_rx_errors); - sessionshutdown(s, "CHAP username too long.", 3, 0); + sessionshutdown(s, "CHAP username too long.", CDN_ADMIN_DISC, TERM_USER_ERROR); return; } @@ -814,7 +814,7 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) default: LOG(2, s, t, "LCP: remote sent %s for type %u?\n", ppp_code(*p), type); - sessionshutdown(s, "Unable to negotiate LCP.", 3, 0); + sessionshutdown(s, "Unable to negotiate LCP.", CDN_ADMIN_DISC, TERM_USER_ERROR); return; } x -= length; @@ -823,7 +823,7 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) if (!authtype) { - sessionshutdown(s, "Unsupported authentication.", 3, 0); + sessionshutdown(s, "Unsupported authentication.", CDN_ADMIN_DISC, TERM_USER_ERROR); return; } @@ -870,7 +870,29 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) } else if (*p == TerminateReq) { - *p = TerminateAck; // close + switch (session[s].ppp.lcp) + { + case Closed: + case Stopped: + case Closing: + case Stopping: + case RequestSent: + case AckReceived: + case AckSent: + break; + + case Opened: + lcp_restart(s); + zero_restart_count(s, lcp); + change_state(s, lcp, Closing); + break; + + default: + LOG(2, s, t, "LCP: ignoring %s in state %s\n", ppp_code(*p), ppp_state(session[s].ppp.lcp)); + return; + } + + *p = TerminateAck; // send ack q = makeppp(b, sizeof(b), p, l, s, t, PPPLCP); if (!q) return; @@ -878,11 +900,6 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) if (config->debug > 3) dumplcp(q, l); tunnelsend(b, l + (q - b), t); // send it - sessionshutdown(s, "Remote end closed connection.", 3, 0); - } - else if (*p == TerminateAck) - { - sessionshutdown(s, "Connection closed.", 3, 0); } else if (*p == ProtocolRej) { @@ -967,7 +984,7 @@ void processipcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) CSTAT(processipcp); LOG_HEX(5, "IPCP", p, l); - if (l < 5) + if (l < 4) { LOG(1, s, t, "Short IPCP %d bytes\n", l); STAT(tunnel_rx_errors); @@ -1039,7 +1056,7 @@ void processipcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) q = ppp_conf_nak(s, b, sizeof(b), PPPIPCP, &response, q, p, o, (uint8_t *) &addr, sizeof(addr)); if (!q || (q != oq && *response == ConfigRej)) { - sessionshutdown(s, "Can't negotiate IPCP.", 3, 0); + sessionshutdown(s, "Can't negotiate IPCP.", CDN_ADMIN_DISC, TERM_USER_ERROR); return; } } @@ -1153,12 +1170,33 @@ void processipcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) } else if (*p == TerminateReq) { - *p = TerminateAck; - q = makeppp(b, sizeof(b), p, l, s, t, PPPIPCP); + switch (session[s].ppp.ipcp) + { + case Closed: + case Stopped: + case Closing: + case Stopping: + case RequestSent: + case AckReceived: + case AckSent: + break; + + case Opened: + zero_restart_count(s, ipcp); + change_state(s, ipcp, Closing); + break; + + default: + LOG(2, s, t, "IPCP: ignoring %s in state %s\n", ppp_code(*p), ppp_state(session[s].ppp.ipcp)); + return; + } + + *p = TerminateAck; // send ack + q = makeppp(b, sizeof(b), p, l, s, t, PPPIPCP); if (!q) return; + LOG(3, s, t, "IPCP: send %s\n", ppp_code(*q)); - tunnelsend(b, l + (q - b), t); - change_state(s, ipcp, Stopped); + tunnelsend(b, l + (q - b), t); // send it } else if (*p != CodeRej) { @@ -1353,12 +1391,33 @@ void processipv6cp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) } else if (*p == TerminateReq) { - *p = TerminateAck; + switch (session[s].ppp.ipv6cp) + { + case Closed: + case Stopped: + case Closing: + case Stopping: + case RequestSent: + case AckReceived: + case AckSent: + break; + + case Opened: + zero_restart_count(s, ipv6cp); + change_state(s, ipv6cp, Closing); + break; + + default: + LOG(2, s, t, "IPV6CP: ignoring %s in state %s\n", ppp_code(*p), ppp_state(session[s].ppp.ipv6cp)); + return; + } + + *p = TerminateAck; // send ack q = makeppp(b, sizeof(b), p, l, s, t, PPPIPV6CP); if (!q) return; + LOG(3, s, t, "IPV6CP: send %s\n", ppp_code(*q)); - tunnelsend(b, l + (q - b), t); - change_state(s, ipv6cp, Stopped); + tunnelsend(b, l + (q - b), t); // send it } else if (*p != CodeRej) { @@ -1757,7 +1816,7 @@ void sendchap(sessionidt s, tunnelidt t) radius[r].retry = backoff(radius[r].try++); if (radius[r].try > 5) { - sessionshutdown(s, "CHAP timeout.", 3, 0); + sessionshutdown(s, "CHAP timeout.", CDN_ADMIN_DISC, TERM_REAUTHENTICATION_FAILURE); STAT(tunnel_tx_errors); return ; }