X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/8aa16e6262042b83953a89548a07459bbef3cbb9..90a81d13b57bc08caaeaaccfcc4be75bf7a418a2:/l2tpns.c?ds=inline diff --git a/l2tpns.c b/l2tpns.c index 93fcc29..6839c25 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.121 2005-08-11 05:50:24 bodea Exp $"; +char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.131 2005-09-13 14:27:14 bodea Exp $"; #include #include @@ -135,6 +135,7 @@ config_descriptt config_values[] = { CONFIG("packet_limit", max_packets, INT), CONFIG("cluster_address", cluster_address, IPv4), CONFIG("cluster_interface", cluster_interface, STRING), + CONFIG("cluster_mcast_ttl", cluster_mcast_ttl, INT), CONFIG("cluster_hb_interval", cluster_hb_interval, INT), CONFIG("cluster_hb_timeout", cluster_hb_timeout, INT), CONFIG("cluster_master_min_adv", cluster_master_min_adv, INT), @@ -1580,10 +1581,11 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error) void sendipcp(sessionidt s, tunnelidt t) { - uint8_t buf[MAXCONTROL]; + uint8_t buf[MAXETHER]; uint8_t *q; CSTAT(sendipcp); + LOG(3, s, t, "IPCP: send ConfigReq\n"); if (!session[s].unique_id) { @@ -1591,7 +1593,7 @@ void sendipcp(sessionidt s, tunnelidt t) session[s].unique_id = last_id; } - q = makeppp(buf,sizeof(buf), 0, 0, s, t, PPPIPCP); + q = makeppp(buf, sizeof(buf), 0, 0, s, t, PPPIPCP); if (!q) return; *q = ConfigReq; @@ -1608,12 +1610,13 @@ void sendipcp(sessionidt s, tunnelidt t) void sendipv6cp(sessionidt s, tunnelidt t) { - uint8_t buf[MAXCONTROL]; + uint8_t buf[MAXETHER]; uint8_t *q; CSTAT(sendipv6cp); + LOG(3, s, t, "IPV6CP: send ConfigReq\n"); - q = makeppp(buf,sizeof(buf), 0, 0, s, t, PPPIPV6CP); + q = makeppp(buf, sizeof(buf), 0, 0, s, t, PPPIPV6CP); if (!q) return; *q = ConfigReq; @@ -1824,6 +1827,11 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr) return; } l -= (p - buf); + + // used to time out old tunnels + if (t && tunnel[t].state == TUNNELOPEN) + tunnel[t].lastrec = time_now; + if (*buf & 0x80) { // control uint16_t message = 0xFFFF; // message type @@ -1911,9 +1919,6 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr) return; } - // This is used to time out old tunnels - tunnel[t].lastrec = time_now; - // check sequence of this message { int skip = tunnel[t].window; // track how many in-window packets are still in queue @@ -2292,7 +2297,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr) controlt *c = controlnew(2); // sending SCCRP control16(c, 2, version, 1); // protocol version control32(c, 3, 3, 1); // framing - controls(c, 7, tunnel[t].hostname, 1); // host name (TBA) + controls(c, 7, hostname, 1); // host name if (chapresponse) controlb(c, 13, chapresponse, 16, 1); // Challenge response control16(c, 9, t, 1); // assigned tunnel controladd(c, 0, t); // send the resply @@ -2376,15 +2381,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 @@ -2412,7 +2418,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr) } else { // data - uint16_t prot; + uint16_t proto; LOG_HEX(5, "Receive Tunnel Data", p, l); if (l > 2 && p[0] == 0xFF && p[1] == 0x03) @@ -2428,12 +2434,12 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr) } if (*p & 1) { - prot = *p++; + proto = *p++; l--; } else { - prot = ntohs(*(uint16_t *) p); + proto = ntohs(*(uint16_t *) p); p += 2; l -= 2; } @@ -2453,43 +2459,43 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr) return; } - if (prot == PPPPAP) + if (proto == PPPPAP) { session[s].last_packet = time_now; if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port); return; } processpap(s, t, p, l); } - else if (prot == PPPCHAP) + else if (proto == PPPCHAP) { session[s].last_packet = time_now; if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port); return; } processchap(s, t, p, l); } - else if (prot == PPPLCP) + else if (proto == PPPLCP) { session[s].last_packet = time_now; if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port); return; } processlcp(s, t, p, l); } - else if (prot == PPPIPCP) + else if (proto == PPPIPCP) { session[s].last_packet = time_now; if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port); return; } processipcp(s, t, p, l); } - else if (prot == PPPIPV6CP) + else if (proto == PPPIPV6CP && config->ipv6_prefix.s6_addr[0]) { session[s].last_packet = time_now; if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port); return; } processipv6cp(s, t, p, l); } - else if (prot == PPPCCP) + else if (proto == PPPCCP) { session[s].last_packet = time_now; if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port); return; } processccp(s, t, p, l); } - else if (prot == PPPIP) + else if (proto == PPPIP) { if (session[s].die) { @@ -2506,13 +2512,8 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr) processipin(s, t, p, l); } - else if (prot == PPPIPV6) + else if (proto == PPPIPV6 && config->ipv6_prefix.s6_addr[0]) { - if (!config->ipv6_prefix.s6_addr[0]) - { - LOG(1, s, t, "IPv6 not configured; yet received IPv6 packet. Ignoring.\n"); - return; - } if (session[s].die) { LOG(4, s, t, "Session %d is closing. Don't process PPP packets\n", s); @@ -2528,10 +2529,38 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr) processipv6in(s, t, p, l); } + else if (session[s].ppp.lcp == Opened) + { + uint8_t buf[MAXETHER]; + uint8_t *q; + int mru = session[s].mru; + + if (!mru) mru = MAXMRU; + if (mru > sizeof(buf)) mru = sizeof(buf); + + l += 6; + if (l > mru) l = mru; + + q = makeppp(buf, sizeof(buf), 0, 0, s, t, proto); + if (!q) return; + + *q = CodeRej; + *(q + 1) = ++sess_local[s].lcp_ident; + *(uint16_t *)(q + 2) = l; + *(uint16_t *)(q + 4) = htons(proto); + memcpy(q + 6, p, l - 6); + + if (proto == PPPIPV6CP) + LOG(3, s, t, "LCP: send ProtocolRej (IPV6CP: not configured)\n"); + else + LOG(2, s, t, "LCP: sent ProtocolRej (0x%04X: unsupported)\n", proto); + + tunnelsend(buf, l + (q - buf), t); + } else { - STAT(tunnel_rx_errors); - LOG(1, s, t, "Unknown PPP protocol %04X\n", prot); + LOG(2, s, t, "Unknown PPP protocol 0x%04X received in LCP %s state\n", + proto, ppp_state(session[s].ppp.lcp)); } } } @@ -2642,7 +2671,7 @@ static void regular_cleanups(double period) } } // Send hello - if (tunnel[t].state == TUNNELOPEN && tunnel[t].lastrec < TIME + 600) + if (tunnel[t].state == TUNNELOPEN && (time_now - tunnel[t].lastrec) > 60) { controlt *c = controlnew(6); // sending HELLO controladd(c, 0, t); // send the message @@ -2715,7 +2744,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, t, sess_local[s].lcp_authtype); + sendlcp(s, session[s].tunnel); change_state(s, lcp, next_state); } else @@ -2746,7 +2775,7 @@ static void regular_cleanups(double period) LOG(3, s, session[s].tunnel, "No ACK for IPCP ConfigReq... resending\n"); sess_local[s].ipcp.restart = time_now + config->ppp_restart_time; sess_local[s].ipcp.conf_sent++; - sendipcp(s, t); + sendipcp(s, session[s].tunnel); change_state(s, ipcp, next_state); } else @@ -2777,7 +2806,7 @@ static void regular_cleanups(double period) LOG(3, s, session[s].tunnel, "No ACK for IPV6CP ConfigReq... resending\n"); sess_local[s].ipv6cp.restart = time_now + config->ppp_restart_time; sess_local[s].ipv6cp.conf_sent++; - sendipv6cp(s, t); + sendipv6cp(s, session[s].tunnel); change_state(s, ipv6cp, next_state); } else @@ -2805,7 +2834,7 @@ static void regular_cleanups(double period) LOG(3, s, session[s].tunnel, "No ACK for CCP ConfigReq... resending\n"); sess_local[s].ccp.restart = time_now + config->ppp_restart_time; sess_local[s].ccp.conf_sent++; - sendccp(s, t); + sendccp(s, session[s].tunnel); change_state(s, ccp, next_state); } else @@ -2830,7 +2859,7 @@ static void regular_cleanups(double period) // No data in ECHO_TIMEOUT seconds, send LCP ECHO if (session[s].ppp.phase >= Establish && (time_now - session[s].last_packet >= ECHO_TIMEOUT)) { - uint8_t b[MAXCONTROL] = {0}; + uint8_t b[MAXETHER]; uint8_t *q = makeppp(b, sizeof(b), 0, 0, s, session[s].tunnel, PPPLCP); if (!q) continue; @@ -3466,6 +3495,7 @@ static void initdata(int optdebug, char *optconfig) config->debug = optdebug; config->num_tbfs = MAXTBFS; config->rl_rate = 28; // 28kbps + config->cluster_mcast_ttl = 1; config->cluster_master_min_adv = 1; config->ppp_restart_time = 3; config->ppp_max_configure = 10;