mirror of
https://github.com/ntop/n2n.git
synced 2024-04-21 16:31:34 +00:00
Merge pull request #317 from skyformat99/dev
add -n option (route) for windows
This commit is contained in:
+8
-8
@@ -124,8 +124,8 @@ static void help() {
|
||||
#endif /* #ifndef WIN32 */
|
||||
#ifdef __linux__
|
||||
"[-T <tos>]"
|
||||
"[-n cidr:gateway] "
|
||||
#endif
|
||||
"[-n cidr:gateway] "
|
||||
"[-m <MAC address>] "
|
||||
"-l <supernode host:port>\n"
|
||||
" "
|
||||
@@ -182,8 +182,8 @@ static void help() {
|
||||
printf("-S | Do not connect P2P. Always use the supernode.\n");
|
||||
#ifdef __linux__
|
||||
printf("-T <tos> | TOS for packets (e.g. 0x48 for SSH like priority)\n");
|
||||
printf("-n <cidr:gateway> | Route an IPv4 network via the gw. Use 0.0.0.0/0 for the default gw. Can be set multiple times.\n");
|
||||
#endif
|
||||
printf("-n <cidr:gateway> | Route an IPv4 network via the gw. Use 0.0.0.0/0 for the default gw. Can be set multiple times.\n");
|
||||
printf("-v | Make more verbose. Repeat as required.\n");
|
||||
printf("-t <port> | Management UDP Port (for multiple edges on a machine).\n");
|
||||
|
||||
@@ -443,6 +443,7 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case 'n':
|
||||
{
|
||||
@@ -480,7 +481,6 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case 's': /* Subnet Mask */
|
||||
{
|
||||
@@ -539,13 +539,13 @@ static const struct option long_options[] =
|
||||
static int loadFromCLI(int argc, char *argv[], n2n_edge_conf_t *conf, n2n_tuntap_priv_config_t *ec) {
|
||||
u_char c;
|
||||
|
||||
while((c = getopt_long(argc, argv,
|
||||
"k:a:bc:Eu:g:m:M:s:d:l:p:fvhrt:i:SDL:z::A::H"
|
||||
while ((c = getopt_long(argc, argv,
|
||||
"k:a:bc:Eu:g:m:M:s:d:l:p:fvhrt:i:SDL:z::A::Hn:"
|
||||
#ifdef __linux__
|
||||
"T:n:"
|
||||
"T:"
|
||||
#endif
|
||||
,
|
||||
long_options, NULL)) != '?') {
|
||||
,
|
||||
long_options, NULL)) != '?') {
|
||||
if(c == 255) break;
|
||||
setOption(c, optarg, ec, conf);
|
||||
}
|
||||
|
||||
+129
-84
@@ -2288,92 +2288,137 @@ static int routectl(int cmd, int flags, n2n_route_t *route, int if_idx) {
|
||||
* the TAP device is destroyed. */
|
||||
static int edge_init_routes(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes) {
|
||||
#ifdef __linux__
|
||||
int i;
|
||||
|
||||
for(i=0; i<num_routes; i++) {
|
||||
n2n_route_t *route = &routes[i];
|
||||
|
||||
if((route->net_addr == 0) && (route->net_bitlen == 0)) {
|
||||
/* This is a default gateway rule. We need to:
|
||||
*
|
||||
* 1. Add a route to the supernode via the host internet gateway
|
||||
* 2. Add the new default gateway route
|
||||
*
|
||||
* Instead of modifying the system default gateway, we use the trick
|
||||
* of adding a route to the networks 0.0.0.0/1 and 128.0.0.0/1, thus
|
||||
* covering the whole IPv4 range. Such routes in linux take precedence
|
||||
* over the default gateway (0.0.0.0/0) since are more specific.
|
||||
* This leaves the default gateway unchanged so that after n2n is
|
||||
* stopped the cleanup is easier.
|
||||
* See https://github.com/zerotier/ZeroTierOne/issues/178#issuecomment-204599227
|
||||
*/
|
||||
n2n_sock_t sn;
|
||||
n2n_route_t custom_route;
|
||||
uint32_t *a;
|
||||
|
||||
if(eee->sn_route_to_clean) {
|
||||
traceEvent(TRACE_ERROR, "Only one default gateway route allowed");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if(eee->conf.sn_num != 1) {
|
||||
traceEvent(TRACE_ERROR, "Only one supernode supported with routes");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if(supernode2addr(&sn, eee->conf.sn_ip_array[0]) < 0)
|
||||
return(-1);
|
||||
|
||||
if(sn.family != AF_INET) {
|
||||
traceEvent(TRACE_ERROR, "Only IPv4 routes supported");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
a = (u_int32_t*)sn.addr.v4;
|
||||
custom_route.net_addr = *a;
|
||||
custom_route.net_bitlen = 32;
|
||||
custom_route.gateway = get_gateway_ip();
|
||||
|
||||
if(!custom_route.gateway) {
|
||||
traceEvent(TRACE_ERROR, "could not determine the gateway IP address");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* ip route add supernode via internet_gateway */
|
||||
if(routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, &custom_route, -1) < 0)
|
||||
return(-1);
|
||||
|
||||
/* Save the route to delete it when n2n is stopped */
|
||||
eee->sn_route_to_clean = calloc(1, sizeof(n2n_route_t));
|
||||
|
||||
/* Store a copy of the rules into the runtime to delete it during shutdown */
|
||||
if(eee->sn_route_to_clean)
|
||||
*eee->sn_route_to_clean = custom_route;
|
||||
|
||||
/* ip route add 0.0.0.0/1 via n2n_gateway */
|
||||
custom_route.net_addr = 0;
|
||||
custom_route.net_bitlen = 1;
|
||||
custom_route.gateway = route->gateway;
|
||||
|
||||
if(routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, &custom_route, eee->device.if_idx) < 0)
|
||||
return(-1);
|
||||
|
||||
/* ip route add 128.0.0.0/1 via n2n_gateway */
|
||||
custom_route.net_addr = 128;
|
||||
custom_route.net_bitlen = 1;
|
||||
custom_route.gateway = route->gateway;
|
||||
|
||||
if(routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, &custom_route, eee->device.if_idx) < 0)
|
||||
return(-1);
|
||||
} else {
|
||||
/* ip route add net via n2n_gateway */
|
||||
if(routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, route, eee->device.if_idx) < 0)
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
return edge_init_routes_linux(eee, routes, num_routes);
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
#ifdef WIN32
|
||||
return edge_init_routes_win(eee, routes, num_routes);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int edge_init_routes_linux(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes) {
|
||||
#ifdef __linux__
|
||||
int i;
|
||||
for (i = 0; i<num_routes; i++) {
|
||||
n2n_route_t *route = &routes[i];
|
||||
|
||||
if ((route->net_addr == 0) && (route->net_bitlen == 0)) {
|
||||
/* This is a default gateway rule. We need to:
|
||||
*
|
||||
* 1. Add a route to the supernode via the host internet gateway
|
||||
* 2. Add the new default gateway route
|
||||
*
|
||||
* Instead of modifying the system default gateway, we use the trick
|
||||
* of adding a route to the networks 0.0.0.0/1 and 128.0.0.0/1, thus
|
||||
* covering the whole IPv4 range. Such routes in linux take precedence
|
||||
* over the default gateway (0.0.0.0/0) since are more specific.
|
||||
* This leaves the default gateway unchanged so that after n2n is
|
||||
* stopped the cleanup is easier.
|
||||
* See https://github.com/zerotier/ZeroTierOne/issues/178#issuecomment-204599227
|
||||
*/
|
||||
n2n_sock_t sn;
|
||||
n2n_route_t custom_route;
|
||||
uint32_t *a;
|
||||
|
||||
if (eee->sn_route_to_clean) {
|
||||
traceEvent(TRACE_ERROR, "Only one default gateway route allowed");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (eee->conf.sn_num != 1) {
|
||||
traceEvent(TRACE_ERROR, "Only one supernode supported with routes");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (supernode2addr(&sn, eee->conf.sn_ip_array[0]) < 0)
|
||||
return(-1);
|
||||
|
||||
if (sn.family != AF_INET) {
|
||||
traceEvent(TRACE_ERROR, "Only IPv4 routes supported");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
a = (u_int32_t*)sn.addr.v4;
|
||||
custom_route.net_addr = *a;
|
||||
custom_route.net_bitlen = 32;
|
||||
custom_route.gateway = get_gateway_ip();
|
||||
|
||||
if (!custom_route.gateway) {
|
||||
traceEvent(TRACE_ERROR, "could not determine the gateway IP address");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* ip route add supernode via internet_gateway */
|
||||
if (routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, &custom_route, -1) < 0)
|
||||
return(-1);
|
||||
|
||||
/* Save the route to delete it when n2n is stopped */
|
||||
eee->sn_route_to_clean = calloc(1, sizeof(n2n_route_t));
|
||||
|
||||
/* Store a copy of the rules into the runtime to delete it during shutdown */
|
||||
if (eee->sn_route_to_clean)
|
||||
*eee->sn_route_to_clean = custom_route;
|
||||
|
||||
/* ip route add 0.0.0.0/1 via n2n_gateway */
|
||||
custom_route.net_addr = 0;
|
||||
custom_route.net_bitlen = 1;
|
||||
custom_route.gateway = route->gateway;
|
||||
|
||||
if (routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, &custom_route, eee->device.if_idx) < 0)
|
||||
return(-1);
|
||||
|
||||
/* ip route add 128.0.0.0/1 via n2n_gateway */
|
||||
custom_route.net_addr = 128;
|
||||
custom_route.net_bitlen = 1;
|
||||
custom_route.gateway = route->gateway;
|
||||
|
||||
if (routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, &custom_route, eee->device.if_idx) < 0)
|
||||
return(-1);
|
||||
}
|
||||
else {
|
||||
/* ip route add net via n2n_gateway */
|
||||
if (routectl(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, route, eee->device.if_idx) < 0)
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int edge_init_routes_win(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_routes)
|
||||
{
|
||||
#ifdef WIN32
|
||||
int i;
|
||||
struct in_addr net_addr, gateway;
|
||||
char c_net_addr[32];
|
||||
char c_gateway[32];
|
||||
char cmd[256];
|
||||
|
||||
for (i = 0; i < num_routes; i++)
|
||||
{
|
||||
n2n_route_t *route = &routes[i];
|
||||
if ((route->net_addr == 0) && (route->net_bitlen == 0))
|
||||
{
|
||||
traceEvent(TRACE_NORMAL, "Warning: The 0.0.0.0/0 route settings are not supported on Windows");
|
||||
return (-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ip route add net via n2n_gateway */
|
||||
memcpy(&net_addr, &(route->net_addr), sizeof(net_addr));
|
||||
memcpy(&gateway, &(route->gateway), sizeof(gateway));
|
||||
_snprintf(c_net_addr, sizeof(c_net_addr), inet_ntoa(net_addr));
|
||||
_snprintf(c_gateway, sizeof(c_gateway), inet_ntoa(gateway));
|
||||
_snprintf(cmd, sizeof(cmd), "route add %s/%d %s > nul", c_net_addr, route->net_bitlen, c_gateway);
|
||||
traceEvent(TRACE_NORMAL, "ROUTE CMD = '%s'\n", cmd);
|
||||
system(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // WIN32
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ************************************** */
|
||||
|
||||
Reference in New Issue
Block a user