Merge branch 'multibind'
This commit is contained in:
commit
c1d1c2a8c4
13 changed files with 340 additions and 358 deletions
|
|
@ -265,6 +265,24 @@ from the address of "bind_address" (For use in cases of specific configuration).
|
||||||
If no address is given to iftun_address and bind_address, 1.1.1.1 is used.
|
If no address is given to iftun_address and bind_address, 1.1.1.1 is used.
|
||||||
</LI>
|
</LI>
|
||||||
|
|
||||||
|
<LI><B>bind_multi_address</B> (ip address)<BR>
|
||||||
|
This parameter permit to listen several addresss of the l2tp udp protocol
|
||||||
|
(and set several address to the tun interface).
|
||||||
|
<BR>
|
||||||
|
WHEN this parameter is set, It OVERWRITE the parameters "bind_address"
|
||||||
|
and "iftun_address".
|
||||||
|
<BR>
|
||||||
|
these can be interesting when you want do load-balancing in cluster mode
|
||||||
|
of the uploaded from the LAC. For example you can set a bgp.prepend(MY_AS)
|
||||||
|
for Address1 on LNS1 and a bgp.prepend(MY_AS) for Address2 on LNS2
|
||||||
|
(see BGP AS-path prepending).
|
||||||
|
<BR>
|
||||||
|
example of use with 2 address:
|
||||||
|
<BR>
|
||||||
|
set bind_multi_address "64.14.13.41, 64.14.13.42"
|
||||||
|
|
||||||
|
</LI>
|
||||||
|
|
||||||
<LI><B>tundevicename</B> (string)<BR>
|
<LI><B>tundevicename</B> (string)<BR>
|
||||||
Name of the tun interface (default: "tun0").
|
Name of the tun interface (default: "tun0").
|
||||||
</LI>
|
</LI>
|
||||||
|
|
|
||||||
7
Makefile
7
Makefile
|
|
@ -26,7 +26,7 @@ INSTALL = install -c -D -o root -g root
|
||||||
l2tpns.LIBS = -lm -lcli -ldl
|
l2tpns.LIBS = -lm -lcli -ldl
|
||||||
|
|
||||||
OBJS = arp.o cli.o cluster.o constants.o control.o icmp.o l2tpns.o \
|
OBJS = arp.o cli.o cluster.o constants.o control.o icmp.o l2tpns.o \
|
||||||
ll.o md5.o ppp.o radius.o tbf.o util.o pppoe.o
|
ll.o md5.o ppp.o radius.o tbf.o util.o pppoe.o l2tplac.o
|
||||||
|
|
||||||
PROGRAMS = l2tpns nsctl
|
PROGRAMS = l2tpns nsctl
|
||||||
PLUGINS = autosnoop.so autothrottle.so garden.so sessionctl.so \
|
PLUGINS = autosnoop.so autothrottle.so garden.so sessionctl.so \
|
||||||
|
|
@ -43,9 +43,6 @@ endif
|
||||||
DEFINES += -DBGP
|
DEFINES += -DBGP
|
||||||
OBJS += bgp.o
|
OBJS += bgp.o
|
||||||
|
|
||||||
DEFINES += -DLAC
|
|
||||||
OBJS += l2tplac.o
|
|
||||||
|
|
||||||
all: programs plugins
|
all: programs plugins
|
||||||
programs: $(PROGRAMS)
|
programs: $(PROGRAMS)
|
||||||
plugins: $(PLUGINS)
|
plugins: $(PLUGINS)
|
||||||
|
|
@ -129,8 +126,8 @@ radius.o: radius.c md5.h constants.h l2tpns.h plugin.h util.h cluster.h \
|
||||||
tbf.o: tbf.c l2tpns.h util.h tbf.h
|
tbf.o: tbf.c l2tpns.h util.h tbf.h
|
||||||
util.o: util.c l2tpns.h bgp.h
|
util.o: util.c l2tpns.h bgp.h
|
||||||
pppoe.o: pppoe.c l2tpns.h cluster.h constants.h md5.h util.h
|
pppoe.o: pppoe.c l2tpns.h cluster.h constants.h md5.h util.h
|
||||||
bgp.o: bgp.c l2tpns.h bgp.h util.h
|
|
||||||
l2tplac.o: l2tplac.c md5.h l2tpns.h util.h cluster.h l2tplac.h pppoe.h
|
l2tplac.o: l2tplac.c md5.h l2tpns.h util.h cluster.h l2tplac.h pppoe.h
|
||||||
|
bgp.o: bgp.c l2tpns.h bgp.h util.h
|
||||||
autosnoop.so: autosnoop.c l2tpns.h plugin.h
|
autosnoop.so: autosnoop.c l2tpns.h plugin.h
|
||||||
autothrottle.so: autothrottle.c l2tpns.h plugin.h
|
autothrottle.so: autothrottle.c l2tpns.h plugin.h
|
||||||
garden.so: garden.c l2tpns.h plugin.h control.h
|
garden.so: garden.c l2tpns.h plugin.h control.h
|
||||||
|
|
|
||||||
39
cli.c
39
cli.c
|
|
@ -31,9 +31,7 @@
|
||||||
#ifdef BGP
|
#ifdef BGP
|
||||||
#include "bgp.h"
|
#include "bgp.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef LAC
|
|
||||||
#include "l2tplac.h"
|
#include "l2tplac.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
extern tunnelt *tunnel;
|
extern tunnelt *tunnel;
|
||||||
extern bundlet *bundle;
|
extern bundlet *bundle;
|
||||||
|
|
@ -102,10 +100,8 @@ static int cmd_remove_plugin(struct cli_def *cli, char *command, char **argv, in
|
||||||
static int cmd_uptime(struct cli_def *cli, char *command, char **argv, int argc);
|
static int cmd_uptime(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
static int cmd_shutdown(struct cli_def *cli, char *command, char **argv, int argc);
|
static int cmd_shutdown(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
static int cmd_reload(struct cli_def *cli, char *command, char **argv, int argc);
|
static int cmd_reload(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
#ifdef LAC
|
|
||||||
static int cmd_setforward(struct cli_def *cli, char *command, char **argv, int argc);
|
static int cmd_setforward(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
static int cmd_show_rmtlnsconf(struct cli_def *cli, char *command, char **argv, int argc);
|
static int cmd_show_rmtlnsconf(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
#endif
|
|
||||||
|
|
||||||
static int regular_stuff(struct cli_def *cli);
|
static int regular_stuff(struct cli_def *cli);
|
||||||
|
|
||||||
|
|
@ -156,9 +152,7 @@ void init_cli()
|
||||||
cli_register_command(cli, c, "pool", cmd_show_pool, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the IP address allocation pool");
|
cli_register_command(cli, c, "pool", cmd_show_pool, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show the IP address allocation pool");
|
||||||
cli_register_command(cli, c, "radius", cmd_show_radius, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show active radius queries");
|
cli_register_command(cli, c, "radius", cmd_show_radius, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show active radius queries");
|
||||||
cli_register_command(cli, c, "running-config", cmd_show_run, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Show the currently running configuration");
|
cli_register_command(cli, c, "running-config", cmd_show_run, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Show the currently running configuration");
|
||||||
#ifdef LAC
|
|
||||||
cli_register_command(cli, c, "remotelns-conf", cmd_show_rmtlnsconf, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Show a list of remote LNS configuration");
|
cli_register_command(cli, c, "remotelns-conf", cmd_show_rmtlnsconf, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Show a list of remote LNS configuration");
|
||||||
#endif
|
|
||||||
cli_register_command(cli, c, "session", cmd_show_session, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show a list of sessions or details for a single session");
|
cli_register_command(cli, c, "session", cmd_show_session, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show a list of sessions or details for a single session");
|
||||||
cli_register_command(cli, c, "tbf", cmd_show_tbf, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "List all token bucket filters in use");
|
cli_register_command(cli, c, "tbf", cmd_show_tbf, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "List all token bucket filters in use");
|
||||||
cli_register_command(cli, c, "throttle", cmd_show_throttle, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "List all throttled sessions and associated TBFs");
|
cli_register_command(cli, c, "throttle", cmd_show_throttle, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "List all throttled sessions and associated TBFs");
|
||||||
|
|
@ -231,9 +225,7 @@ void init_cli()
|
||||||
|
|
||||||
cli_register_command(cli, NULL, "set", cmd_set, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Set a configuration variable");
|
cli_register_command(cli, NULL, "set", cmd_set, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Set a configuration variable");
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
cli_register_command(cli, NULL, "setforward", cmd_setforward, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Set the Remote LNS Forward");
|
cli_register_command(cli, NULL, "setforward", cmd_setforward, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Set the Remote LNS Forward");
|
||||||
#endif
|
|
||||||
|
|
||||||
c = cli_register_command(cli, NULL, "ip", NULL, PRIVILEGE_PRIVILEGED, MODE_CONFIG, NULL);
|
c = cli_register_command(cli, NULL, "ip", NULL, PRIVILEGE_PRIVILEGED, MODE_CONFIG, NULL);
|
||||||
cli_register_command(cli, c, "access-list", cmd_ip_access_list, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Add named access-list");
|
cli_register_command(cli, c, "access-list", cmd_ip_access_list, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Add named access-list");
|
||||||
|
|
@ -542,15 +534,9 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show Summary
|
// Show Summary
|
||||||
#ifdef LAC
|
|
||||||
cli_print(cli, "%5s %7s %4s %-32s %-15s %s %s %s %s %10s %10s %10s %4s %10s %-18s %s",
|
cli_print(cli, "%5s %7s %4s %-32s %-15s %s %s %s %s %10s %10s %10s %4s %10s %-18s %s",
|
||||||
#else
|
|
||||||
cli_print(cli, "%5s %4s %-32s %-15s %s %s %s %s %10s %10s %10s %4s %10s %-15s %s",
|
|
||||||
#endif
|
|
||||||
"SID",
|
"SID",
|
||||||
#ifdef LAC
|
|
||||||
"LkToSID",
|
"LkToSID",
|
||||||
#endif
|
|
||||||
"TID",
|
"TID",
|
||||||
"Username",
|
"Username",
|
||||||
"IP",
|
"IP",
|
||||||
|
|
@ -563,11 +549,7 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
|
||||||
"uploaded",
|
"uploaded",
|
||||||
"idle",
|
"idle",
|
||||||
"Rem.Time",
|
"Rem.Time",
|
||||||
#ifdef LAC
|
|
||||||
"LAC(L)/RLNS(R)/PPPOE(P)",
|
"LAC(L)/RLNS(R)/PPPOE(P)",
|
||||||
#else
|
|
||||||
"LAC(L)/PPPOE(P)",
|
|
||||||
#endif
|
|
||||||
"CLI");
|
"CLI");
|
||||||
|
|
||||||
for (i = 1; i < MAXSESSION; i++)
|
for (i = 1; i < MAXSESSION; i++)
|
||||||
|
|
@ -578,15 +560,9 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
|
||||||
rem_time = session[i].timeout ? (session[i].timeout - bundle[session[i].bundle].online_time) : 0;
|
rem_time = session[i].timeout ? (session[i].timeout - bundle[session[i].bundle].online_time) : 0;
|
||||||
else
|
else
|
||||||
rem_time = session[i].timeout ? (session[i].timeout - (time_now-session[i].opened)) : 0;
|
rem_time = session[i].timeout ? (session[i].timeout - (time_now-session[i].opened)) : 0;
|
||||||
#ifdef LAC
|
|
||||||
cli_print(cli, "%5d %7d %4d %-32s %-15s %s %s %s %s %10u %10lu %10lu %4u %10lu %3s%-20s %s",
|
cli_print(cli, "%5d %7d %4d %-32s %-15s %s %s %s %s %10u %10lu %10lu %4u %10lu %3s%-20s %s",
|
||||||
#else
|
|
||||||
cli_print(cli, "%5d %4d %-32s %-15s %s %s %s %s %10u %10lu %10lu %4u %10lu %3s%-20s %s",
|
|
||||||
#endif
|
|
||||||
i,
|
i,
|
||||||
#ifdef LAC
|
|
||||||
session[i].forwardtosession,
|
session[i].forwardtosession,
|
||||||
#endif
|
|
||||||
session[i].tunnel,
|
session[i].tunnel,
|
||||||
session[i].user[0] ? session[i].user : "*",
|
session[i].user[0] ? session[i].user : "*",
|
||||||
fmtaddr(htonl(session[i].ip), 0),
|
fmtaddr(htonl(session[i].ip), 0),
|
||||||
|
|
@ -599,11 +575,7 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
|
||||||
(unsigned long)session[i].cin,
|
(unsigned long)session[i].cin,
|
||||||
abs(time_now - (session[i].last_packet ? session[i].last_packet : time_now)),
|
abs(time_now - (session[i].last_packet ? session[i].last_packet : time_now)),
|
||||||
(unsigned long)(rem_time),
|
(unsigned long)(rem_time),
|
||||||
#ifdef LAC
|
|
||||||
(session[i].tunnel == TUNNEL_ID_PPPOE)?"(P)":(tunnel[session[i].tunnel].isremotelns?"(R)":"(L)"),
|
(session[i].tunnel == TUNNEL_ID_PPPOE)?"(P)":(tunnel[session[i].tunnel].isremotelns?"(R)":"(L)"),
|
||||||
#else
|
|
||||||
(session[i].tunnel == TUNNEL_ID_PPPOE)?"(P)":"(L)",
|
|
||||||
#endif
|
|
||||||
(session[i].tunnel == TUNNEL_ID_PPPOE)?fmtMacAddr(session[i].src_hwaddr):fmtaddr(htonl(tunnel[session[i].tunnel].ip), 1),
|
(session[i].tunnel == TUNNEL_ID_PPPOE)?fmtMacAddr(session[i].src_hwaddr):fmtaddr(htonl(tunnel[session[i].tunnel].ip), 1),
|
||||||
session[i].calling[0] ? session[i].calling : "*");
|
session[i].calling[0] ? session[i].calling : "*");
|
||||||
}
|
}
|
||||||
|
|
@ -694,11 +666,7 @@ static int cmd_show_tunnels(struct cli_def *cli, char *command, char **argv, int
|
||||||
fmtaddr(htonl(tunnel[i].ip), 0),
|
fmtaddr(htonl(tunnel[i].ip), 0),
|
||||||
states[tunnel[i].state],
|
states[tunnel[i].state],
|
||||||
sessions
|
sessions
|
||||||
#ifdef LAC
|
|
||||||
,(i == TUNNEL_ID_PPPOE)?"Tunnel pppoe":(tunnel[i].isremotelns?"Tunnel To Remote LNS":"Tunnel To LAC")
|
,(i == TUNNEL_ID_PPPOE)?"Tunnel pppoe":(tunnel[i].isremotelns?"Tunnel To Remote LNS":"Tunnel To LAC")
|
||||||
#else
|
|
||||||
,(i == TUNNEL_ID_PPPOE)?"Tunnel pppoe":"Tunnel To LAC"
|
|
||||||
#endif
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1309,13 +1277,11 @@ static int cmd_drop_session(struct cli_def *cli, char *command, char **argv, int
|
||||||
cli_print(cli, "Dropping session %d", s);
|
cli_print(cli, "Dropping session %d", s);
|
||||||
cli_session_actions[s].action |= CLI_SESS_KILL;
|
cli_session_actions[s].action |= CLI_SESS_KILL;
|
||||||
}
|
}
|
||||||
#ifdef LAC
|
|
||||||
else if (session[s].forwardtosession && session[s].opened && !session[s].die)
|
else if (session[s].forwardtosession && session[s].opened && !session[s].die)
|
||||||
{
|
{
|
||||||
cli_print(cli, "Dropping session %d", s);
|
cli_print(cli, "Dropping session %d", s);
|
||||||
cli_session_actions[s].action |= CLI_SESS_KILL;
|
cli_session_actions[s].action |= CLI_SESS_KILL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cli_error(cli, "Session %d is not active.", s);
|
cli_error(cli, "Session %d is not active.", s);
|
||||||
|
|
@ -3106,7 +3072,7 @@ static int cmd_show_access_list(struct cli_def *cli, char *command, char **argv,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i)
|
if (i)
|
||||||
cli_print(cli, "");
|
cli_print(cli, " ");
|
||||||
|
|
||||||
cli_print(cli, "%s IP access list %s",
|
cli_print(cli, "%s IP access list %s",
|
||||||
ip_filters[f].extended ? "Extended" : "Standard",
|
ip_filters[f].extended ? "Extended" : "Standard",
|
||||||
|
|
@ -3144,8 +3110,6 @@ static int cmd_reload(struct cli_def *cli, char *command, char **argv, int argc)
|
||||||
return CLI_OK;
|
return CLI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
|
|
||||||
static int cmd_setforward(struct cli_def *cli, char *command, char **argv, int argc)
|
static int cmd_setforward(struct cli_def *cli, char *command, char **argv, int argc)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
@ -3216,4 +3180,3 @@ static int cmd_show_rmtlnsconf(struct cli_def *cli, char *command, char **argv,
|
||||||
|
|
||||||
return CLI_OK;
|
return CLI_OK;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
|
||||||
22
cluster.c
22
cluster.c
|
|
@ -305,10 +305,11 @@ static int _forward_packet(uint8_t *data, int size, in_addr_t addr, int port, in
|
||||||
// The master just processes the payload as if it had
|
// The master just processes the payload as if it had
|
||||||
// received it off the tun device.
|
// received it off the tun device.
|
||||||
//(note: THIS ROUTINE WRITES TO pack[-6]).
|
//(note: THIS ROUTINE WRITES TO pack[-6]).
|
||||||
int master_forward_packet(uint8_t *data, int size, in_addr_t addr, int port)
|
int master_forward_packet(uint8_t *data, int size, in_addr_t addr, uint16_t port, uint16_t indexudp)
|
||||||
{
|
{
|
||||||
uint8_t *p = data - (3 * sizeof(uint32_t));
|
uint8_t *p = data - (3 * sizeof(uint32_t));
|
||||||
uint8_t *psave = p;
|
uint8_t *psave = p;
|
||||||
|
uint32_t indexandport = port | ((indexudp << 16) & 0xFFFF0000);
|
||||||
|
|
||||||
if (!config->cluster_master_address) // No election has been held yet. Just skip it.
|
if (!config->cluster_master_address) // No election has been held yet. Just skip it.
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -316,7 +317,7 @@ int master_forward_packet(uint8_t *data, int size, in_addr_t addr, int port)
|
||||||
LOG(4, 0, 0, "Forwarding packet from %s to master (size %d)\n", fmtaddr(addr, 0), size);
|
LOG(4, 0, 0, "Forwarding packet from %s to master (size %d)\n", fmtaddr(addr, 0), size);
|
||||||
|
|
||||||
STAT(c_forwarded);
|
STAT(c_forwarded);
|
||||||
add_type(&p, C_FORWARD, addr, (uint8_t *) &port, sizeof(port)); // ick. should be uint16_t
|
add_type(&p, C_FORWARD, addr, (uint8_t *) &indexandport, sizeof(indexandport));
|
||||||
|
|
||||||
return peer_send_data(config->cluster_master_address, psave, size + (3 * sizeof(uint32_t)));
|
return peer_send_data(config->cluster_master_address, psave, size + (3 * sizeof(uint32_t)));
|
||||||
}
|
}
|
||||||
|
|
@ -1503,16 +1504,9 @@ static int cluster_process_heartbeat(uint8_t *data, int size, int more, uint8_t
|
||||||
int i, type;
|
int i, type;
|
||||||
int hb_ver = more;
|
int hb_ver = more;
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
#if HB_VERSION != 7
|
#if HB_VERSION != 7
|
||||||
# error "need to update cluster_process_heartbeat()"
|
# error "need to update cluster_process_heartbeat()"
|
||||||
#endif
|
#endif
|
||||||
#else
|
|
||||||
#if HB_VERSION != 6
|
|
||||||
# error "need to update cluster_process_heartbeat()"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// we handle versions 5 through 7
|
// we handle versions 5 through 7
|
||||||
if (hb_ver < 5 || hb_ver > HB_VERSION) {
|
if (hb_ver < 5 || hb_ver > HB_VERSION) {
|
||||||
|
|
@ -1726,12 +1720,8 @@ static int cluster_process_heartbeat(uint8_t *data, int size, int more, uint8_t
|
||||||
size = rle_decompress((uint8_t **) &p, s, c, sizeof(c));
|
size = rle_decompress((uint8_t **) &p, s, c, sizeof(c));
|
||||||
s -= (p - orig_p);
|
s -= (p - orig_p);
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
if ( ((hb_ver >= HB_VERSION) && (size != sizeof(tunnelt))) ||
|
if ( ((hb_ver >= HB_VERSION) && (size != sizeof(tunnelt))) ||
|
||||||
((hb_ver < HB_VERSION) && (size > sizeof(tunnelt))) )
|
((hb_ver < HB_VERSION) && (size > sizeof(tunnelt))) )
|
||||||
#else
|
|
||||||
if (size != sizeof(tunnelt) )
|
|
||||||
#endif
|
|
||||||
{ // Ouch! Very very bad!
|
{ // Ouch! Very very bad!
|
||||||
LOG(0, 0, 0, "DANGER: Received a CTUNNEL that didn't decompress correctly!\n");
|
LOG(0, 0, 0, "DANGER: Received a CTUNNEL that didn't decompress correctly!\n");
|
||||||
// Now what? Should exit! No-longer up to date!
|
// Now what? Should exit! No-longer up to date!
|
||||||
|
|
@ -1854,9 +1844,11 @@ int processcluster(uint8_t *data, int size, in_addr_t addr)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct sockaddr_in a;
|
struct sockaddr_in a;
|
||||||
|
uint16_t indexudp;
|
||||||
a.sin_addr.s_addr = more;
|
a.sin_addr.s_addr = more;
|
||||||
|
|
||||||
a.sin_port = *(int *) p;
|
a.sin_port = (*(int *) p) & 0xFFFF;
|
||||||
|
indexudp = ((*(int *) p) >> 16) & 0xFFFF;
|
||||||
s -= sizeof(int);
|
s -= sizeof(int);
|
||||||
p += sizeof(int);
|
p += sizeof(int);
|
||||||
|
|
||||||
|
|
@ -1871,7 +1863,7 @@ int processcluster(uint8_t *data, int size, in_addr_t addr)
|
||||||
processdae(p, s, &a, sizeof(a), &local);
|
processdae(p, s, &a, sizeof(a), &local);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
processudp(p, s, &a);
|
processudp(p, s, &a, indexudp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,7 @@
|
||||||
#define C_MPPP_FORWARD 19 // MPPP Forwarded packet..
|
#define C_MPPP_FORWARD 19 // MPPP Forwarded packet..
|
||||||
#define C_PPPOE_FORWARD 20 // PPPOE Forwarded packet..
|
#define C_PPPOE_FORWARD 20 // PPPOE Forwarded packet..
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
#define HB_VERSION 7 // Protocol version number..
|
#define HB_VERSION 7 // Protocol version number..
|
||||||
#else
|
|
||||||
#define HB_VERSION 6 // Protocol version number..
|
|
||||||
#endif
|
|
||||||
#define HB_MAX_SEQ (1<<30) // Maximum sequence number. (MUST BE A POWER OF 2!)
|
#define HB_MAX_SEQ (1<<30) // Maximum sequence number. (MUST BE A POWER OF 2!)
|
||||||
#define HB_HISTORY_SIZE 64 // How many old heartbeats we remember?? (Must be a factor of HB_MAX_SEQ)
|
#define HB_HISTORY_SIZE 64 // How many old heartbeats we remember?? (Must be a factor of HB_MAX_SEQ)
|
||||||
|
|
||||||
|
|
@ -86,7 +82,7 @@ int processcluster(uint8_t *buf, int size, in_addr_t addr);
|
||||||
int cluster_send_session(int sid);
|
int cluster_send_session(int sid);
|
||||||
int cluster_send_bundle(int bid);
|
int cluster_send_bundle(int bid);
|
||||||
int cluster_send_tunnel(int tid);
|
int cluster_send_tunnel(int tid);
|
||||||
int master_forward_packet(uint8_t *data, int size, in_addr_t addr, int port);
|
int master_forward_packet(uint8_t *data, int size, in_addr_t addr, uint16_t port, uint16_t indexudp);
|
||||||
int master_forward_dae_packet(uint8_t *data, int size, in_addr_t addr, int port);
|
int master_forward_dae_packet(uint8_t *data, int size, in_addr_t addr, int port);
|
||||||
int master_throttle_packet(int tid, uint8_t *data, int size);
|
int master_throttle_packet(int tid, uint8_t *data, int size);
|
||||||
int master_garden_packet(sessionidt s, uint8_t *data, int size);
|
int master_garden_packet(sessionidt s, uint8_t *data, int size);
|
||||||
|
|
|
||||||
|
|
@ -295,6 +295,7 @@ static int lac_create_tunnelsession(tunnelidt t, sessionidt s, confrlnsidt i_con
|
||||||
tunnel[t].port = pconfigrlns[i_conf].port;
|
tunnel[t].port = pconfigrlns[i_conf].port;
|
||||||
tunnel[t].window = 4; // default window
|
tunnel[t].window = 4; // default window
|
||||||
tunnel[t].isremotelns = i_conf;
|
tunnel[t].isremotelns = i_conf;
|
||||||
|
tunnel[t].indexudp = config->indexlacudpfd;
|
||||||
STAT(tunnel_created);
|
STAT(tunnel_created);
|
||||||
|
|
||||||
random_data(pconfigrlns[i_conf].auth, sizeof(pconfigrlns[i_conf].auth));
|
random_data(pconfigrlns[i_conf].auth, sizeof(pconfigrlns[i_conf].auth));
|
||||||
|
|
@ -449,7 +450,7 @@ void lac_calc_rlns_auth(tunnelidt t, uint8_t id, uint8_t *out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward session to LAC or Remote LNS
|
// Forward session to LAC or Remote LNS
|
||||||
int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto, in_addr_t s_addr, int sin_port)
|
int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto, in_addr_t s_addr, int sin_port, uint16_t indexudpfd)
|
||||||
{
|
{
|
||||||
uint16_t t = 0, s = 0;
|
uint16_t t = 0, s = 0;
|
||||||
uint8_t *p = buf + 2; // First word L2TP options
|
uint8_t *p = buf + 2; // First word L2TP options
|
||||||
|
|
@ -482,7 +483,7 @@ int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto,
|
||||||
(proto == PPPCCP) )
|
(proto == PPPCCP) )
|
||||||
{
|
{
|
||||||
session[sess].last_packet = time_now;
|
session[sess].last_packet = time_now;
|
||||||
master_forward_packet(buf, len, s_addr, sin_port);
|
master_forward_packet(buf, len, s_addr, sin_port, indexudpfd);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ typedef uint16_t confrlnsidt;
|
||||||
|
|
||||||
// l2tplac.c
|
// l2tplac.c
|
||||||
void lac_initremotelnsdata();
|
void lac_initremotelnsdata();
|
||||||
int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto, in_addr_t s_addr, int sin_port);
|
int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto, in_addr_t s_addr, int sin_port, uint16_t indexudpfd);
|
||||||
int lac_conf_forwardtoremotelns(sessionidt s, char * puser);
|
int lac_conf_forwardtoremotelns(sessionidt s, char * puser);
|
||||||
void lac_calc_rlns_auth(tunnelidt t, uint8_t id, uint8_t *out);
|
void lac_calc_rlns_auth(tunnelidt t, uint8_t id, uint8_t *out);
|
||||||
int lac_addremotelns(char *mask, char *IP_RemoteLNS, char *Port_RemoteLNS, char *SecretRemoteLNS);
|
int lac_addremotelns(char *mask, char *IP_RemoteLNS, char *Port_RemoteLNS, char *SecretRemoteLNS);
|
||||||
|
|
|
||||||
399
l2tpns.c
399
l2tpns.c
|
|
@ -53,24 +53,18 @@
|
||||||
#include "bgp.h"
|
#include "bgp.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
#include "l2tplac.h"
|
#include "l2tplac.h"
|
||||||
#endif
|
|
||||||
#include "pppoe.h"
|
#include "pppoe.h"
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
char * Vendor_name = "Linux L2TPNS";
|
char * Vendor_name = "Linux L2TPNS";
|
||||||
uint32_t call_serial_number = 0;
|
uint32_t call_serial_number = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
// Globals
|
// Globals
|
||||||
configt *config = NULL; // all configuration
|
configt *config = NULL; // all configuration
|
||||||
int nlfd = -1; // netlink socket
|
int nlfd = -1; // netlink socket
|
||||||
int tunfd = -1; // tun interface file handle. (network device)
|
int tunfd = -1; // tun interface file handle. (network device)
|
||||||
int udpfd = -1; // UDP file handle
|
int udpfd[MAX_UDPFD + 1] = INIT_TABUDPFD; // array UDP file handle + 1 for lac udp
|
||||||
#ifdef LAC
|
|
||||||
int udplacfd = -1; // UDP LAC file handle
|
int udplacfd = -1; // UDP LAC file handle
|
||||||
#endif
|
|
||||||
int controlfd = -1; // Control signal handle
|
int controlfd = -1; // Control signal handle
|
||||||
int clifd = -1; // Socket listening for CLI connections.
|
int clifd = -1; // Socket listening for CLI connections.
|
||||||
int daefd = -1; // Socket listening for DAE connections.
|
int daefd = -1; // Socket listening for DAE connections.
|
||||||
|
|
@ -181,17 +175,16 @@ config_descriptt config_values[] = {
|
||||||
CONFIG("idle_echo_timeout", idle_echo_timeout, INT),
|
CONFIG("idle_echo_timeout", idle_echo_timeout, INT),
|
||||||
CONFIG("iftun_address", iftun_address, IPv4),
|
CONFIG("iftun_address", iftun_address, IPv4),
|
||||||
CONFIG("tundevicename", tundevicename, STRING),
|
CONFIG("tundevicename", tundevicename, STRING),
|
||||||
#ifdef LAC
|
|
||||||
CONFIG("disable_lac_func", disable_lac_func, BOOL),
|
CONFIG("disable_lac_func", disable_lac_func, BOOL),
|
||||||
CONFIG("auth_tunnel_change_addr_src", auth_tunnel_change_addr_src, BOOL),
|
CONFIG("auth_tunnel_change_addr_src", auth_tunnel_change_addr_src, BOOL),
|
||||||
CONFIG("bind_address_remotelns", bind_address_remotelns, IPv4),
|
CONFIG("bind_address_remotelns", bind_address_remotelns, IPv4),
|
||||||
CONFIG("bind_portremotelns", bind_portremotelns, SHORT),
|
CONFIG("bind_portremotelns", bind_portremotelns, SHORT),
|
||||||
#endif
|
|
||||||
CONFIG("pppoe_if_to_bind", pppoe_if_to_bind, STRING),
|
CONFIG("pppoe_if_to_bind", pppoe_if_to_bind, STRING),
|
||||||
CONFIG("pppoe_service_name", pppoe_service_name, STRING),
|
CONFIG("pppoe_service_name", pppoe_service_name, STRING),
|
||||||
CONFIG("pppoe_ac_name", pppoe_ac_name, STRING),
|
CONFIG("pppoe_ac_name", pppoe_ac_name, STRING),
|
||||||
CONFIG("disable_sending_hello", disable_sending_hello, BOOL),
|
CONFIG("disable_sending_hello", disable_sending_hello, BOOL),
|
||||||
CONFIG("disable_no_spoof", disable_no_spoof, BOOL),
|
CONFIG("disable_no_spoof", disable_no_spoof, BOOL),
|
||||||
|
CONFIG("bind_multi_address", bind_multi_address, STRING),
|
||||||
{ NULL, 0, 0, 0 }
|
{ NULL, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -700,7 +693,7 @@ static void inittun(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*config->tundevicename)
|
if (*config->tundevicename)
|
||||||
strncpy(ifr.ifr_name, config->tundevicename, IFNAMSIZ);
|
strncpy(ifr.ifr_name, config->tundevicename, IFNAMSIZ);
|
||||||
|
|
||||||
if (ioctl(tunfd, TUNSETIFF, (void *) &ifr) < 0)
|
if (ioctl(tunfd, TUNSETIFF, (void *) &ifr) < 0)
|
||||||
{
|
{
|
||||||
|
|
@ -762,14 +755,30 @@ static void inittun(void)
|
||||||
req.ifmsg.ifaddr.ifa_scope = RT_SCOPE_UNIVERSE;
|
req.ifmsg.ifaddr.ifa_scope = RT_SCOPE_UNIVERSE;
|
||||||
req.ifmsg.ifaddr.ifa_index = tunidx;
|
req.ifmsg.ifaddr.ifa_index = tunidx;
|
||||||
|
|
||||||
if (config->iftun_address)
|
if (config->nbmultiaddress > 1)
|
||||||
ip = config->iftun_address;
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < config->nbmultiaddress ; i++)
|
||||||
|
{
|
||||||
|
ip = config->iftun_n_address[i];
|
||||||
|
netlink_addattr(&req.nh, IFA_LOCAL, &ip, sizeof(ip));
|
||||||
|
if (netlink_send(&req.nh) < 0)
|
||||||
|
goto senderror;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ip = 0x01010101; // 1.1.1.1
|
{
|
||||||
netlink_addattr(&req.nh, IFA_LOCAL, &ip, sizeof(ip));
|
if (config->iftun_address)
|
||||||
|
ip = config->iftun_address;
|
||||||
|
else
|
||||||
|
ip = 0x01010101; // 1.1.1.1
|
||||||
|
netlink_addattr(&req.nh, IFA_LOCAL, &ip, sizeof(ip));
|
||||||
|
|
||||||
|
if (netlink_send(&req.nh) < 0)
|
||||||
|
goto senderror;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (netlink_send(&req.nh) < 0)
|
|
||||||
goto senderror;
|
|
||||||
|
|
||||||
// Only setup IPv6 on the tun device if we have a configured prefix
|
// Only setup IPv6 on the tun device if we have a configured prefix
|
||||||
if (config->ipv6_prefix.s6_addr[0]) {
|
if (config->ipv6_prefix.s6_addr[0]) {
|
||||||
|
|
@ -839,56 +848,12 @@ senderror:
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up UDP ports
|
// set up LAC UDP ports
|
||||||
static void initudp(void)
|
static void initlacudp(void)
|
||||||
{
|
{
|
||||||
int on = 1;
|
int on = 1;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
// Tunnel
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_port = htons(L2TPPORT);
|
|
||||||
addr.sin_addr.s_addr = config->bind_address;
|
|
||||||
udpfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
setsockopt(udpfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
|
||||||
{
|
|
||||||
int flags = fcntl(udpfd, F_GETFL, 0);
|
|
||||||
fcntl(udpfd, F_SETFL, flags | O_NONBLOCK);
|
|
||||||
}
|
|
||||||
if (bind(udpfd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
|
|
||||||
{
|
|
||||||
LOG(0, 0, 0, "Error in UDP bind: %s\n", strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Control
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_port = htons(NSCTL_PORT);
|
|
||||||
controlfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
setsockopt(controlfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
|
||||||
setsockopt(controlfd, SOL_IP, IP_PKTINFO, &on, sizeof(on)); // recvfromto
|
|
||||||
if (bind(controlfd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
|
|
||||||
{
|
|
||||||
LOG(0, 0, 0, "Error in control bind: %s\n", strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dynamic Authorization Extensions to RADIUS
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_port = htons(config->radius_dae_port);
|
|
||||||
daefd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
setsockopt(daefd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
|
||||||
setsockopt(daefd, SOL_IP, IP_PKTINFO, &on, sizeof(on)); // recvfromto
|
|
||||||
if (bind(daefd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
|
|
||||||
{
|
|
||||||
LOG(0, 0, 0, "Error in DAE bind: %s\n", strerror(errno));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
// Tunnel to Remote LNS
|
// Tunnel to Remote LNS
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
|
|
@ -905,10 +870,70 @@ static void initudp(void)
|
||||||
LOG(0, 0, 0, "Error in UDP REMOTE LNS bind: %s\n", strerror(errno));
|
LOG(0, 0, 0, "Error in UDP REMOTE LNS bind: %s\n", strerror(errno));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
// Intercept
|
// set up control ports
|
||||||
snoopfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
static void initcontrol(void)
|
||||||
|
{
|
||||||
|
int on = 1;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
// Control
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(NSCTL_PORT);
|
||||||
|
controlfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
setsockopt(controlfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||||
|
setsockopt(controlfd, SOL_IP, IP_PKTINFO, &on, sizeof(on)); // recvfromto
|
||||||
|
if (bind(controlfd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
|
||||||
|
{
|
||||||
|
LOG(0, 0, 0, "Error in control bind: %s\n", strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up Dynamic Authorization Extensions to RADIUS port
|
||||||
|
static void initdae(void)
|
||||||
|
{
|
||||||
|
int on = 1;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
// Dynamic Authorization Extensions to RADIUS
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(config->radius_dae_port);
|
||||||
|
daefd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
setsockopt(daefd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||||
|
setsockopt(daefd, SOL_IP, IP_PKTINFO, &on, sizeof(on)); // recvfromto
|
||||||
|
if (bind(daefd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
|
||||||
|
{
|
||||||
|
LOG(0, 0, 0, "Error in DAE bind: %s\n", strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up UDP ports
|
||||||
|
static void initudp(int * pudpfd, in_addr_t ip_bind)
|
||||||
|
{
|
||||||
|
int on = 1;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
// Tunnel
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(L2TPPORT);
|
||||||
|
addr.sin_addr.s_addr = ip_bind;
|
||||||
|
(*pudpfd) = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
setsockopt((*pudpfd), SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||||
|
{
|
||||||
|
int flags = fcntl((*pudpfd), F_GETFL, 0);
|
||||||
|
fcntl((*pudpfd), F_SETFL, flags | O_NONBLOCK);
|
||||||
|
}
|
||||||
|
if (bind((*pudpfd), (struct sockaddr *) &addr, sizeof(addr)) < 0)
|
||||||
|
{
|
||||||
|
LOG(0, 0, 0, "Error in UDP bind: %s\n", strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -1233,14 +1258,11 @@ void tunnelsend(uint8_t * buf, uint16_t l, tunnelidt t)
|
||||||
LOG(3, 0, t, "Control message resend try %d\n", tunnel[t].try);
|
LOG(3, 0, t, "Control message resend try %d\n", tunnel[t].try);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef LAC
|
|
||||||
if (sendto((tunnel[t].isremotelns?udplacfd:udpfd), buf, l, 0, (void *) &addr, sizeof(addr)) < 0)
|
if (sendto(udpfd[tunnel[t].indexudp], buf, l, 0, (void *) &addr, sizeof(addr)) < 0)
|
||||||
#else
|
|
||||||
if (sendto(udpfd, buf, l, 0, (void *) &addr, sizeof(addr)) < 0)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
LOG(0, ntohs((*(uint16_t *) (buf + 6))), t, "Error sending data out tunnel: %s (udpfd=%d, buf=%p, len=%d, dest=%s)\n",
|
LOG(0, ntohs((*(uint16_t *) (buf + 6))), t, "Error sending data out tunnel: %s (udpfd=%d, buf=%p, len=%d, dest=%s)\n",
|
||||||
strerror(errno), udpfd, buf, l, inet_ntoa(addr.sin_addr));
|
strerror(errno), udpfd[tunnel[t].indexudp], buf, l, inet_ntoa(addr.sin_addr));
|
||||||
STAT(tunnel_tx_errors);
|
STAT(tunnel_tx_errors);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -2208,7 +2230,7 @@ void sendipcp(sessionidt s, tunnelidt t)
|
||||||
q[4] = 3; // ip address option
|
q[4] = 3; // ip address option
|
||||||
q[5] = 6; // option length
|
q[5] = 6; // option length
|
||||||
*(in_addr_t *) (q + 6) = config->peer_address ? config->peer_address :
|
*(in_addr_t *) (q + 6) = config->peer_address ? config->peer_address :
|
||||||
config->iftun_address ? config->iftun_address :
|
config->iftun_n_address[tunnel[t].indexudp] ? config->iftun_n_address[tunnel[t].indexudp] :
|
||||||
my_address; // send my IP
|
my_address; // send my IP
|
||||||
|
|
||||||
tunnelsend(buf, 10 + (q - buf), t); // send it
|
tunnelsend(buf, 10 + (q - buf), t); // send it
|
||||||
|
|
@ -2272,7 +2294,6 @@ void sessionkill(sessionidt s, char *reason)
|
||||||
if (sess_local[s].radius)
|
if (sess_local[s].radius)
|
||||||
radiusclear(sess_local[s].radius, s); // cant send clean accounting data, session is killed
|
radiusclear(sess_local[s].radius, s); // cant send clean accounting data, session is killed
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
if (session[s].forwardtosession)
|
if (session[s].forwardtosession)
|
||||||
{
|
{
|
||||||
sessionidt sess = session[s].forwardtosession;
|
sessionidt sess = session[s].forwardtosession;
|
||||||
|
|
@ -2282,7 +2303,6 @@ void sessionkill(sessionidt s, char *reason)
|
||||||
sessionshutdown(sess, reason, CDN_ADMIN_DISC, TERM_ADMIN_RESET);
|
sessionshutdown(sess, reason, CDN_ADMIN_DISC, TERM_ADMIN_RESET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
LOG(2, s, session[s].tunnel, "Kill session %d (%s): %s\n", s, session[s].user, reason);
|
LOG(2, s, session[s].tunnel, "Kill session %d (%s): %s\n", s, session[s].user, reason);
|
||||||
sessionclear(s);
|
sessionclear(s);
|
||||||
|
|
@ -2388,7 +2408,7 @@ static void tunnelshutdown(tunnelidt t, char *reason, int result, int error, cha
|
||||||
}
|
}
|
||||||
|
|
||||||
// read and process packet on tunnel (UDP)
|
// read and process packet on tunnel (UDP)
|
||||||
void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexudpfd)
|
||||||
{
|
{
|
||||||
uint8_t *chapresponse = NULL;
|
uint8_t *chapresponse = NULL;
|
||||||
uint16_t l = len, t = 0, s = 0, ns = 0, nr = 0;
|
uint16_t l = len, t = 0, s = 0, ns = 0, nr = 0;
|
||||||
|
|
@ -2479,7 +2499,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
|
|
||||||
if (!config->cluster_iam_master)
|
if (!config->cluster_iam_master)
|
||||||
{
|
{
|
||||||
master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port);
|
master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port, indexudpfd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2529,6 +2549,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
tunnel[t].ip = ntohl(*(in_addr_t *) & addr->sin_addr);
|
tunnel[t].ip = ntohl(*(in_addr_t *) & addr->sin_addr);
|
||||||
tunnel[t].port = ntohs(addr->sin_port);
|
tunnel[t].port = ntohs(addr->sin_port);
|
||||||
tunnel[t].window = 4; // default window
|
tunnel[t].window = 4; // default window
|
||||||
|
tunnel[t].indexudp = indexudpfd;
|
||||||
STAT(tunnel_created);
|
STAT(tunnel_created);
|
||||||
LOG(1, 0, t, " New tunnel from %s:%u ID %u\n",
|
LOG(1, 0, t, " New tunnel from %s:%u ID %u\n",
|
||||||
fmtaddr(htonl(tunnel[t].ip), 0), tunnel[t].port, t);
|
fmtaddr(htonl(tunnel[t].ip), 0), tunnel[t].port, t);
|
||||||
|
|
@ -2800,7 +2821,6 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 13: // Response
|
case 13: // Response
|
||||||
#ifdef LAC
|
|
||||||
if (tunnel[t].isremotelns)
|
if (tunnel[t].isremotelns)
|
||||||
{
|
{
|
||||||
chapresponse = calloc(17, 1);
|
chapresponse = calloc(17, 1);
|
||||||
|
|
@ -2808,7 +2828,6 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
LOG(3, s, t, "received challenge response from REMOTE LNS\n");
|
LOG(3, s, t, "received challenge response from REMOTE LNS\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* LAC */
|
|
||||||
// Why did they send a response? We never challenge.
|
// Why did they send a response? We never challenge.
|
||||||
LOG(2, s, t, " received unexpected challenge response\n");
|
LOG(2, s, t, " received unexpected challenge response\n");
|
||||||
break;
|
break;
|
||||||
|
|
@ -3054,7 +3073,6 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
case 2: // SCCRP
|
case 2: // SCCRP
|
||||||
tunnel[t].state = TUNNELOPEN;
|
tunnel[t].state = TUNNELOPEN;
|
||||||
tunnel[t].lastrec = time_now;
|
tunnel[t].lastrec = time_now;
|
||||||
#ifdef LAC
|
|
||||||
LOG(3, s, t, "Received SCCRP\n");
|
LOG(3, s, t, "Received SCCRP\n");
|
||||||
if (main_quit != QUIT_SHUTDOWN)
|
if (main_quit != QUIT_SHUTDOWN)
|
||||||
{
|
{
|
||||||
|
|
@ -3085,7 +3103,6 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
{
|
{
|
||||||
tunnelshutdown(t, "Shutting down", 6, 0, 0);
|
tunnelshutdown(t, "Shutting down", 6, 0, 0);
|
||||||
}
|
}
|
||||||
#endif /* LAC */
|
|
||||||
break;
|
break;
|
||||||
case 3: // SCCN
|
case 3: // SCCN
|
||||||
LOG(3, s, t, "Received SCCN\n");
|
LOG(3, s, t, "Received SCCN\n");
|
||||||
|
|
@ -3163,7 +3180,6 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 11: // ICRP
|
case 11: // ICRP
|
||||||
#ifdef LAC
|
|
||||||
LOG(3, s, t, "Received ICRP\n");
|
LOG(3, s, t, "Received ICRP\n");
|
||||||
if (session[s].forwardtosession)
|
if (session[s].forwardtosession)
|
||||||
{
|
{
|
||||||
|
|
@ -3179,7 +3195,6 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
controladd(c, asession, t); // send the message
|
controladd(c, asession, t); // send the message
|
||||||
LOG(3, s, t, "Sending ICCN\n");
|
LOG(3, s, t, "Sending ICCN\n");
|
||||||
}
|
}
|
||||||
#endif /* LAC */
|
|
||||||
break;
|
break;
|
||||||
case 12: // ICCN
|
case 12: // ICCN
|
||||||
LOG(3, s, t, "Received ICCN\n");
|
LOG(3, s, t, "Received ICCN\n");
|
||||||
|
|
@ -3195,7 +3210,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
|
|
||||||
// Set multilink options before sending initial LCP packet
|
// Set multilink options before sending initial LCP packet
|
||||||
sess_local[s].mp_mrru = 1614;
|
sess_local[s].mp_mrru = 1614;
|
||||||
sess_local[s].mp_epdis = ntohl(config->iftun_address ? config->iftun_address : my_address);
|
sess_local[s].mp_epdis = ntohl(config->iftun_n_address[tunnel[t].indexudp] ? config->iftun_n_address[tunnel[t].indexudp] : my_address);
|
||||||
|
|
||||||
sendlcp(s, t);
|
sendlcp(s, t);
|
||||||
change_state(s, lcp, RequestSent);
|
change_state(s, lcp, RequestSent);
|
||||||
|
|
@ -3253,12 +3268,11 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
l -= 2;
|
l -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
if (session[s].forwardtosession)
|
if (session[s].forwardtosession)
|
||||||
{
|
{
|
||||||
LOG(5, s, t, "Forwarding data session to session %u\n", session[s].forwardtosession);
|
LOG(5, s, t, "Forwarding data session to session %u\n", session[s].forwardtosession);
|
||||||
// Forward to LAC/BAS or Remote LNS session
|
// Forward to LAC/BAS or Remote LNS session
|
||||||
lac_session_forward(buf, len, s, proto, addr->sin_addr.s_addr, addr->sin_port);
|
lac_session_forward(buf, len, s, proto, addr->sin_addr.s_addr, addr->sin_port, indexudpfd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (config->auth_tunnel_change_addr_src)
|
else if (config->auth_tunnel_change_addr_src)
|
||||||
|
|
@ -3273,14 +3287,13 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
tunnel[t].ip = ntohl(addr->sin_addr.s_addr);
|
tunnel[t].ip = ntohl(addr->sin_addr.s_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* LAC */
|
|
||||||
|
|
||||||
if (s && !session[s].opened) // Is something wrong??
|
if (s && !session[s].opened) // Is something wrong??
|
||||||
{
|
{
|
||||||
if (!config->cluster_iam_master)
|
if (!config->cluster_iam_master)
|
||||||
{
|
{
|
||||||
// Pass it off to the master to deal with..
|
// Pass it off to the master to deal with..
|
||||||
master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port);
|
master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port, indexudpfd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3292,37 +3305,37 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
if (proto == PPPPAP)
|
if (proto == PPPPAP)
|
||||||
{
|
{
|
||||||
session[s].last_packet = time_now;
|
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; }
|
if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port, indexudpfd); return; }
|
||||||
processpap(s, t, p, l);
|
processpap(s, t, p, l);
|
||||||
}
|
}
|
||||||
else if (proto == PPPCHAP)
|
else if (proto == PPPCHAP)
|
||||||
{
|
{
|
||||||
session[s].last_packet = time_now;
|
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; }
|
if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port, indexudpfd); return; }
|
||||||
processchap(s, t, p, l);
|
processchap(s, t, p, l);
|
||||||
}
|
}
|
||||||
else if (proto == PPPLCP)
|
else if (proto == PPPLCP)
|
||||||
{
|
{
|
||||||
session[s].last_packet = time_now;
|
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; }
|
if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port, indexudpfd); return; }
|
||||||
processlcp(s, t, p, l);
|
processlcp(s, t, p, l);
|
||||||
}
|
}
|
||||||
else if (proto == PPPIPCP)
|
else if (proto == PPPIPCP)
|
||||||
{
|
{
|
||||||
session[s].last_packet = time_now;
|
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; }
|
if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port, indexudpfd); return; }
|
||||||
processipcp(s, t, p, l);
|
processipcp(s, t, p, l);
|
||||||
}
|
}
|
||||||
else if (proto == PPPIPV6CP && config->ipv6_prefix.s6_addr[0])
|
else if (proto == PPPIPV6CP && config->ipv6_prefix.s6_addr[0])
|
||||||
{
|
{
|
||||||
session[s].last_packet = time_now;
|
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; }
|
if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port, indexudpfd); return; }
|
||||||
processipv6cp(s, t, p, l);
|
processipv6cp(s, t, p, l);
|
||||||
}
|
}
|
||||||
else if (proto == PPPCCP)
|
else if (proto == PPPCCP)
|
||||||
{
|
{
|
||||||
session[s].last_packet = time_now;
|
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; }
|
if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port, indexudpfd); return; }
|
||||||
processccp(s, t, p, l);
|
processccp(s, t, p, l);
|
||||||
}
|
}
|
||||||
else if (proto == PPPIP)
|
else if (proto == PPPIP)
|
||||||
|
|
@ -3336,7 +3349,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
session[s].last_packet = session[s].last_data = time_now;
|
session[s].last_packet = session[s].last_data = time_now;
|
||||||
if (session[s].walled_garden && !config->cluster_iam_master)
|
if (session[s].walled_garden && !config->cluster_iam_master)
|
||||||
{
|
{
|
||||||
master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port);
|
master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port, indexudpfd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3354,7 +3367,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
if (!config->cluster_iam_master)
|
if (!config->cluster_iam_master)
|
||||||
{
|
{
|
||||||
// The fragments reconstruction is managed by the Master.
|
// The fragments reconstruction is managed by the Master.
|
||||||
master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port);
|
master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port, indexudpfd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3371,7 +3384,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
session[s].last_packet = session[s].last_data = time_now;
|
session[s].last_packet = session[s].last_data = time_now;
|
||||||
if (session[s].walled_garden && !config->cluster_iam_master)
|
if (session[s].walled_garden && !config->cluster_iam_master)
|
||||||
{
|
{
|
||||||
master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port);
|
master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port, indexudpfd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3380,7 +3393,7 @@ void processudp(uint8_t *buf, int len, struct sockaddr_in *addr)
|
||||||
else if (session[s].ppp.lcp == Opened)
|
else if (session[s].ppp.lcp == Opened)
|
||||||
{
|
{
|
||||||
session[s].last_packet = time_now;
|
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; }
|
if (!config->cluster_iam_master) { master_forward_packet(buf, len, addr->sin_addr.s_addr, addr->sin_port, indexudpfd); return; }
|
||||||
protoreject(s, t, p, l, proto);
|
protoreject(s, t, p, l, proto);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -3949,13 +3962,8 @@ static int still_busy(void)
|
||||||
# include "fake_epoll.h"
|
# include "fake_epoll.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LAC
|
// the base set of fds polled: cli, cluster, tun, udp (MAX_UDPFD), control, dae, netlink, udplac, pppoedisc, pppoesess
|
||||||
// the base set of fds polled: cli, cluster, tun, udp, control, dae, netlink, udplac, pppoedisc, pppoesess
|
#define BASE_FDS (9 + MAX_UDPFD)
|
||||||
#define BASE_FDS 10
|
|
||||||
#else
|
|
||||||
// the base set of fds polled: cli, cluster, tun, udp, control, dae, netlink, pppoedisc, pppoesess
|
|
||||||
#define BASE_FDS 9
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// additional polled fds
|
// additional polled fds
|
||||||
#ifdef BGP
|
#ifdef BGP
|
||||||
|
|
@ -3967,7 +3975,7 @@ static int still_busy(void)
|
||||||
// main loop - gets packets on tun or udp and processes them
|
// main loop - gets packets on tun or udp and processes them
|
||||||
static void mainloop(void)
|
static void mainloop(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i, j;
|
||||||
uint8_t buf[65536];
|
uint8_t buf[65536];
|
||||||
uint8_t *p = buf + 32; // for the hearder of the forwarded MPPP packet (see C_MPPP_FORWARD)
|
uint8_t *p = buf + 32; // for the hearder of the forwarded MPPP packet (see C_MPPP_FORWARD)
|
||||||
// and the forwarded pppoe session
|
// and the forwarded pppoe session
|
||||||
|
|
@ -3982,13 +3990,8 @@ static void mainloop(void)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
LOG(4, 0, 0, "Beginning of main loop. clifd=%d, cluster_sockfd=%d, tunfd=%d, udpfd=%d, controlfd=%d, daefd=%d, nlfd=%d , udplacfd=%d, pppoefd=%d, pppoesessfd=%d\n",
|
LOG(4, 0, 0, "Beginning of main loop. clifd=%d, cluster_sockfd=%d, tunfd=%d, udpfd=%d, controlfd=%d, daefd=%d, nlfd=%d , udplacfd=%d, pppoefd=%d, pppoesessfd=%d\n",
|
||||||
clifd, cluster_sockfd, tunfd, udpfd, controlfd, daefd, nlfd, udplacfd, pppoediscfd, pppoesessfd);
|
clifd, cluster_sockfd, tunfd, udpfd[0], controlfd, daefd, nlfd, udplacfd, pppoediscfd, pppoesessfd);
|
||||||
#else
|
|
||||||
LOG(4, 0, 0, "Beginning of main loop. clifd=%d, cluster_sockfd=%d, tunfd=%d, udpfd=%d, controlfd=%d, daefd=%d, nlfd=%d, pppoefd=%d, pppoesessfd=%d\n",
|
|
||||||
clifd, cluster_sockfd, tunfd, udpfd, controlfd, daefd, nlfd, pppoediscfd, pppoesessfd);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* setup our fds to poll for input */
|
/* setup our fds to poll for input */
|
||||||
{
|
{
|
||||||
|
|
@ -4013,10 +4016,6 @@ static void mainloop(void)
|
||||||
e.data.ptr = &d[i++];
|
e.data.ptr = &d[i++];
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, tunfd, &e);
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, tunfd, &e);
|
||||||
|
|
||||||
d[i].type = FD_TYPE_UDP;
|
|
||||||
e.data.ptr = &d[i++];
|
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, udpfd, &e);
|
|
||||||
|
|
||||||
d[i].type = FD_TYPE_CONTROL;
|
d[i].type = FD_TYPE_CONTROL;
|
||||||
e.data.ptr = &d[i++];
|
e.data.ptr = &d[i++];
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, controlfd, &e);
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, controlfd, &e);
|
||||||
|
|
@ -4029,12 +4028,6 @@ static void mainloop(void)
|
||||||
e.data.ptr = &d[i++];
|
e.data.ptr = &d[i++];
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, nlfd, &e);
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, nlfd, &e);
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
d[i].type = FD_TYPE_UDPLAC;
|
|
||||||
e.data.ptr = &d[i++];
|
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, udplacfd, &e);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
d[i].type = FD_TYPE_PPPOEDISC;
|
d[i].type = FD_TYPE_PPPOEDISC;
|
||||||
e.data.ptr = &d[i++];
|
e.data.ptr = &d[i++];
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, pppoediscfd, &e);
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, pppoediscfd, &e);
|
||||||
|
|
@ -4042,6 +4035,14 @@ static void mainloop(void)
|
||||||
d[i].type = FD_TYPE_PPPOESESS;
|
d[i].type = FD_TYPE_PPPOESESS;
|
||||||
e.data.ptr = &d[i++];
|
e.data.ptr = &d[i++];
|
||||||
epoll_ctl(epollfd, EPOLL_CTL_ADD, pppoesessfd, &e);
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, pppoesessfd, &e);
|
||||||
|
|
||||||
|
for (j = 0; j < config->nbudpfd; j++)
|
||||||
|
{
|
||||||
|
d[i].type = FD_TYPE_UDP;
|
||||||
|
d[i].index = j;
|
||||||
|
e.data.ptr = &d[i++];
|
||||||
|
epoll_ctl(epollfd, EPOLL_CTL_ADD, udpfd[j], &e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BGP
|
#ifdef BGP
|
||||||
|
|
@ -4103,16 +4104,12 @@ static void mainloop(void)
|
||||||
struct in_addr local;
|
struct in_addr local;
|
||||||
socklen_t alen;
|
socklen_t alen;
|
||||||
int c, s;
|
int c, s;
|
||||||
int udp_ready = 0;
|
int udp_ready[MAX_UDPFD + 1] = INIT_TABUDPVAR;
|
||||||
#ifdef LAC
|
|
||||||
int udplac_ready = 0;
|
|
||||||
int udplac_pkts = 0;
|
|
||||||
#endif
|
|
||||||
int pppoesess_ready = 0;
|
int pppoesess_ready = 0;
|
||||||
int pppoesess_pkts = 0;
|
int pppoesess_pkts = 0;
|
||||||
int tun_ready = 0;
|
int tun_ready = 0;
|
||||||
int cluster_ready = 0;
|
int cluster_ready = 0;
|
||||||
int udp_pkts = 0;
|
int udp_pkts[MAX_UDPFD + 1] = INIT_TABUDPVAR;
|
||||||
int tun_pkts = 0;
|
int tun_pkts = 0;
|
||||||
int cluster_pkts = 0;
|
int cluster_pkts = 0;
|
||||||
#ifdef BGP
|
#ifdef BGP
|
||||||
|
|
@ -4146,10 +4143,7 @@ static void mainloop(void)
|
||||||
// these are handled below, with multiple interleaved reads
|
// these are handled below, with multiple interleaved reads
|
||||||
case FD_TYPE_CLUSTER: cluster_ready++; break;
|
case FD_TYPE_CLUSTER: cluster_ready++; break;
|
||||||
case FD_TYPE_TUN: tun_ready++; break;
|
case FD_TYPE_TUN: tun_ready++; break;
|
||||||
case FD_TYPE_UDP: udp_ready++; break;
|
case FD_TYPE_UDP: udp_ready[d->index]++; break;
|
||||||
#ifdef LAC
|
|
||||||
case FD_TYPE_UDPLAC: udplac_ready++; break;
|
|
||||||
#endif
|
|
||||||
case FD_TYPE_PPPOESESS: pppoesess_ready++; break;
|
case FD_TYPE_PPPOESESS: pppoesess_ready++; break;
|
||||||
|
|
||||||
case FD_TYPE_PPPOEDISC: // pppoe discovery
|
case FD_TYPE_PPPOEDISC: // pppoe discovery
|
||||||
|
|
@ -4190,8 +4184,8 @@ static void mainloop(void)
|
||||||
|
|
||||||
#ifdef BGP
|
#ifdef BGP
|
||||||
case FD_TYPE_BGP:
|
case FD_TYPE_BGP:
|
||||||
bgp_events[d->index] = events[i].events;
|
bgp_events[d->index] = events[i].events;
|
||||||
n--;
|
n--;
|
||||||
break;
|
break;
|
||||||
#endif /* BGP */
|
#endif /* BGP */
|
||||||
|
|
||||||
|
|
@ -4210,7 +4204,6 @@ static void mainloop(void)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
||||||
LOG(0, 0, 0, "Got a netlink error: %s\n", strerror(-errmsg->error));
|
LOG(0, 0, 0, "Got a netlink error: %s\n", strerror(-errmsg->error));
|
||||||
}
|
}
|
||||||
// else it's a ack
|
// else it's a ack
|
||||||
|
|
@ -4222,7 +4215,7 @@ static void mainloop(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG(0, 0, 0, "Unexpected fd type returned from epoll_wait: %d\n", d->type);
|
LOG(0, 0, 0, "Unexpected fd type returned from epoll_wait: %d\n", d->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4232,40 +4225,25 @@ static void mainloop(void)
|
||||||
|
|
||||||
for (c = 0; n && c < config->multi_read_count; c++)
|
for (c = 0; n && c < config->multi_read_count; c++)
|
||||||
{
|
{
|
||||||
// L2TP
|
for (j = 0; j < config->nbudpfd; j++)
|
||||||
if (udp_ready)
|
|
||||||
{
|
{
|
||||||
alen = sizeof(addr);
|
// L2TP and L2TP REMOTE LNS
|
||||||
if ((s = recvfrom(udpfd, p, size_bufp, 0, (void *) &addr, &alen)) > 0)
|
if (udp_ready[j])
|
||||||
{
|
{
|
||||||
processudp(p, s, &addr);
|
alen = sizeof(addr);
|
||||||
udp_pkts++;
|
if ((s = recvfrom(udpfd[j], p, size_bufp, 0, (void *) &addr, &alen)) > 0)
|
||||||
}
|
{
|
||||||
else
|
processudp(p, s, &addr, j);
|
||||||
{
|
udp_pkts[j]++;
|
||||||
udp_ready = 0;
|
}
|
||||||
n--;
|
else
|
||||||
|
{
|
||||||
|
udp_ready[j] = 0;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef LAC
|
|
||||||
// L2TP REMOTE LNS
|
|
||||||
if (udplac_ready)
|
|
||||||
{
|
|
||||||
alen = sizeof(addr);
|
|
||||||
if ((s = recvfrom(udplacfd, p, size_bufp, 0, (void *) &addr, &alen)) > 0)
|
|
||||||
{
|
|
||||||
if (!config->disable_lac_func)
|
|
||||||
processudp(p, s, &addr);
|
|
||||||
|
|
||||||
udplac_pkts++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
udplac_ready = 0;
|
|
||||||
n--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// incoming IP
|
// incoming IP
|
||||||
if (tun_ready)
|
if (tun_ready)
|
||||||
{
|
{
|
||||||
|
|
@ -4313,18 +4291,13 @@ static void mainloop(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (udp_pkts > 1 || tun_pkts > 1 || cluster_pkts > 1)
|
if (udp_pkts[0] > 1 || tun_pkts > 1 || cluster_pkts > 1)
|
||||||
STAT(multi_read_used);
|
STAT(multi_read_used);
|
||||||
|
|
||||||
if (c >= config->multi_read_count)
|
if (c >= config->multi_read_count)
|
||||||
{
|
{
|
||||||
#ifdef LAC
|
|
||||||
LOG(3, 0, 0, "Reached multi_read_count (%d); processed %d udp, %d tun %d cluster %d rmlns and %d pppoe packets\n",
|
|
||||||
config->multi_read_count, udp_pkts, tun_pkts, cluster_pkts, udplac_pkts, pppoesess_pkts);
|
|
||||||
#else
|
|
||||||
LOG(3, 0, 0, "Reached multi_read_count (%d); processed %d udp, %d tun %d cluster and %d pppoe packets\n",
|
LOG(3, 0, 0, "Reached multi_read_count (%d); processed %d udp, %d tun %d cluster and %d pppoe packets\n",
|
||||||
config->multi_read_count, udp_pkts, tun_pkts, cluster_pkts, pppoesess_pkts);
|
config->multi_read_count, udp_pkts[0], tun_pkts, cluster_pkts, pppoesess_pkts);
|
||||||
#endif
|
|
||||||
STAT(multi_read_exceeded);
|
STAT(multi_read_exceeded);
|
||||||
more++;
|
more++;
|
||||||
}
|
}
|
||||||
|
|
@ -4659,9 +4632,7 @@ static void initdata(int optdebug, char *optconfig)
|
||||||
}
|
}
|
||||||
#endif /* BGP */
|
#endif /* BGP */
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
lac_initremotelnsdata();
|
lac_initremotelnsdata();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int assign_ip_address(sessionidt s)
|
static int assign_ip_address(sessionidt s)
|
||||||
|
|
@ -4948,11 +4919,7 @@ void snoop_send_packet(uint8_t *packet, uint16_t size, in_addr_t destination, ui
|
||||||
|
|
||||||
static int dump_session(FILE **f, sessiont *s)
|
static int dump_session(FILE **f, sessiont *s)
|
||||||
{
|
{
|
||||||
#ifdef LAC
|
|
||||||
if (!s->opened || (!s->ip && !s->forwardtosession) || !(s->cin_delta || s->cout_delta) || !*s->user || s->walled_garden)
|
if (!s->opened || (!s->ip && !s->forwardtosession) || !(s->cin_delta || s->cout_delta) || !*s->user || s->walled_garden)
|
||||||
#else
|
|
||||||
if (!s->opened || !s->ip || !(s->cin_delta || s->cout_delta) || !*s->user || s->walled_garden)
|
|
||||||
#endif
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!*f)
|
if (!*f)
|
||||||
|
|
@ -4978,7 +4945,7 @@ static int dump_session(FILE **f, sessiont *s)
|
||||||
"# uptime: %ld\n"
|
"# uptime: %ld\n"
|
||||||
"# format: username ip qos uptxoctets downrxoctets\n",
|
"# format: username ip qos uptxoctets downrxoctets\n",
|
||||||
hostname,
|
hostname,
|
||||||
fmtaddr(config->iftun_address ? config->iftun_address : my_address, 0),
|
fmtaddr(config->iftun_n_address[tunnel[s->tunnel].indexudp] ? config->iftun_n_address[tunnel[s->tunnel].indexudp] : my_address, 0),
|
||||||
now,
|
now,
|
||||||
now - basetime);
|
now - basetime);
|
||||||
}
|
}
|
||||||
|
|
@ -5132,7 +5099,26 @@ int main(int argc, char *argv[])
|
||||||
init_pppoe();
|
init_pppoe();
|
||||||
LOG(1, 0, 0, "Set up on pppoe interface %s\n", config->pppoe_if_to_bind);
|
LOG(1, 0, 0, "Set up on pppoe interface %s\n", config->pppoe_if_to_bind);
|
||||||
}
|
}
|
||||||
initudp();
|
|
||||||
|
if (!config->nbmultiaddress)
|
||||||
|
{
|
||||||
|
config->bind_n_address[0] = config->bind_address;
|
||||||
|
config->nbmultiaddress++;
|
||||||
|
}
|
||||||
|
config->nbudpfd = config->nbmultiaddress;
|
||||||
|
for (i = 0; i < config->nbudpfd; i++)
|
||||||
|
initudp(&udpfd[i], config->bind_n_address[i]);
|
||||||
|
initlacudp();
|
||||||
|
config->indexlacudpfd = config->nbudpfd;
|
||||||
|
udpfd[config->indexlacudpfd] = udplacfd;
|
||||||
|
config->nbudpfd++;
|
||||||
|
|
||||||
|
initcontrol();
|
||||||
|
initdae();
|
||||||
|
|
||||||
|
// Intercept
|
||||||
|
snoopfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
|
||||||
initrad();
|
initrad();
|
||||||
initippool();
|
initippool();
|
||||||
|
|
||||||
|
|
@ -5364,14 +5350,62 @@ static void update_config()
|
||||||
if (!config->radius_dae_port)
|
if (!config->radius_dae_port)
|
||||||
config->radius_dae_port = DAEPORT;
|
config->radius_dae_port = DAEPORT;
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
if(!config->bind_portremotelns)
|
if(!config->bind_portremotelns)
|
||||||
config->bind_portremotelns = L2TPLACPORT;
|
config->bind_portremotelns = L2TPLACPORT;
|
||||||
if(!config->bind_address_remotelns)
|
if(!config->bind_address_remotelns)
|
||||||
config->bind_address_remotelns = INADDR_ANY;
|
config->bind_address_remotelns = INADDR_ANY;
|
||||||
#endif
|
|
||||||
|
if (*config->bind_multi_address)
|
||||||
|
{
|
||||||
|
char *sip = config->bind_multi_address;
|
||||||
|
char *n = sip;
|
||||||
|
char *e = config->bind_multi_address + strlen(config->bind_multi_address);
|
||||||
|
config->nbmultiaddress = 0;
|
||||||
|
|
||||||
|
while (*sip && (sip < e))
|
||||||
|
{
|
||||||
|
in_addr_t ip = 0;
|
||||||
|
uint8_t u = 0;
|
||||||
|
|
||||||
|
while (n < e && (*n == ',' || *n == ' ')) n++;
|
||||||
|
|
||||||
|
while (n < e && (isdigit(*n) || *n == '.'))
|
||||||
|
{
|
||||||
|
if (*n == '.')
|
||||||
|
{
|
||||||
|
ip = (ip << 8) + u;
|
||||||
|
u = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
u = u * 10 + *n - '0';
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
ip = (ip << 8) + u;
|
||||||
|
n++;
|
||||||
|
|
||||||
|
if (ip)
|
||||||
|
{
|
||||||
|
config->bind_n_address[config->nbmultiaddress] = htonl(ip);
|
||||||
|
config->iftun_n_address[config->nbmultiaddress] = htonl(ip);
|
||||||
|
config->nbmultiaddress++;
|
||||||
|
LOG(1, 0, 0, "Bind address %s\n", fmtaddr(htonl(ip), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
sip = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config->nbmultiaddress >= 1)
|
||||||
|
{
|
||||||
|
config->bind_address = config->bind_n_address[0];
|
||||||
|
config->iftun_address = config->bind_address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!config->iftun_address)
|
if(!config->iftun_address)
|
||||||
|
{
|
||||||
config->iftun_address = config->bind_address;
|
config->iftun_address = config->bind_address;
|
||||||
|
config->iftun_n_address[0] = config->iftun_address;
|
||||||
|
}
|
||||||
|
|
||||||
if (!*config->pppoe_ac_name)
|
if (!*config->pppoe_ac_name)
|
||||||
strncpy(config->pppoe_ac_name, DEFAULT_PPPOE_AC_NAME, sizeof(config->pppoe_ac_name) - 1);
|
strncpy(config->pppoe_ac_name, DEFAULT_PPPOE_AC_NAME, sizeof(config->pppoe_ac_name) - 1);
|
||||||
|
|
@ -6429,8 +6463,6 @@ int ip_filter(uint8_t *buf, int len, uint8_t filter)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
|
|
||||||
tunnelidt lac_new_tunnel()
|
tunnelidt lac_new_tunnel()
|
||||||
{
|
{
|
||||||
return new_tunnel();
|
return new_tunnel();
|
||||||
|
|
@ -6476,4 +6508,3 @@ void lac_tunnelshutdown(tunnelidt t, char *reason, int result, int error, char *
|
||||||
tunnelshutdown(t, reason, result, error, msg);
|
tunnelshutdown(t, reason, result, error, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
38
l2tpns.h
38
l2tpns.h
|
|
@ -66,6 +66,13 @@
|
||||||
// it's not expected to have a space for more than 10 unassembled packets = 10 * MAXBUNDLESES
|
// it's not expected to have a space for more than 10 unassembled packets = 10 * MAXBUNDLESES
|
||||||
#define MAXFRAGNUM_MASK (MAXFRAGNUM - 1) // Must be equal to MAXFRAGNUM-1
|
#define MAXFRAGNUM_MASK (MAXFRAGNUM - 1) // Must be equal to MAXFRAGNUM-1
|
||||||
|
|
||||||
|
// Multi bind address constants
|
||||||
|
#define MAX_UDPFD 4
|
||||||
|
#define MAX_BINDADDR MAX_UDPFD
|
||||||
|
// 4 + 1 for the udplac
|
||||||
|
#define INIT_TABUDPFD {-1, -1, -1, -1, -1}
|
||||||
|
#define INIT_TABUDPVAR {0, 0, 0, 0, 0}
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
#ifndef ETCDIR
|
#ifndef ETCDIR
|
||||||
#define ETCDIR "/etc/l2tpns"
|
#define ETCDIR "/etc/l2tpns"
|
||||||
|
|
@ -322,14 +329,9 @@ typedef struct
|
||||||
char class[MAXCLASS];
|
char class[MAXCLASS];
|
||||||
uint8_t ipv6prefixlen; // IPv6 route prefix length
|
uint8_t ipv6prefixlen; // IPv6 route prefix length
|
||||||
struct in6_addr ipv6route; // Static IPv6 route
|
struct in6_addr ipv6route; // Static IPv6 route
|
||||||
#ifdef LAC
|
|
||||||
sessionidt forwardtosession; // LNS id_session to forward
|
sessionidt forwardtosession; // LNS id_session to forward
|
||||||
uint8_t src_hwaddr[ETH_ALEN]; // MAC addr source (for pppoe sessions 6 bytes)
|
uint8_t src_hwaddr[ETH_ALEN]; // MAC addr source (for pppoe sessions 6 bytes)
|
||||||
char reserved[4]; // Space to expand structure without changing HB_VERSION
|
char reserved[4]; // Space to expand structure without changing HB_VERSION
|
||||||
#else
|
|
||||||
uint8_t src_hwaddr[ETH_ALEN]; // MAC addr source (for pppoe sessions 6 bytes)
|
|
||||||
char reserved[6]; // Space to expand structure without changing HB_VERSION
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
sessiont;
|
sessiont;
|
||||||
|
|
||||||
|
|
@ -449,12 +451,9 @@ typedef struct
|
||||||
uint16_t controlc; // outstaind messages in queue
|
uint16_t controlc; // outstaind messages in queue
|
||||||
controlt *controls; // oldest message
|
controlt *controls; // oldest message
|
||||||
controlt *controle; // newest message
|
controlt *controle; // newest message
|
||||||
#ifdef LAC
|
|
||||||
uint16_t isremotelns; // != 0 if the tunnel is to remote LNS (== index on the conf remote lns)
|
uint16_t isremotelns; // != 0 if the tunnel is to remote LNS (== index on the conf remote lns)
|
||||||
char reserved[14]; // Space to expand structure without changing HB_VERSION
|
uint16_t indexudp; // Index UDP file handle (in udpfd[])
|
||||||
#else
|
char reserved[12]; // Space to expand structure without changing HB_VERSION
|
||||||
char reserved[16]; // Space to expand structure without changing HB_VERSION
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
tunnelt;
|
tunnelt;
|
||||||
|
|
||||||
|
|
@ -765,19 +764,23 @@ typedef struct
|
||||||
int idle_echo_timeout; // Time between last packet seen and
|
int idle_echo_timeout; // Time between last packet seen and
|
||||||
// Drop sessions who have not responded within IDLE_ECHO_TIMEOUT seconds
|
// Drop sessions who have not responded within IDLE_ECHO_TIMEOUT seconds
|
||||||
in_addr_t iftun_address;
|
in_addr_t iftun_address;
|
||||||
#ifdef LAC
|
|
||||||
int disable_lac_func;
|
int disable_lac_func;
|
||||||
int auth_tunnel_change_addr_src;
|
int auth_tunnel_change_addr_src;
|
||||||
int highest_rlnsid;
|
int highest_rlnsid;
|
||||||
uint16_t bind_portremotelns;
|
uint16_t bind_portremotelns;
|
||||||
in_addr_t bind_address_remotelns;
|
in_addr_t bind_address_remotelns;
|
||||||
#endif
|
|
||||||
char pppoe_if_to_bind[IFNAMSIZ]; // Name pppoe interface to bind
|
char pppoe_if_to_bind[IFNAMSIZ]; // Name pppoe interface to bind
|
||||||
char pppoe_service_name[64]; // pppoe service name
|
char pppoe_service_name[64]; // pppoe service name
|
||||||
char pppoe_ac_name[64];
|
char pppoe_ac_name[64];
|
||||||
uint8_t pppoe_hwaddr[ETH_ALEN]; // MAC addr of interface pppoe to bind
|
uint8_t pppoe_hwaddr[ETH_ALEN]; // MAC addr of interface pppoe to bind
|
||||||
int disable_sending_hello; // Disable l2tp sending HELLO message for Apple compatibility.
|
int disable_sending_hello; // Disable l2tp sending HELLO message for Apple compatibility.
|
||||||
int disable_no_spoof; // Disable no spoof (permit load balancing client --> internet)
|
int disable_no_spoof; // Disable no spoof (permit load balancing client --> internet)
|
||||||
|
int nbudpfd; // number UDP file handle
|
||||||
|
int nbmultiaddress; // number multi address to bind
|
||||||
|
int indexlacudpfd; // Index UDP LAC file handle (in udpfd[])
|
||||||
|
in_addr_t bind_n_address[MAX_BINDADDR];
|
||||||
|
in_addr_t iftun_n_address[MAX_BINDADDR];
|
||||||
|
char bind_multi_address[256];
|
||||||
} configt;
|
} configt;
|
||||||
|
|
||||||
enum config_typet { INT, STRING, UNSIGNED_LONG, SHORT, BOOL, IPv4, IPv6 };
|
enum config_typet { INT, STRING, UNSIGNED_LONG, SHORT, BOOL, IPv4, IPv6 };
|
||||||
|
|
@ -913,9 +916,7 @@ void radiusretry(uint16_t r);
|
||||||
uint16_t radiusnew(sessionidt s);
|
uint16_t radiusnew(sessionidt s);
|
||||||
void radiusclear(uint16_t r, sessionidt s);
|
void radiusclear(uint16_t r, sessionidt s);
|
||||||
void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen, struct in_addr *local);
|
void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen, struct in_addr *local);
|
||||||
#ifdef LAC
|
|
||||||
int rad_tunnel_pwdecode(uint8_t *pl2tpsecret, size_t *pl2tpsecretlen, const char *radiussecret, const uint8_t * auth);
|
int rad_tunnel_pwdecode(uint8_t *pl2tpsecret, size_t *pl2tpsecretlen, const char *radiussecret, const uint8_t * auth);
|
||||||
#endif
|
|
||||||
|
|
||||||
// l2tpns.c
|
// l2tpns.c
|
||||||
clockt backoff(uint8_t try);
|
clockt backoff(uint8_t try);
|
||||||
|
|
@ -935,7 +936,7 @@ int tun_write(uint8_t *data, int size);
|
||||||
void adjust_tcp_mss(sessionidt s, tunnelidt t, uint8_t *buf, int len, uint8_t *tcp);
|
void adjust_tcp_mss(sessionidt s, tunnelidt t, uint8_t *buf, int len, uint8_t *tcp);
|
||||||
void sendipcp(sessionidt s, tunnelidt t);
|
void sendipcp(sessionidt s, tunnelidt t);
|
||||||
void sendipv6cp(sessionidt s, tunnelidt t);
|
void sendipv6cp(sessionidt s, tunnelidt t);
|
||||||
void processudp(uint8_t *buf, int len, struct sockaddr_in *addr);
|
void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexudpfd);
|
||||||
void processipout(uint8_t *buf, int len);
|
void processipout(uint8_t *buf, int len);
|
||||||
void snoop_send_packet(uint8_t *packet, uint16_t size, in_addr_t destination, uint16_t port);
|
void snoop_send_packet(uint8_t *packet, uint16_t size, in_addr_t destination, uint16_t port);
|
||||||
int find_filter(char const *name, size_t len);
|
int find_filter(char const *name, size_t len);
|
||||||
|
|
@ -943,13 +944,11 @@ int ip_filter(uint8_t *buf, int len, uint8_t filter);
|
||||||
int cmd_show_ipcache(struct cli_def *cli, char *command, char **argv, int argc);
|
int cmd_show_ipcache(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
int cmd_show_hist_idle(struct cli_def *cli, char *command, char **argv, int argc);
|
int cmd_show_hist_idle(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
int cmd_show_hist_open(struct cli_def *cli, char *command, char **argv, int argc);
|
int cmd_show_hist_open(struct cli_def *cli, char *command, char **argv, int argc);
|
||||||
#ifdef LAC
|
|
||||||
tunnelidt lac_new_tunnel();
|
tunnelidt lac_new_tunnel();
|
||||||
void lac_tunnelclear(tunnelidt t);
|
void lac_tunnelclear(tunnelidt t);
|
||||||
void lac_send_SCCRQ(tunnelidt t, uint8_t * auth, unsigned int auth_len);
|
void lac_send_SCCRQ(tunnelidt t, uint8_t * auth, unsigned int auth_len);
|
||||||
void lac_send_ICRQ(tunnelidt t, sessionidt s);
|
void lac_send_ICRQ(tunnelidt t, sessionidt s);
|
||||||
void lac_tunnelshutdown(tunnelidt t, char *reason, int result, int error, char *msg);
|
void lac_tunnelshutdown(tunnelidt t, char *reason, int result, int error, char *msg);
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef LOG
|
#undef LOG
|
||||||
#undef LOG_HEX
|
#undef LOG_HEX
|
||||||
|
|
@ -1009,13 +1008,10 @@ struct event_data {
|
||||||
FD_TYPE_RADIUS,
|
FD_TYPE_RADIUS,
|
||||||
FD_TYPE_BGP,
|
FD_TYPE_BGP,
|
||||||
FD_TYPE_NETLINK,
|
FD_TYPE_NETLINK,
|
||||||
#ifdef LAC
|
|
||||||
FD_TYPE_UDPLAC,
|
|
||||||
#endif
|
|
||||||
FD_TYPE_PPPOEDISC,
|
FD_TYPE_PPPOEDISC,
|
||||||
FD_TYPE_PPPOESESS
|
FD_TYPE_PPPOESESS
|
||||||
} type;
|
} type;
|
||||||
int index; // for RADIUS, BGP
|
int index; // for RADIUS, BGP, UDP
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TIME (config->current_time)
|
#define TIME (config->current_time)
|
||||||
|
|
|
||||||
6
ppp.c
6
ppp.c
|
|
@ -12,9 +12,7 @@
|
||||||
#include "tbf.h"
|
#include "tbf.h"
|
||||||
#include "cluster.h"
|
#include "cluster.h"
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
#include "l2tplac.h"
|
#include "l2tplac.h"
|
||||||
#endif
|
|
||||||
#include "pppoe.h"
|
#include "pppoe.h"
|
||||||
|
|
||||||
extern tunnelt *tunnel;
|
extern tunnelt *tunnel;
|
||||||
|
|
@ -105,13 +103,11 @@ void processpap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
LOG(3, s, t, "PAP login %s/%s\n", user, pass);
|
LOG(3, s, t, "PAP login %s/%s\n", user, pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
if ((!config->disable_lac_func) && lac_conf_forwardtoremotelns(s, user))
|
if ((!config->disable_lac_func) && lac_conf_forwardtoremotelns(s, user))
|
||||||
{
|
{
|
||||||
// Creating a tunnel/session has been started
|
// Creating a tunnel/session has been started
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (session[s].ip || !(r = radiusnew(s)))
|
if (session[s].ip || !(r = radiusnew(s)))
|
||||||
{
|
{
|
||||||
|
|
@ -264,7 +260,6 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
packet.username = calloc(l + 1, 1);
|
packet.username = calloc(l + 1, 1);
|
||||||
memcpy(packet.username, p, l);
|
memcpy(packet.username, p, l);
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
if ((!config->disable_lac_func) && lac_conf_forwardtoremotelns(s, packet.username))
|
if ((!config->disable_lac_func) && lac_conf_forwardtoremotelns(s, packet.username))
|
||||||
{
|
{
|
||||||
free(packet.username);
|
free(packet.username);
|
||||||
|
|
@ -272,7 +267,6 @@ void processchap(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
|
||||||
// Creating a tunnel/session has been started
|
// Creating a tunnel/session has been started
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
run_plugins(PLUGIN_PRE_AUTH, &packet);
|
run_plugins(PLUGIN_PRE_AUTH, &packet);
|
||||||
if (!packet.continue_auth)
|
if (!packet.continue_auth)
|
||||||
|
|
|
||||||
4
pppoe.c
4
pppoe.c
|
|
@ -902,7 +902,6 @@ void process_pppoe_disc(uint8_t *pack, int size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
// Forward from pppoe to l2tp remote LNS
|
// Forward from pppoe to l2tp remote LNS
|
||||||
static void pppoe_forwardto_session_rmlns(uint8_t *pack, int size, sessionidt sess, uint16_t proto)
|
static void pppoe_forwardto_session_rmlns(uint8_t *pack, int size, sessionidt sess, uint16_t proto)
|
||||||
{
|
{
|
||||||
|
|
@ -1036,7 +1035,6 @@ void pppoe_forwardto_session_pppoe(uint8_t *pack, int size, sessionidt sess, uin
|
||||||
|
|
||||||
tunnelsend(p, lpppoe, t); // send it....
|
tunnelsend(p, lpppoe, t); // send it....
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void process_pppoe_sess(uint8_t *pack, int size)
|
void process_pppoe_sess(uint8_t *pack, int size)
|
||||||
{
|
{
|
||||||
|
|
@ -1101,13 +1099,11 @@ void process_pppoe_sess(uint8_t *pack, int size)
|
||||||
lppp -= 2;
|
lppp -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
if (session[sid].forwardtosession)
|
if (session[sid].forwardtosession)
|
||||||
{ // Must be forwaded to a remote lns tunnel l2tp
|
{ // Must be forwaded to a remote lns tunnel l2tp
|
||||||
pppoe_forwardto_session_rmlns(pack, size, sid, proto);
|
pppoe_forwardto_session_rmlns(pack, size, sid, proto);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (proto == PPPPAP)
|
if (proto == PPPPAP)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
13
radius.c
13
radius.c
|
|
@ -19,9 +19,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "cluster.h"
|
#include "cluster.h"
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
#include "l2tplac.h"
|
#include "l2tplac.h"
|
||||||
#endif
|
|
||||||
#include "pppoe.h"
|
#include "pppoe.h"
|
||||||
|
|
||||||
extern radiust *radius;
|
extern radiust *radius;
|
||||||
|
|
@ -537,9 +535,7 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
uint8_t routes = 0;
|
uint8_t routes = 0;
|
||||||
int r_code;
|
int r_code;
|
||||||
int r_id;
|
int r_id;
|
||||||
#ifdef LAC
|
|
||||||
int OpentunnelReq = 0;
|
int OpentunnelReq = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
CSTAT(processrad);
|
CSTAT(processrad);
|
||||||
|
|
||||||
|
|
@ -641,11 +637,10 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
// Extract IP, routes, etc
|
// Extract IP, routes, etc
|
||||||
uint8_t *p = buf + 20;
|
uint8_t *p = buf + 20;
|
||||||
uint8_t *e = buf + len;
|
uint8_t *e = buf + len;
|
||||||
#ifdef LAC
|
|
||||||
uint8_t tag;
|
uint8_t tag;
|
||||||
uint8_t strtemp[256];
|
uint8_t strtemp[256];
|
||||||
lac_reset_rad_tag_tunnel_ctxt();
|
lac_reset_rad_tag_tunnel_ctxt();
|
||||||
#endif
|
|
||||||
for (; p + 2 <= e && p[1] && p + p[1] <= e; p += p[1])
|
for (; p + 2 <= e && p[1] && p + p[1] <= e; p += p[1])
|
||||||
{
|
{
|
||||||
if (*p == 26 && p[1] >= 7)
|
if (*p == 26 && p[1] >= 7)
|
||||||
|
|
@ -840,7 +835,6 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
session[s].classlen = MAXCLASS;
|
session[s].classlen = MAXCLASS;
|
||||||
memcpy(session[s].class, p + 2, session[s].classlen);
|
memcpy(session[s].class, p + 2, session[s].classlen);
|
||||||
}
|
}
|
||||||
#ifdef LAC
|
|
||||||
else if (*p == 64)
|
else if (*p == 64)
|
||||||
{
|
{
|
||||||
// Tunnel-Type
|
// Tunnel-Type
|
||||||
|
|
@ -929,7 +923,6 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
// Fill context
|
// Fill context
|
||||||
lac_set_rad_tag_tunnel_assignment_id(tag, (char *) strtemp);
|
lac_set_rad_tag_tunnel_assignment_id(tag, (char *) strtemp);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (r_code == AccessReject)
|
else if (r_code == AccessReject)
|
||||||
|
|
@ -939,7 +932,6 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
if ((!config->disable_lac_func) && OpentunnelReq)
|
if ((!config->disable_lac_func) && OpentunnelReq)
|
||||||
{
|
{
|
||||||
char assignment_id[256];
|
char assignment_id[256];
|
||||||
|
|
@ -996,7 +988,6 @@ void processrad(uint8_t *buf, int len, char socket_index)
|
||||||
LOG(3, s, session[s].tunnel, " PAP User %s authentication %s.\n", session[s].user,
|
LOG(3, s, session[s].tunnel, " PAP User %s authentication %s.\n", session[s].user,
|
||||||
(r_code == AccessAccept) ? "allowed" : "denied");
|
(r_code == AccessAccept) ? "allowed" : "denied");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!session[s].dns1 && config->default_dns1)
|
if (!session[s].dns1 && config->default_dns1)
|
||||||
{
|
{
|
||||||
|
|
@ -1341,7 +1332,6 @@ void processdae(uint8_t *buf, int len, struct sockaddr_in *addr, int alen, struc
|
||||||
LOG(0, 0, 0, "Error sending DAE response packet: %s\n", strerror(errno));
|
LOG(0, 0, 0, "Error sending DAE response packet: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LAC
|
|
||||||
// Decrypte the encrypted Tunnel Password.
|
// Decrypte the encrypted Tunnel Password.
|
||||||
// Defined in RFC-2868.
|
// Defined in RFC-2868.
|
||||||
// the pl2tpsecret buffer must set to 256 characters.
|
// the pl2tpsecret buffer must set to 256 characters.
|
||||||
|
|
@ -1432,4 +1422,3 @@ int rad_tunnel_pwdecode(uint8_t *pl2tpsecret, size_t *pl2tpsecretlen,
|
||||||
|
|
||||||
return decodedlen;
|
return decodedlen;
|
||||||
};
|
};
|
||||||
#endif /* LAC */
|
|
||||||
|
|
|
||||||
139
util.c
139
util.c
|
|
@ -51,100 +51,109 @@ void *shared_malloc(unsigned int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int forked;
|
extern int forked;
|
||||||
extern int cluster_sockfd, tunfd, udpfd, controlfd, daefd, snoopfd, ifrfd, ifr6fd, rand_fd;
|
extern int cluster_sockfd, tunfd, controlfd, daefd, snoopfd, ifrfd, ifr6fd, rand_fd;
|
||||||
|
extern int pppoediscfd, pppoesessfd;
|
||||||
extern int *radfds;
|
extern int *radfds;
|
||||||
|
extern int udpfd[MAX_UDPFD + 1];
|
||||||
|
|
||||||
pid_t fork_and_close()
|
pid_t fork_and_close()
|
||||||
{
|
{
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (pid)
|
if (pid)
|
||||||
return pid;
|
return pid;
|
||||||
|
|
||||||
forked++;
|
forked++;
|
||||||
if (config->scheduler_fifo)
|
if (config->scheduler_fifo)
|
||||||
{
|
|
||||||
struct sched_param params = {0};
|
|
||||||
params.sched_priority = 0;
|
|
||||||
if (sched_setscheduler(0, SCHED_OTHER, ¶ms))
|
|
||||||
{
|
{
|
||||||
LOG(0, 0, 0, "Error setting scheduler to OTHER after fork: %s\n", strerror(errno));
|
struct sched_param params = {0};
|
||||||
LOG(0, 0, 0, "This is probably really really bad.\n");
|
params.sched_priority = 0;
|
||||||
|
if (sched_setscheduler(0, SCHED_OTHER, ¶ms))
|
||||||
|
{
|
||||||
|
LOG(0, 0, 0, "Error setting scheduler to OTHER after fork: %s\n", strerror(errno));
|
||||||
|
LOG(0, 0, 0, "This is probably really really bad.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
signal(SIGPIPE, SIG_DFL);
|
signal(SIGPIPE, SIG_DFL);
|
||||||
signal(SIGCHLD, SIG_DFL);
|
signal(SIGCHLD, SIG_DFL);
|
||||||
signal(SIGHUP, SIG_DFL);
|
signal(SIGHUP, SIG_DFL);
|
||||||
signal(SIGUSR1, SIG_DFL);
|
signal(SIGUSR1, SIG_DFL);
|
||||||
signal(SIGQUIT, SIG_DFL);
|
signal(SIGQUIT, SIG_DFL);
|
||||||
signal(SIGKILL, SIG_DFL);
|
signal(SIGKILL, SIG_DFL);
|
||||||
signal(SIGTERM, SIG_DFL);
|
signal(SIGTERM, SIG_DFL);
|
||||||
|
|
||||||
// Close sockets
|
// Close sockets
|
||||||
if (clifd != -1) close(clifd);
|
if (clifd != -1) close(clifd);
|
||||||
if (cluster_sockfd != -1) close(cluster_sockfd);
|
if (cluster_sockfd != -1) close(cluster_sockfd);
|
||||||
if (tunfd != -1) close(tunfd);
|
if (tunfd != -1) close(tunfd);
|
||||||
if (udpfd != -1) close(udpfd);
|
|
||||||
if (controlfd != -1) close(controlfd);
|
|
||||||
if (daefd != -1) close(daefd);
|
|
||||||
if (snoopfd != -1) close(snoopfd);
|
|
||||||
if (rand_fd != -1) close(rand_fd);
|
|
||||||
if (epollfd != -1) close(epollfd);
|
|
||||||
|
|
||||||
for (i = 0; radfds && i < RADIUS_FDS; i++)
|
for (i = 0; i < config->nbudpfd; i++)
|
||||||
close(radfds[i]);
|
{
|
||||||
|
if (udpfd[i] != -1) close(udpfd[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pppoediscfd != -1) close(pppoediscfd);
|
||||||
|
if (pppoediscfd != -1) close(pppoediscfd);
|
||||||
|
if (controlfd != -1) close(controlfd);
|
||||||
|
if (daefd != -1) close(daefd);
|
||||||
|
if (snoopfd != -1) close(snoopfd);
|
||||||
|
if (rand_fd != -1) close(rand_fd);
|
||||||
|
if (epollfd != -1) close(epollfd);
|
||||||
|
|
||||||
|
for (i = 0; radfds && i < RADIUS_FDS; i++)
|
||||||
|
close(radfds[i]);
|
||||||
|
|
||||||
#ifdef BGP
|
#ifdef BGP
|
||||||
for (i = 0; i < BGP_NUM_PEERS; i++)
|
for (i = 0; i < BGP_NUM_PEERS; i++)
|
||||||
if (bgp_peers[i].sock != -1)
|
if (bgp_peers[i].sock != -1)
|
||||||
close(bgp_peers[i].sock);
|
close(bgp_peers[i].sock);
|
||||||
#endif /* BGP */
|
#endif /* BGP */
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t recvfromto(int s, void *buf, size_t len, int flags,
|
ssize_t recvfromto(int s, void *buf, size_t len, int flags,
|
||||||
struct sockaddr *from, socklen_t *fromlen, struct in_addr *toaddr)
|
struct sockaddr *from, socklen_t *fromlen, struct in_addr *toaddr)
|
||||||
{
|
{
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
struct iovec vec;
|
struct iovec vec;
|
||||||
char cbuf[128];
|
char cbuf[128];
|
||||||
|
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
msg.msg_name = from;
|
msg.msg_name = from;
|
||||||
msg.msg_namelen = *fromlen;
|
msg.msg_namelen = *fromlen;
|
||||||
|
|
||||||
vec.iov_base = buf;
|
vec.iov_base = buf;
|
||||||
vec.iov_len = len;
|
vec.iov_len = len;
|
||||||
msg.msg_iov = &vec;
|
msg.msg_iov = &vec;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
msg.msg_flags = 0;
|
msg.msg_flags = 0;
|
||||||
|
|
||||||
msg.msg_control = cbuf;
|
msg.msg_control = cbuf;
|
||||||
msg.msg_controllen = sizeof(cbuf);
|
msg.msg_controllen = sizeof(cbuf);
|
||||||
|
|
||||||
if ((r = recvmsg(s, &msg, flags)) < 0)
|
if ((r = recvmsg(s, &msg, flags)) < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (fromlen)
|
if (fromlen)
|
||||||
*fromlen = msg.msg_namelen;
|
*fromlen = msg.msg_namelen;
|
||||||
|
|
||||||
memset(toaddr, 0, sizeof(*toaddr));
|
memset(toaddr, 0, sizeof(*toaddr));
|
||||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
|
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
|
||||||
{
|
|
||||||
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_PKTINFO)
|
|
||||||
{
|
{
|
||||||
struct in_pktinfo *i = (struct in_pktinfo *) CMSG_DATA(cmsg);
|
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_PKTINFO)
|
||||||
memcpy(toaddr, &i->ipi_addr, sizeof(*toaddr));
|
{
|
||||||
break;
|
struct in_pktinfo *i = (struct in_pktinfo *) CMSG_DATA(cmsg);
|
||||||
|
memcpy(toaddr, &i->ipi_addr, sizeof(*toaddr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t sendtofrom(int s, void const *buf, size_t len, int flags,
|
ssize_t sendtofrom(int s, void const *buf, size_t len, int flags,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue