X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/2267fbe504476b75d30270fb39a0f01481087676..6f7d8eb27fcd243080d62ed0f05f928110f11e1d:/ppp.c?ds=sidebyside diff --git a/ppp.c b/ppp.c index 6888328..0d3b168 100644 --- a/ppp.c +++ b/ppp.c @@ -1,6 +1,6 @@ // L2TPNS PPP Stuff -char const *cvs_id_ppp = "$Id: ppp.c,v 1.56 2005-05-10 09:47:23 bodea Exp $"; +char const *cvs_id_ppp = "$Id: ppp.c,v 1.64 2005-06-24 08:34:53 bodea Exp $"; #include #include @@ -150,7 +150,6 @@ void processchap(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l) { LOG(1, s, t, "Unexpected CHAP message\n"); STAT(tunnel_rx_errors); - sessionshutdown(s, "Unexpected CHAP message.", 3, 0); return; } @@ -355,7 +354,33 @@ void processlcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l) if (*p == ConfigAck) { - LOG(3, s, t, "LCP: Discarding ConfigAck\n"); + int x = l - 4; + uint8_t *o = (p + 4); + + LOG(3, s, t, "LCP: ConfigAck (%d bytes)...\n", l); + if (config->debug > 3) dumplcp(p, l); + + while (x > 2) + { + int type = o[0]; + int length = o[1]; + + if (length == 0 || type == 0 || x < length) break; + switch (type) + { + case 3: // Authentication-Protocol + { + int proto = ntohs(*(uint16_t *)(o + 2)); + if (proto == PPPCHAP && *(o + 4) == 5) + sendchap(t, s); + } + + break; + } + x -= length; + o += length; + } + session[s].flags |= SF_LCP_ACKED; } else if (*p == ConfigReq) @@ -524,7 +549,7 @@ void processlcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l) { int x = l - 4; uint8_t *o = (p + 4); - int authtype = 0; + int authtype = -1; LOG(3, s, t, "LCP: ConfigNak (%d bytes)...\n", l); if (config->debug > 3) dumplcp(p, l); @@ -543,7 +568,7 @@ void processlcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l) break; case 3: // Authentication-Protocol - if (authtype) + if (authtype > 0) break; { @@ -567,21 +592,23 @@ void processlcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l) } } - if (!authtype) - { - sessionshutdown(s, "Unsupported authentication.", 3, 0); - return; - } - break; default: LOG(2, s, t, " Remote NAKed LCP type %u?\n", type); break; } + x -= length; + o += length; } if (!authtype) + { + sessionshutdown(s, "Unsupported authentication.", 3, 0); + return; + } + + if (authtype == -1) authtype = config->radius_authprefer; sendlcp(t, s, authtype); @@ -691,22 +718,32 @@ void processipcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l) if (*p == ConfigAck) { - // happy with our IPCP uint16_t r = sess_local[s].radius; - if ((!r || radius[r].state == RADIUSIPCP) && !session[s].walled_garden) - { - if (!r) - r = radiusnew(s); - if (r) - radiussend(r, RADIUSSTART); // send radius start, having got IPCP at last - } + + // ignore duplicate ACKs + if (session[s].flags & SF_IPCP_ACKED) + return; + + // happy with our IPCP session[s].flags |= SF_IPCP_ACKED; LOG(3, s, t, "IPCP Acked, session is now active\n"); - // clear LCP_ACKED/CCP_ACKED flag for possible fast renegotiaion for routers + // clear LCP_ACKED/CCP_ACKED flag for possible fast renegotiation for routers session[s].flags &= ~(SF_LCP_ACKED|SF_CCP_ACKED); + if (r && session[s].walled_garden) + { + radiusclear(r, s); + return; + } + + if (!r) + r = radiusnew(s); + + if (r) + radiussend(r, RADIUSSTART); // send radius start, having got IPCP at last + return; } if (*p != ConfigReq) @@ -988,21 +1025,26 @@ void processipin(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l) return; } + p += 4; + l -= 4; + if (session[s].snoop_ip && session[s].snoop_port) { // Snooping this session - snoop_send_packet(p + 4, l - 4, session[s].snoop_ip, session[s].snoop_port); + snoop_send_packet(p, l, session[s].snoop_ip, session[s].snoop_port); } - session[s].cin += l - 4; - session[s].total_cin += l - 4; - sess_local[s].cin += l - 4; - + increment_counter(&session[s].cin, &session[s].cin_wrap, l); + session[s].cin_delta += l; session[s].pin++; - eth_tx += l - 4; + + sess_local[s].cin += l; + sess_local[s].pin++; + + eth_tx += l; STAT(tun_tx_packets); - INC_STAT(tun_tx_bytes, l - 4); + INC_STAT(tun_tx_bytes, l); } // process IPv6 packet received @@ -1076,21 +1118,26 @@ void processipv6in(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l) return; } + p += 4; + l -= 4; + if (session[s].snoop_ip && session[s].snoop_port) { // Snooping this session - snoop_send_packet(p + 4, l - 4, session[s].snoop_ip, session[s].snoop_port); + snoop_send_packet(p, l, session[s].snoop_ip, session[s].snoop_port); } - session[s].cin += l - 4; - session[s].total_cin += l - 4; - sess_local[s].cin += l - 4; - + increment_counter(&session[s].cin, &session[s].cin_wrap, l); + session[s].cin_delta += l; session[s].pin++; - eth_tx += l - 4; + + sess_local[s].cin += l; + sess_local[s].pin++; + + eth_tx += l; STAT(tun_tx_packets); - INC_STAT(tun_tx_bytes, l - 4); + INC_STAT(tun_tx_bytes, l); } // @@ -1110,19 +1157,24 @@ void send_ipin(sessionidt s, uint8_t *buf, int len) return; } + buf += 4; + len -= 4; + if (session[s].snoop_ip && session[s].snoop_port) { // Snooping this session - snoop_send_packet(buf + 4, len - 4, session[s].snoop_ip, session[s].snoop_port); + snoop_send_packet(buf, len, session[s].snoop_ip, session[s].snoop_port); } // Increment packet counters - session[s].cin += len - 4; - session[s].total_cin += len - 4; - sess_local[s].cin += len - 4; - + increment_counter(&session[s].cin, &session[s].cin_wrap, len); + session[s].cin_delta += len; session[s].pin++; - eth_tx += len - 4; + + sess_local[s].cin += len; + sess_local[s].pin++; + + eth_tx += len; STAT(tun_tx_packets); INC_STAT(tun_tx_bytes, len - 4); @@ -1301,7 +1353,7 @@ void sendlcp(tunnelidt t, sessionidt s, int authtype) return; LOG(4, s, t, "Sending LCP ConfigReq for %s\n", - config->radius_authprefer == AUTHCHAP ? "CHAP" : "PAP"); + authtype == AUTHCHAP ? "CHAP" : "PAP"); if (!session[s].mru) session[s].mru = DEFAULT_MRU;