From 53f1a814a14f348ecf1405d406303e1125205504 Mon Sep 17 00:00:00 2001 From: bodea Date: Mon, 29 Aug 2005 06:17:53 +0000 Subject: [PATCH 1/1] handle rejection of MRU negotiation by peer --- Changes | 1 + l2tpns.c | 7 ++++--- l2tpns.h | 4 ++-- ppp.c | 50 +++++++++++++++++++++++++++++++++----------------- 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/Changes b/Changes index d54c990..8144831 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,7 @@ * Mon Aug 29 2005 Brendan O'Dea 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 2.1.3 - Fail IPCP negotiation only on ConfigRej of IP-Address. diff --git a/l2tpns.c b/l2tpns.c index 4a91a3f..b8af6af 100644 --- 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 #include @@ -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 diff --git a/l2tpns.h b/l2tpns.h index 49c9a77..3d19b8f 100644 --- 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 005d42a..922f591 100644 --- 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 #include @@ -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); -- 2.20.1