2 ifconfig.c -- Generate platform specific interface configuration commands
3 Copyright (C) 2016-2018 Guus Sliepen <guus@tinc-vpn.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 void ifconfig_header(FILE *out) {
30 fprintf(out, "#!/bin/sh\n");
32 fprintf(out, "ip link set \"$INTERFACE\" up\n");
37 void ifconfig_dhcp(FILE *out) {
38 fprintf(out, "dhclient -nw \"$INTERFACE\"\n");
41 void ifconfig_dhcp6(FILE *out) {
42 fprintf(out, "dhclient -6 -nw \"$INTERFACE\"\n");
45 void ifconfig_slaac(FILE *out) {
47 fprintf(out, "echo 1 >\"/proc/sys/net/ipv6/conf/$INTERFACE/accept_ra\"\n");
48 fprintf(out, "echo 1 >\"/proc/sys/net/ipv6/conf/$INTERFACE/autoconf\"\n");
50 fprintf(out, "rtsol \"$INTERFACE\" &\n");
54 bool ifconfig_footer(FILE *out) {
55 if(ftell(out) == start) {
58 "#ip addr add <your vpn IP address>/<prefix of whole VPN> dev $INTERFACE\n"
60 "#ifconfig $INTERFACE <your vpn IP address>/<prefix of whole VPN>\n"
63 "echo \"Unconfigured tinc-up script, please edit '$0'!\" >&2\n");
67 fprintf(out, "ifconfig \"$INTERFACE\" up\n");
73 void ifconfig_header(FILE *out) {
77 void ifconfig_dhcp(FILE *out) {
78 fprintf(out, "netsh interface ipv4 set address \"%%INTERFACE%%\" dhcp\n");
81 void ifconfig_dhcp6(FILE *out) {
83 fprintf(stderr, "DHCPv6 requested, but not supported by tinc on this platform\n");
86 void ifconfig_slaac(FILE *out) {
91 bool ifconfig_footer(FILE *out) {
92 return ftell(out) != start;
96 static subnet_t ipv4, ipv6;
98 void ifconfig_address(FILE *out, const char *value) {
99 subnet_t address = {0};
100 char address_str[MAXNETSTR];
102 if(!str2net(&address, value) || !net2str(address_str, sizeof(address_str), &address)) {
103 fprintf(stderr, "Could not parse address in Ifconfig statement\n");
107 switch(address.type) {
121 #if defined(HAVE_LINUX)
123 switch(address.type) {
125 fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str);
129 fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str);
133 fprintf(out, "ip addr replace %s dev \"$INTERFACE\"\n", address_str);
140 #elif defined(HAVE_WINDOWS)
142 switch(address.type) {
144 fprintf(out, "ip link set \"$INTERFACE\" address %s\n", address_str);
148 fprintf(out, "netsh interface ipv4 set address \"%%INTERFACE%%\" static %s\n", address_str);
152 fprintf(out, "netsh interface ipv6 set address \"%%INTERFACE%%\" %s\n", address_str);
161 switch(address.type) {
163 fprintf(out, "ifconfig \"$INTERFACE\" link %s\n", address_str);
167 fprintf(out, "ifconfig \"$INTERFACE\" %s\n", address_str);
171 fprintf(out, "ifconfig \"$INTERFACE\" inet6 %s\n", address_str);
181 void ifconfig_route(FILE *out, const char *value) {
182 subnet_t subnet = {0}, gateway = {0};
183 char subnet_str[MAXNETSTR] = "", gateway_str[MAXNETSTR] = "";
184 char *sep = strchr(value, ' ');
190 if(!str2net(&subnet, value) || !net2str(subnet_str, sizeof(subnet_str), &subnet) || subnet.type == SUBNET_MAC) {
191 fprintf(stderr, "Could not parse subnet in Route statement\n");
196 if(!str2net(&gateway, sep) || !net2str(gateway_str, sizeof(gateway_str), &gateway) || gateway.type != subnet.type) {
197 fprintf(stderr, "Could not parse gateway in Route statement\n");
201 char *slash = strchr(gateway_str, '/');
208 #if defined(HAVE_LINUX)
211 switch(subnet.type) {
213 fprintf(out, "ip route add %s via %s dev \"$INTERFACE\" onlink\n", subnet_str, gateway_str);
217 fprintf(out, "ip route add %s via %s dev \"$INTERFACE\" onlink\n", subnet_str, gateway_str);
225 switch(subnet.type) {
227 fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str);
231 fprintf(out, "ip route add %s dev \"$INTERFACE\"\n", subnet_str);
240 #elif defined(HAVE_WINDOWS)
243 switch(subnet.type) {
245 fprintf(out, "netsh interface ipv4 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str);
249 fprintf(out, "netsh interface ipv6 add route %s \"%%INTERFACE%%\" %s\n", subnet_str, gateway_str);
257 switch(subnet.type) {
259 fprintf(out, "netsh interface ipv4 add route %s \"%%INTERFACE%%\"\n", subnet_str);
263 fprintf(out, "netsh interface ipv6 add route %s \"%%INTERFACE%%\"\n", subnet_str);
275 switch(subnet.type) {
278 fprintf(stderr, "Route requested but no Ifconfig\n");
282 net2str(gateway_str, sizeof(gateway_str), &ipv4);
287 fprintf(stderr, "Route requested but no Ifconfig\n");
291 net2str(gateway_str, sizeof(gateway_str), &ipv6);
299 char *slash = strchr(gateway_str, '/');
306 switch(subnet.type) {
308 fprintf(out, "route add %s %s\n", subnet_str, gateway_str);
312 fprintf(out, "route add -inet6 %s %s\n", subnet_str, gateway_str);