From 6d0452896673c36226c24144d4bde824a49c3950 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sun, 17 Apr 2016 13:23:01 +0200 Subject: [PATCH] Allow gateways to be specified for routes. Also improve the variable names, and ensure the % symbols in %INTERFACE% are properly quoted. --- src/ifconfig.c | 120 ++++++++++++++++++++++++++++++------------------- 1 file changed, 73 insertions(+), 47 deletions(-) diff --git a/src/ifconfig.c b/src/ifconfig.c index d063b17b..4331f16d 100644 --- a/src/ifconfig.c +++ b/src/ifconfig.c @@ -67,7 +67,7 @@ void ifconfig_header(FILE *out) { } void ifconfig_dhcp(FILE *out) { - fprintf(out, "netsh interface ipv4 set address \"%INTERFACE%\" dhcp\n"); + fprintf(out, "netsh interface ipv4 set address \"%%INTERFACE%%\" dhcp\n"); } void ifconfig_dhcp6(FILE *out) { @@ -86,76 +86,102 @@ bool ifconfig_footer(FILE *out) { static subnet_t ipv4, ipv6; void ifconfig_address(FILE *out, const char *value) { - subnet_t subnet = {}; - char str[MAXNETSTR]; - if(!str2net(&subnet, value) || !net2str(str, sizeof str, &subnet)) { + subnet_t address = {}; + char address_str[MAXNETSTR]; + if(!str2net(&address, value) || !net2str(address_str, sizeof address_str, &address)) { fprintf(stderr, "Could not parse Ifconfig statement\n"); return; } - switch(subnet.type) { - case SUBNET_IPV4: ipv4 = subnet; break; - case SUBNET_IPV6: ipv6 = subnet; break; + switch(address.type) { + case SUBNET_IPV4: ipv4 = address; break; + case SUBNET_IPV6: ipv6 = address; break; } #if defined(HAVE_LINUX) - switch(subnet.type) { - case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", str); break; - case SUBNET_IPV4: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", str); break; - case SUBNET_IPV6: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", str); break; + switch(address.type) { + case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); break; + case SUBNET_IPV4: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); break; + case SUBNET_IPV6: fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str); break; } #elif defined(HAVE_BSD) - switch(subnet.type) { - case SUBNET_MAC: fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", str); break; - case SUBNET_IPV4: fprintf(out, "ifconfig \"$INTERFACE\" %s\n", str); break; - case SUBNET_IPV6: fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", str); break; + switch(address.type) { + case SUBNET_MAC: fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str); break; + case SUBNET_IPV4: fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str); break; + case SUBNET_IPV6: fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str); break; } #elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) - switch(subnet.type) { - case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", str); break; - case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 set address \"$INTERFACE\" static %s\n", str); break; - case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 set address \"$INTERFACE\" static %s\n", str); break; + switch(address.type) { + case SUBNET_MAC: fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str); break; + case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 set address \"$INTERFACE\" static %s\n", address_str); break; + case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 set address \"$INTERFACE\" static %s\n", address_str); break; } #endif } void ifconfig_route(FILE *out, const char *value) { - subnet_t subnet = {}; - char str[MAXNETSTR]; - if(!str2net(&subnet, value) || !net2str(str, sizeof str, &subnet) || subnet.type == SUBNET_MAC) { + subnet_t subnet = {}, gateway = {}; + char subnet_str[MAXNETSTR] = "", gateway_str[MAXNETSTR] = ""; + const char *sep = strchr(value, ' '); + if(!str2net(&subnet, value) || !net2str(subnet_str, sizeof subnet_str, &subnet) || subnet.type == SUBNET_MAC) { fprintf(stderr, "Could not parse Ifconfig statement\n"); return; } + if(sep) { + sep++; + if(!str2net(&gateway, sep) || !net2str(gateway_str, sizeof gateway_str, &gateway) || gateway.type != subnet.type) { + fprintf(stderr, "Could not parse Ifconfig statement\n"); + return; + } + char *slash = strchr(gateway_str, '/'); if(slash) *slash = 0; + } #if defined(HAVE_LINUX) - switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", str); break; - case SUBNET_IPV6: fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", str); break; + if(*gateway_str) { + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); break; + case SUBNET_IPV6: fprintf(out, "ip route add %s via %s dev \"$INTERFACE\"\n", subnet_str, gateway_str); break; + } + } else { + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); break; + case SUBNET_IPV6: fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str); break; + } } #elif defined(HAVE_BSD) // BSD route command is silly and doesn't accept an interface name as a destination. - char gwstr[MAXNETSTR] = ""; + if(!*gateway_str) { + switch(subnet.type) { + case SUBNET_IPV4: + if(!ipv4.type) { + fprintf(stderr, "Route requested but no Ifconfig\n"); + return; + } + net2str(gateway_str, sizeof gateway_str, &ipv4); + break; + case SUBNET_IPV6: + if(!ipv6.type) { + fprintf(stderr, "Route requested but no Ifconfig\n"); + return; + } + net2str(gateway_str, sizeof gateway_str, &ipv6); + break; + } + char *slash = strchr(gateway_str, '/'); if(slash) *slash = 0; + } + switch(subnet.type) { - case SUBNET_IPV4: - if(!ipv4.type) { - fprintf(stderr, "Route requested but no Ifconfig\n"); - return; - } - net2str(gwstr, sizeof gwstr, &ipv4); - char *p = strchr(gwstr, '/'); if(p) *p = 0; - fprintf(out, "route add %s %s\n", str, gwstr); - break; - case SUBNET_IPV6: - if(!ipv6.type) { - fprintf(stderr, "Route requested but no Ifconfig\n"); - return; - } - net2str(gwstr, sizeof gwstr, &ipv6); - char *p = strchr(gwstr, '/'); if(p) *p = 0; - fprintf(out, "route add -inet6 %s %s\n", str, gwstr); - break; + case SUBNET_IPV4: fprintf(out, "route add %s %s\n", subnet_str, gateway_str); break; + case SUBNET_IPV6: fprintf(out, "route add -inet6 %s %s\n", subnet_str, gateway_str); break; } #elif defined(HAVE_MINGW) || defined(HAVE_CYGWIN) - switch(subnet.type) { - case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"$INTERFACE\"\n", str); break; - case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"$INTERFACE\"\n", str); break; + if(*gateway_str) { + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; + case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str); break; + } + } else { + switch(subnet.type) { + case SUBNET_IPV4: fprintf(out, "netsh inetface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; + case SUBNET_IPV6: fprintf(out, "netsh inetface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str); break; + } } #endif } -- 2.20.1