handle rejection of MRU negotiation by peer
authorBrendan O'Dea <bod@optus.net>
Mon, 29 Aug 2005 06:17:53 +0000 (06:17 +0000)
committerBrendan O'Dea <bod@optus.net>
Mon, 29 Aug 2005 06:17:53 +0000 (06:17 +0000)
Changes
l2tpns.c
l2tpns.h
ppp.c

diff --git a/Changes b/Changes
index d54c990..8144831 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,6 +1,7 @@
 * Mon Aug 29 2005 Brendan O'Dea <bod@optus.net> 2.1.4
 - Drop level of "Unexpected CHAP message" log.
 - Fix parsing of ProtocolRej (allow 1 or two byte protocols).
+- Handle rejection of MRU negotiation by peer.
 
 * Wed Aug 17 2005 Brendan O'Dea <bod@optus.net> 2.1.3
 - Fail IPCP negotiation only on ConfigRej of IP-Address.
index 25808d8..55f53dc 100644 (file)
--- a/l2tpns.c
+++ b/l2tpns.c
@@ -4,7 +4,7 @@
 // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
 // vim: sw=8 ts=8
 
-char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.123 2005-08-12 08:35:16 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.124 2005-08-29 06:17:53 bodea Exp $";
 
 #include <arpa/inet.h>
 #include <assert.h>
@@ -2378,15 +2378,16 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
                                        if (amagic == 0) amagic = time_now;
                                        session[s].magic = amagic; // set magic number
                                        session[s].l2tp_flags = aflags; // set flags received
+                                       session[s].mru = DEFAULT_MRU;
                                        controlnull(t); // ack
 
                                        // start LCP
-                                       sendlcp(s, t, config->radius_authprefer);
                                        sess_local[s].lcp.restart = time_now + config->ppp_restart_time;
                                        sess_local[s].lcp.conf_sent = 1;
                                        sess_local[s].lcp.nak_sent = 0;
                                        sess_local[s].lcp_authtype = config->radius_authprefer;
                                        session[s].ppp.lcp = RequestSent;
+                                       sendlcp(s, t);
 
                                        break;
                                case 14:      // CDN
@@ -2717,7 +2718,7 @@ static void regular_cleanups(double period)
                                        LOG(3, s, session[s].tunnel, "No ACK for LCP ConfigReq... resending\n");
                                        sess_local[s].lcp.restart = time_now + config->ppp_restart_time;
                                        sess_local[s].lcp.conf_sent++;
-                                       sendlcp(s, session[s].tunnel, sess_local[s].lcp_authtype);
+                                       sendlcp(s, session[s].tunnel);
                                        change_state(s, lcp, next_state);
                                }
                                else
index 7979fd5..c58e2d9 100644 (file)
--- a/l2tpns.h
+++ b/l2tpns.h
@@ -1,5 +1,5 @@
 // L2TPNS Global Stuff
-// $Id: l2tpns.h,v 1.84 2005-08-24 23:44:08 bodea Exp $
+// $Id: l2tpns.h,v 1.85 2005-08-29 06:17:53 bodea Exp $
 
 #ifndef __L2TPNS_H__
 #define __L2TPNS_H__
@@ -669,7 +669,7 @@ void processipv6in(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l);
 void processccp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l);
 void sendchap(sessionidt s, tunnelidt t);
 uint8_t *makeppp(uint8_t *b, int size, uint8_t *p, int l, sessionidt s, tunnelidt t, uint16_t mtype);
-void sendlcp(sessionidt s, tunnelidt t, int authtype);
+void sendlcp(sessionidt s, tunnelidt t);
 void send_ipin(sessionidt s, uint8_t *buf, int len);
 void sendccp(sessionidt s, tunnelidt t);
 
diff --git a/ppp.c b/ppp.c
index 09c3a36..abd5609 100644 (file)
--- a/ppp.c
+++ b/ppp.c
@@ -1,6 +1,6 @@
 // L2TPNS PPP Stuff
 
-char const *cvs_id_ppp = "$Id: ppp.c,v 1.76 2005-08-29 03:21:14 bodea Exp $";
+char const *cvs_id_ppp = "$Id: ppp.c,v 1.77 2005-08-29 06:17:53 bodea Exp $";
 
 #include <stdio.h>
 #include <string.h>
@@ -521,7 +521,7 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
                        if (session[s].ppp.lcp == Opened)
                                lcp_restart(s);
 
-                       sendlcp(s, t, sess_local[s].lcp_authtype);
+                       sendlcp(s, t);
                        change_state(s, lcp, RequestSent);
                        break;
 
@@ -651,7 +651,7 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
 
                case Stopped:
                        initialise_restart_count(s, lcp);
-                       sendlcp(s, t, sess_local[s].lcp_authtype);
+                       sendlcp(s, t);
                        if (*response == ConfigAck)
                                change_state(s, lcp, AckSent);
                        else
@@ -673,7 +673,7 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
 
                case Opened:
                        lcp_restart(s);
-                       sendlcp(s, t, sess_local[s].lcp_authtype);
+                       sendlcp(s, t);
                        /* fallthrough */
 
                case AckSent:
@@ -694,7 +694,7 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
 
                tunnelsend(b, l + (response - b), t);
        }
-       else if (*p == ConfigNak)
+       else if (*p == ConfigNak || *p == ConfigRej)
        {
                int x = l - 4;
                uint8_t *o = (p + 4);
@@ -709,14 +709,24 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
                        switch (type)
                        {
                                case 1: // Maximum-Receive-Unit
-                                       session[s].mru = ntohs(*(uint16_t *)(o + 2));
-                                       LOG(3, s, t, "    Remote requested MRU of %u\n", session[s].mru);
+                                       if (*p == ConfigNak)
+                                       {
+                                               session[s].mru = ntohs(*(uint16_t *)(o + 2));
+                                               LOG(3, s, t, "    Remote requested MRU of %u\n", session[s].mru);
+                                       }
+                                       else
+                                       {
+                                               session[s].mru = 0;
+                                               LOG(3, s, t, "    Remote rejected MRU negotiation\n");
+                                       }
+
                                        break;
 
                                case 3: // Authentication-Protocol
                                        if (authtype > 0)
                                                break;
 
+                                       if (*p == ConfigNak)
                                        {
                                                int proto = ntohs(*(uint16_t *)(o + 2));
                                                if (proto == PPPPAP)
@@ -737,11 +747,16 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
                                                                proto);
                                                }
                                        }
+                                       else
+                                       {
+                                               LOG(2, s, t, "LCP: remote rejected auth negotiation\n");
+                                               authtype = 0; // shutdown
+                                       }
 
                                        break;
 
                                default:
-                                       LOG(2, s, t, "    Remote NAKed LCP type %u?\n", type);
+                                       LOG(2, s, t, "LCP: remote sent %s for type %u?\n", ppp_code(*p), type);
                                        break;
                        }
                        x -= length;
@@ -777,17 +792,17 @@ void processlcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
                case RequestSent:
                case AckSent:
                        initialise_restart_count(s, lcp);
-                       sendlcp(s, t, sess_local[s].lcp_authtype);
+                       sendlcp(s, t);
                        break;
 
                case AckReceived:
                        LOG(2, s, t, "LCP: ConfigNak in state %s?  Sending ConfigReq\n", ppp_state(session[s].ppp.lcp));
-                       sendlcp(s, t, sess_local[s].lcp_authtype);
+                       sendlcp(s, t);
                        break;
 
                case Opened:
                        lcp_restart(s);
-                       sendlcp(s, t, sess_local[s].lcp_authtype);
+                       sendlcp(s, t);
                        break;
 
                default:
@@ -1810,9 +1825,10 @@ static int add_lcp_auth(uint8_t *b, int size, int authtype)
 }
 
 // Send initial LCP ConfigReq for MRU, authentication type and magic no
-void sendlcp(sessionidt s, tunnelidt t, int authtype)
+void sendlcp(sessionidt s, tunnelidt t)
 {
        uint8_t b[500], *q, *l;
+       int authtype = sess_local[s].lcp_authtype;
 
        if (!(q = makeppp(b, sizeof(b), NULL, 0, s, t, PPPLCP)))
                return;
@@ -1822,17 +1838,17 @@ void sendlcp(sessionidt s, tunnelidt t, int authtype)
            authtype ? (authtype == AUTHCHAP ? "CHAP" : "PAP") : "",
            authtype ? ")" : "");
 
-       if (!session[s].mru)
-               session[s].mru = DEFAULT_MRU;
-
        l = q;
        *l++ = ConfigReq;
        *l++ = (time_now % 255) + 1; // ID
 
        l += 2; //Save space for length
 
-       *l++ = 1; *l++ = 4; // Maximum-Receive-Unit (length 4)
-       *(uint16_t *) l = htons(session[s].mru); l += 2;
+       if (session[s].mru)
+       {
+               *l++ = 1; *l++ = 4; // Maximum-Receive-Unit (length 4)
+               *(uint16_t *) l = htons(session[s].mru); l += 2;
+       }
 
        if (authtype)
                l += add_lcp_auth(l, sizeof(b) - (l - b), authtype);