X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/58d994f8f4aa2a6465dc9a2f13e7ba8ddf412ec7..92bfbe46e854e7ff40d6d4297c8df74f1efcf10f:/ppp.c diff --git a/ppp.c b/ppp.c index cb8512f..29bf1bc 100644 --- a/ppp.c +++ b/ppp.c @@ -5,9 +5,10 @@ #include #include #include -#include #include +#include +#include "dhcp6.h" #include "l2tpns.h" #include "constants.h" #include "plugin.h" @@ -1480,11 +1481,28 @@ void processipcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) static void ipv6cp_open(sessionidt s, tunnelidt t) { + int i; + groupidt g; LOG(3, s, t, "IPV6CP: Opened\n"); change_state(s, ipv6cp, Opened); - if (session[s].ipv6prefixlen) - route6set(s, session[s].ipv6route, session[s].ipv6prefixlen, 1); + for (i = 0; i < MAXROUTE6 && session[s].route6[i].ipv6prefixlen; i++) + { + route6set(s, session[s].route6[i].ipv6route, session[s].route6[i].ipv6prefixlen, 1); + } + + if (session[s].ipv6address.s6_addr[0]) + { + // Check if included in prefix + if (sessionbyipv6(session[s].ipv6address) != s) + route6set(s, session[s].ipv6address, 128, 1); + } + + if ((g = grp_groupbysession(s))) + { + grp_setgrouproute6(g, 1); + cluster_send_groupe(g); + } // Send an initial RA (TODO: Should we send these regularly?) send_ipv6_ra(s, t, NULL); @@ -1571,8 +1589,16 @@ void processipv6cp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) gotip++; // seen address if (o[1] != 10) return; - ident[0] = htonl(session[s].ip); - ident[1] = 0; + if (session[s].ipv6address.s6_addr[0]) + { + // LSB 64bits of assigned IPv6 address to user (see radius attribut Framed-IPv6-Address) + memcpy(&ident[0], &session[s].ipv6address.s6_addr[8], 8); + } + else + { + ident[0] = htonl(session[s].ip); + ident[1] = 0; + } if (memcmp(o + 2, ident, sizeof(ident))) { @@ -1738,7 +1764,7 @@ static void update_sessions_in_stat(sessionidt s, uint16_t l) // (i.e. this routine writes to p[-4]). void processipin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) { - in_addr_t ip; + in_addr_t ip, ip_dst; CSTAT(processipin); @@ -1752,6 +1778,7 @@ void processipin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) } ip = ntohl(*(uint32_t *)(p + 12)); + ip_dst = *(uint32_t *)(p + 16); if (l > MAXETHER) { @@ -1792,12 +1819,15 @@ void processipin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) if (session[s].tbf_in) { - // Are we throttling this session? - if (config->cluster_iam_master) - tbf_queue_packet(session[s].tbf_in, p, l); - else - master_throttle_packet(session[s].tbf_in, p, l); - return; + if (!config->no_throttle_local_IP || !sessionbyip(ip_dst)) + { + // Are we throttling this session? + if (config->cluster_iam_master) + tbf_queue_packet(session[s].tbf_in, p, l); + else + master_throttle_packet(session[s].tbf_in, p, l); + return; + } } // send to ethernet @@ -2241,7 +2271,19 @@ void processipv6in(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) return; // no spoof - if ((ipv4 != session[s].ip || memcmp(&config->ipv6_prefix, &ip, 8)) && sessionbyipv6(ip) != s) + if (session[s].ipv6address.s6_addr[0]) + { + if ((sessionbyipv6new(ip) != s) && + (ip.s6_addr[0] != 0xFE || ip.s6_addr[1] != 0x80 || ip.s6_addr16[1] != 0 || ip.s6_addr16[2] != 0 || ip.s6_addr16[3] != 0) && + (!grp_groupbyipv6(ip))) + { + char str[INET6_ADDRSTRLEN]; + LOG(5, s, t, "Dropping packet with spoofed IP %s\n", + inet_ntop(AF_INET6, &ip, str, INET6_ADDRSTRLEN)); + return; + } + } + else if ((ipv4 != session[s].ip || memcmp(&config->ipv6_prefix, &ip, 8)) && sessionbyipv6(ip) != s) { char str[INET6_ADDRSTRLEN]; LOG(5, s, t, "Dropping packet with spoofed IP %s\n", @@ -2259,6 +2301,16 @@ void processipv6in(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) return; } + // Check if DhcpV6, IP dst: FF02::1:2, Src Port 0x0222 (546), Dst Port 0x0223 (547) + if (*(p + 6) == 17 && *(p + 24) == 0xFF && *(p + 25) == 2 && + *(uint32_t *)(p + 26) == 0 && *(uint32_t *)(p + 30) == 0 && + *(uint16_t *)(p + 34) == 0 && *(p + 36) == 0 && *(p + 37) == 1 && *(p + 38) == 0 && *(p + 39) == 2 && + *(p + 40) == 2 && *(p + 41) == 0x22 && *(p + 42) == 2 && *(p + 43) == 0x23) + { + dhcpv6_process(s, t, p, l); + return; + } + // Add on the tun header p -= 4; *(uint32_t *) p = htonl(PKTIPV6); @@ -2510,9 +2562,9 @@ void sendchap(sessionidt s, tunnelidt t) q[1] = radius[r].id; // ID q[4] = 16; // value size (size of challenge) memcpy(q + 5, radius[r].auth, 16); // challenge - strcpy((char *) q + 21, hostname); // our name - *(uint16_t *) (q + 2) = htons(strlen(hostname) + 21); // length - tunnelsend(b, strlen(hostname) + 21 + (q - b), t); // send it + strcpy((char *) q + 21, config->multi_n_hostname[tunnel[t].indexudp][0]?config->multi_n_hostname[tunnel[t].indexudp]:hostname); // our name + *(uint16_t *) (q + 2) = htons(strlen(config->multi_n_hostname[tunnel[t].indexudp][0]?config->multi_n_hostname[tunnel[t].indexudp]:hostname) + 21); // length + tunnelsend(b, strlen(config->multi_n_hostname[tunnel[t].indexudp][0]?config->multi_n_hostname[tunnel[t].indexudp]:hostname) + 21 + (q - b), t); // send it } // fill in a L2TP message with a PPP frame,