tinc: integration and gui
[tomato.git] / release / src / router / rc / tinc.c
blobaf379ae8e4911ee64a38510d0a7f21df0073372f
1 /*
3 Copyright (C) 2014 Lance Fredrickson
4 lancethepants@gmail.com
6 */
8 #include "rc.h"
10 #define BUF_SIZE 256
12 void start_tinc(void)
15 char *nv, *nvp, *b;
16 const char *connecto, *name, *address, *port, *compression, *subnet, *rsa, *ecdsa, *custom, *tinc_tmp_value;
17 char buffer[BUF_SIZE];
18 FILE *fp, *hp;
21 // create tinc directories
22 mkdir("/etc/tinc", 0700);
23 mkdir("/etc/tinc/hosts", 0700);
26 // write private rsa key
27 if ( strcmp( tinc_tmp_value = nvram_safe_get("tinc_private_rsa"), "") != 0 ){
28 if ( !( fp = fopen( "/etc/tinc/rsa_key.priv", "w" ))){
29 perror( "/etc/tinc/rsa_key.priv" );
30 return;
32 fprintf(fp, "%s\n", tinc_tmp_value );
33 fclose(fp);
34 chmod("/etc/tinc/rsa_key.priv", 0600);
38 // write private ecdsa key
39 if ( strcmp( tinc_tmp_value = nvram_safe_get("tinc_private_ecdsa"), "") != 0 ){
40 if ( !( fp = fopen( "/etc/tinc/ecdsa_key.priv", "w" ))){
41 perror( "/etc/tinc/ecdsa_key.priv" );
42 return;
44 fprintf(fp, "%s\n", tinc_tmp_value );
45 fclose(fp);
46 chmod("/etc/tinc/ecdsa_key.priv", 0600);
50 // create tinc.conf
51 if ( !( fp = fopen( "/etc/tinc/tinc.conf", "w" ))){
52 perror( "/etc/tinc/tinc.conf" );
53 return;
57 fprintf(fp, "Name = %s\n", nvram_safe_get( "tinc_name" ));
59 fprintf(fp, "Interface = tinc\n" );
61 fprintf(fp, "DeviceType = %s\n", nvram_safe_get( "tinc_devicetype" ));
64 if (nvram_match("tinc_devicetype", "tun")){
65 fprintf(fp, "Mode = router\n");
67 else if (nvram_match("tinc_devicetype", "tap")){
68 fprintf(fp, "Mode = %s\n", nvram_safe_get( "tinc_mode" ));
72 // create tinc host files
73 nvp = nv = strdup(nvram_safe_get("tinc_hosts"));
74 if (!nv) return;
75 while ((b = strsep(&nvp, ">")) != NULL) {
77 if (vstrsep(b, "<", &connecto, &name, &address, &port, &compression, &subnet, &rsa, &ecdsa, &custom) != 9) continue;
79 sprintf(&buffer[0], "/etc/tinc/hosts/%s", name);
80 if ( !( hp = fopen( &buffer[0], "w" ))){
81 perror( &buffer[0] );
82 return;
85 // write Connecto's to tinc.conf, excluding the host system if connecto is enabled
86 if ( (strcmp( connecto, "1") == 0 ) && (strcmp( nvram_safe_get("tinc_name"), name) != 0 ) ){
87 fprintf(fp, "ConnectTo = %s\n", name );
90 if ( strcmp( rsa, "" ) != 0 )
91 fprintf(hp, "%s\n", rsa );
93 if ( strcmp( ecdsa, "" ) != 0 )
94 fprintf(hp, "%s\n", ecdsa );
96 if ( strcmp( address, "" ) != 0 )
97 fprintf(hp, "Address = %s\n", address );
99 if ( strcmp( subnet, "" ) != 0 )
100 fprintf(hp, "Subnet = %s\n", subnet );
102 if ( strcmp( compression, "" ) != 0 )
103 fprintf(hp, "Compression = %s\n", compression );
105 if ( strcmp( port, "") != 0 )
106 fprintf(hp, "Port = %s\n", port );
108 if ( strcmp( custom, "") != 0 )
109 fprintf(hp, "%s\n", custom );
111 fclose(hp);
113 // generate tinc-up and firewall scripts
114 if ( strcmp( nvram_safe_get("tinc_name"), name) == 0 ){
116 // create tinc-up script if this is the host system.
118 if ( !( hp = fopen( "/etc/tinc/tinc-up", "w" ))){
119 perror( "/etc/tinc/tinc-up" );
120 return;
123 fprintf(hp, "#!/bin/sh\n" );
125 // Determine whether automatically generate tinc-up, or use manually supplied script.
126 if ( !nvram_match("tinc_manual_tinc_up", "1") ){
128 if (nvram_match("tinc_devicetype", "tun")){
129 fprintf(hp, "ifconfig $INTERFACE %s netmask %s\n", nvram_safe_get("lan_ipaddr"), nvram_safe_get("tinc_vpn_netmask") );
131 else if (nvram_match("tinc_devicetype", "tap")){
132 fprintf(hp, "brctl addif %s $INTERFACE\n", nvram_safe_get("lan_ifname") );
133 fprintf(hp, "ifconfig $INTERFACE 0.0.0.0 promisc up\n" );
136 else {
137 fprintf(hp, "%s\n", nvram_safe_get("tinc_tinc_up") );
140 fclose(hp);
141 chmod("/etc/tinc/tinc-up", 0744);
143 // Create firewall script if manual firewall is not enabled.
144 if ( !nvram_match("tinc_manual_firewall", "1") ){
146 if ( !( hp = fopen( "/etc/tinc/tinc-fw.sh", "w" ))){
147 perror( "/etc/tinc/tinc-fw.sh" );
148 return;
151 if ( strcmp( port, "") == 0 )
152 port = "655";
154 fprintf(hp, "#!/bin/sh\n" );
156 fprintf(hp, "iptables -t nat -I PREROUTING -p udp --dport %s -j ACCEPT\n", port );
157 fprintf(hp, "iptables -t nat -I PREROUTING -p tcp --dport %s -j ACCEPT\n", port );
160 fprintf(hp, "iptables -I INPUT -p udp --dport %s -j ACCEPT\n", port );
161 fprintf(hp, "iptables -I INPUT -p tcp --dport %s -j ACCEPT\n", port );
164 fprintf(hp, "iptables -I INPUT -i tinc -j ACCEPT\n" );
165 fprintf(hp, "iptables -I FORWARD -i tinc -j ACCEPT\n" );
167 #ifdef TCONFIG_IPV6
168 if (ipv6_enabled()){
170 fprintf(hp, "\n" );
171 fprintf(hp, "ip6tables -I INPUT -p udp --dport %s -j ACCEPT\n", port );
172 fprintf(hp, "ip6tables -I INPUT -p tcp --dport %s -j ACCEPT\n", port );
174 fprintf(hp, "ip6tables -I INPUT -i tinc -j ACCEPT\n" );
175 fprintf(hp, "ip6tables -I FORWARD -i tinc -j ACCEPT\n" );
177 #endif
179 fclose(hp);
180 chmod("/etc/tinc/tinc-fw.sh", 0744);
185 // Write tinc.conf custom configuration
186 if ( strcmp( tinc_tmp_value = nvram_safe_get("tinc_custom"), "") != 0 )
187 fprintf(fp, "%s\n", tinc_tmp_value );
189 fclose(fp);
190 free(nv);
192 // write tinc-down
193 if ( strcmp( tinc_tmp_value = nvram_safe_get("tinc_tinc_down"), "") != 0 ){
194 if ( !( fp = fopen( "/etc/tinc/tinc-down", "w" ))){
195 perror( "/etc/tinc/tinc-down" );
196 return;
198 fprintf(fp, "#!/bin/sh\n" );
199 fprintf(fp, "%s\n", tinc_tmp_value );
200 fclose(fp);
201 chmod("/etc/tinc/tinc-down", 0744);
204 // write host-up
205 if ( strcmp( tinc_tmp_value = nvram_safe_get("tinc_host_up"), "") != 0 ){
206 if ( !( fp = fopen( "/etc/tinc/host-up", "w" ))){
207 perror( "/etc/tinc/host-up" );
208 return;
210 fprintf(fp, "#!/bin/sh\n" );
211 fprintf(fp, "%s\n", tinc_tmp_value );
212 fclose(fp);
213 chmod("/etc/tinc/host-up", 0744);
216 // write host-down
217 if ( strcmp( tinc_tmp_value = nvram_safe_get("tinc_host_down"), "") != 0 ){
218 if ( !( fp = fopen( "/etc/tinc/host-down", "w" ))){
219 perror( "/etc/tinc/host-down" );
220 return;
222 fprintf(fp, "#!/bin/sh\n" );
223 fprintf(fp, "%s\n", tinc_tmp_value );
224 fclose(fp);
225 chmod("/etc/tinc/host-down", 0744);
228 // write subnet-up
229 if ( strcmp( tinc_tmp_value = nvram_safe_get("tinc_subnet_up"), "") != 0 ){
230 if ( !( fp = fopen( "/etc/tinc/subnet-up", "w" ))){
231 perror( "/etc/tinc/subnet-up" );
232 return;
234 fprintf(fp, "#!/bin/sh\n" );
235 fprintf(fp, "%s\n", tinc_tmp_value );
236 fclose(fp);
237 chmod("/etc/tinc/subnet-up", 0744);
240 // write subnet-down
241 if ( strcmp( tinc_tmp_value = nvram_safe_get("tinc_subnet_down"), "") != 0 ){
242 if ( !( fp = fopen( "/etc/tinc/subnet-down", "w" ))){
243 perror( "/etc/tinc/subnet-down" );
244 return;
246 fprintf(fp, "#!/bin/sh\n" );
247 fprintf(fp, "%s\n", tinc_tmp_value );
248 fclose(fp);
249 chmod("/etc/tinc/subnet-down", 0744);
253 // Make sure module is loaded
254 modprobe("tun");
255 f_wait_exists("/dev/net/tun", 5);
257 run_tinc_firewall_script();
258 xstart( "/usr/sbin/tinc", "start" );
259 return;
262 void stop_tinc(void)
264 killall("tincd", SIGTERM);
265 system( "/bin/sed -i \'s/-A/-D/g;s/-I/-D/g\' /etc/tinc/tinc-fw.sh\n");
266 run_tinc_firewall_script();
267 system( "/bin/rm -rf /etc/tinc\n" );
268 return;
271 void run_tinc_firewall_script(void){
273 FILE *fp;
275 if ((fp = fopen( "/etc/tinc/tinc-fw.sh", "r" ))){
277 fclose(fp);
278 system( "/etc/tinc/tinc-fw.sh" );
281 return;
284 void start_tinc_wanup(void){
286 if ( nvram_match("tinc_wanup", "1") )
287 start_tinc();
289 return;