root/src/router/services/networking/udhcpc.c

Revision 12357, 10.2 kB (checked in by BrainSlayer, 5 months ago)

gateway setting for pptp (will be used as single route)

Line 
1 /*
2  * udhcpc.c
3  *
4  * Copyright (C) 2007 Sebastian Gottschall <gottschall@dd-wrt.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * $Id:
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <net/route.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
30 #include <errno.h>
31 #include <time.h>
32 #include <unistd.h>
33 #include <sys/sysinfo.h>
34
35 #include <bcmnvram.h>
36 #include <netconf.h>
37 #include <shutils.h>
38 #include <rc.h>
39 #include <code_pattern.h>
40 #include <cy_conf.h>
41 #include <utils.h>
42 #include <services.h>
43
44 #define IFUP (IFF_UP | IFF_RUNNING | IFF_BROADCAST | IFF_MULTICAST)
45
46 static int expires(unsigned int in)
47 {
48         struct sysinfo info;
49         FILE *fp;
50
51         sysinfo(&info);
52
53         /*
54          * Save uptime ranther than system time, because the system time may
55          * change
56          */
57         if (!(fp = fopen("/tmp/udhcpc.expires", "w"))) {
58                 perror("/tmp/udhcpd.expires");
59                 return errno;
60         }
61         fprintf(fp, "%d", (unsigned int)info.uptime + in);
62         fclose(fp);
63         return 0;
64 }
65
66 /*
67  * deconfig: This argument is used when udhcpc starts, and when a
68  * leases is lost. The script should put the interface in an up, but
69  * deconfigured state.
70  */
71 static int deconfig(void)
72 {
73         char *wan_ifname = safe_getenv("interface");
74
75         eval("ifconfig", wan_ifname, "0.0.0.0", "up");
76         expires(0);
77
78         nvram_set("wan_ipaddr", "0.0.0.0");
79         nvram_set("wan_netmask", "0.0.0.0");
80         nvram_set("wan_gateway", "0.0.0.0");
81         nvram_set("wan_get_dns", "");
82         // nvram_set("wan_wins","0.0.0.0"); // Don't care for linksys spec
83         nvram_set("wan_lease", "0");
84
85         unlink("/tmp/get_lease_time");
86         unlink("/tmp/lease_time");
87
88         cprintf("done\n");
89         return 0;
90 }
91
92 // ==================================================================
93 static int update_value(void)
94 {
95
96         char *value;
97         int changed = 0;
98
99         if ((value = getenv("ip"))) {
100                 chomp(value);
101                 if (nvram_invmatch("wan_ipaddr", value)) {
102                         nvram_set("wan_ipaddr", value);
103                         changed++;
104                 }
105         }
106         if ((value = getenv("subnet"))) {
107                 chomp(value);
108                 if (nvram_invmatch("wan_netmask", value)) {
109                         nvram_set("wan_netmask", value);
110                         changed++;
111                 }
112         }
113         if ((value = getenv("router"))) {
114                 chomp(value);
115                 if (nvram_invmatch("wan_gateway", value)) {
116                         nvram_set("wan_gateway", value);
117                         changed++;
118                 }
119         }
120         if ((value = getenv("dns"))) {
121                 chomp(value);
122                 if (nvram_invmatch("wan_get_dns", value)) {
123                         nvram_set("wan_get_dns", value);
124                         changed++;
125                 }
126         }
127         /*
128          * if ((value = getenv("wins"))) nvram_set("wan_wins", value); if ((value
129          * = getenv("hostname"))) sethostname(value, strlen(value) + 1);
130          */
131         if ((value = getenv("domain"))) {
132                 chomp(value);
133                 if (nvram_invmatch("wan_get_domain", value)) {
134                         nvram_set("wan_get_domain", value);
135                         changed++;
136                 }
137         }
138         if ((value = getenv("lease"))) {
139                 chomp(value);
140                 if (nvram_invmatch("wan_lease", value)) {
141                         nvram_set("wan_lease", value);
142                         changed++;
143                 }
144                 expires(atoi(value));
145         }
146
147         if (changed) {
148                 set_host_domain_name();
149 #ifdef HAVE_UDHCPD
150                 stop_udhcpd();
151                 start_udhcpd();
152 #endif
153         }
154         return 0;
155 }
156
157 // =================================================================
158
159 /*
160  * bound: This argument is used when udhcpc moves from an unbound, to
161  * a bound state. All of the paramaters are set in enviromental
162  * variables, The script should configure the interface, and set any
163  * other relavent parameters (default gateway, dns server, etc).
164  */
165 #ifdef HAVE_HEARTBEAT
166 extern void start_heartbeat_boot(void);
167 #endif
168 static int bound(void)
169 {
170         nvram_unset("dhcpc_done");
171         char *wan_ifname = safe_getenv("interface");
172         char *value;
173         char temp_wan_ipaddr[16], temp_wan_netmask[16], temp_wan_gateway[16];
174         int changed = 0;
175
176         if ((value = getenv("ip"))) {
177                 chomp(value);
178                 if (nvram_match("wan_proto", "pptp")
179                     && nvram_match("pptp_use_dhcp", "1"))
180                         strcpy(temp_wan_ipaddr, value);
181                 else {
182                         if (nvram_invmatch("wan_ipaddr", value))
183                                 changed = 1;
184                 }
185                 nvram_set("wan_ipaddr", value);
186         }
187         if ((value = getenv("subnet"))) {
188                 chomp(value);
189                 if (nvram_match("wan_proto", "pptp")
190                     && nvram_match("pptp_use_dhcp", "1"))
191                         strcpy(temp_wan_netmask, value);
192                 else {
193                         if (nvram_invmatch("wan_netmask", value))
194                                 changed = 1;
195                         nvram_set("wan_netmask", value);
196                 }
197         }
198         if ((value = getenv("router"))) {
199                 chomp(value);
200                 if (nvram_invmatch("wan_gateway", value))
201                         changed = 1;
202                 nvram_set("wan_gateway", value);
203         }
204         if ((value = getenv("dns"))) {
205                 chomp(value);
206                 // if (nvram_invmatch("wan_get_dns",value))
207                 // changed=1;
208                 nvram_set("wan_get_dns", value);
209         }
210         /*
211          * Don't care for linksys spec if ((value = getenv("wins")))
212          * nvram_set("wan_wins", value); if ((value = getenv("hostname")))
213          * sethostname(value, strlen(value) + 1);
214          */
215         if ((value = getenv("domain"))) {
216                 chomp(value);
217                 if (nvram_invmatch("wan_get_domain", value))
218                         changed = 1;
219                 nvram_set("wan_get_domain", value);     // HeartBeat need to use
220         }
221         if ((value = getenv("lease"))) {
222                 chomp(value);
223                 nvram_set("wan_lease", value);
224                 expires(atoi(value));
225         }
226         if (!changed) {
227                 cprintf("interface hasnt changed, do nothing\n");
228                 return 0;
229         }
230         stop_firewall();
231         cprintf("configure to IF[%s] , IP[%s], MASK[%s]\n", wan_ifname,
232                 nvram_safe_get("wan_ipaddr"), nvram_safe_get("wan_netmask"));
233
234         if (nvram_match("wan_proto", "pptp")
235             && nvram_match("pptp_use_dhcp", "1"))
236                 eval("ifconfig", wan_ifname, temp_wan_ipaddr, "netmask",
237                      temp_wan_netmask, "up");
238         else
239                 eval("ifconfig", wan_ifname, nvram_safe_get("wan_ipaddr"),
240                      "netmask", nvram_safe_get("wan_netmask"), "up");
241
242         /*
243          * We only want to exec bellow functions after dhcp get ip if the
244          * wan_proto is heartbeat
245          */
246 #ifdef HAVE_HEARTBEAT
247         if (nvram_match("wan_proto", "heartbeat")) {
248                 int i = 0;
249
250                 /*
251                  * Delete all default routes
252                  */
253                 while (route_del(wan_ifname, 0, NULL, NULL, NULL) == 0
254                        || i++ < 10) ;
255
256                 /*
257                  * Set default route to gateway if specified
258                  */
259                 route_add(wan_ifname, 0, "0.0.0.0",
260                           nvram_safe_get("wan_gateway"), "0.0.0.0");
261
262                 /*
263                  * save dns to resolv.conf
264                  */
265                 dns_to_resolv();
266                 stop_udhcpd();
267                 start_udhcpd();
268                 start_firewall();
269                 stop_wland();
270                 start_wshaper();
271                 start_wland();
272                 start_heartbeat_boot();
273         }
274 #else
275         if (0) {
276                 // nothing
277         }
278 #endif
279 #ifdef HAVE_PPTP
280         else if (nvram_match("wan_proto", "pptp")
281                  && nvram_match("pptp_use_dhcp", "1")) {
282                 char pptpip[64];
283                 struct dns_lists *dns_list = NULL;
284
285                 dns_to_resolv();
286
287                 dns_list = get_dns_list();
288                 int i = 0;
289
290                 if (dns_list) {
291                         for (i = 0; i < dns_list->num_servers; i++)
292                                 route_add(wan_ifname, 0,
293                                           dns_list->dns_server[i],
294                                           nvram_safe_get("wan_gateway"),
295                                           "255.255.255.255");
296                         free(dns_list);
297                 }
298                 route_add(wan_ifname, 0, "0.0.0.0",
299                           nvram_safe_get("wan_gateway"), "0.0.0.0");
300
301                 nvram_set("wan_gateway_buf", nvram_get("wan_gateway"));
302
303                 getIPFromName(nvram_safe_get("pptp_server_name"), pptpip);
304                 nvram_set("pptp_server_ip", pptpip);
305
306                 // Add the route to the PPTP server on the wan interface for pptp
307                 // client to reach it
308                 if (nvram_match("wan_gateway", "0.0.0.0")
309                     || nvram_match("wan_netmask", "0.0.0.0"))
310                         route_add(wan_ifname, 0,
311                                   nvram_safe_get("pptp_server_ip"),
312                                   nvram_safe_get("wan_gateway"),
313                                   "255.255.255.255");
314                 else
315                         route_add(wan_ifname, 0,
316                                   nvram_safe_get("pptp_server_ip"),
317                                   nvram_safe_get("wan_gateway"),
318                                   nvram_safe_get("wan_netmask"));
319
320         }
321 #endif
322 #ifdef HAVE_L2TP
323         else if (nvram_match("wan_proto", "l2tp")) {
324                 int i = 0;
325
326                 /*
327                  * Delete all default routes
328                  */
329                 while (route_del(wan_ifname, 0, NULL, NULL, NULL) == 0
330                        || i++ < 10) ;
331
332                 /*
333                  * Set default route to gateway if specified
334                  */
335                 route_add(wan_ifname, 0, "0.0.0.0",
336                           nvram_safe_get("wan_gateway"), "0.0.0.0");
337
338                 /*
339                  * Backup the default gateway. It should be used if L2TP connection
340                  * is broken
341                  */
342                 nvram_set("wan_gateway_buf", nvram_get("wan_gateway"));
343
344                 /*
345                  * clear dns from the resolv.conf
346                  */
347                 nvram_set("wan_get_dns", "");
348                 dns_to_resolv();
349                 start_firewall();
350                 start_l2tp_boot();
351         }
352 #endif
353         else {
354                 cprintf("start wan done\n");
355                 start_wan_done(wan_ifname);
356         }
357         nvram_set("dhcpc_done", "1");
358         cprintf("done\n");
359         return 0;
360 }
361
362 /*
363  * renew: This argument is used when a DHCP lease is renewed. All of
364  * the paramaters are set in enviromental variables. This argument is
365  * used when the interface is already configured, so the IP address,
366  * will not change, however, the other DHCP paramaters, such as the
367  * default gateway, subnet mask, and dns server may change.
368  */
369 static int renew(void)
370 {
371         bound();
372
373         cprintf("done\n");
374         return 0;
375 }
376
377 int udhcpc_main(int argc, char **argv)
378 {
379         if (check_action() != ACT_IDLE)
380                 return -1;
381
382         if (!argv[1])
383                 return EINVAL;
384         else if (strstr(argv[1], "deconfig"))
385                 return deconfig();
386         else if (strstr(argv[1], "bound"))
387                 return bound();
388         else if (strstr(argv[1], "renew"))
389                 return renew();
390         else if (strstr(argv[1], "update"))
391                 return update_value();
392         else
393                 return EINVAL;
394 }
395
396 static int bound_tv(void)
397 {
398         char *ifname = safe_getenv("interface");
399         char *ip = safe_getenv("ip");
400         char *net = safe_getenv("subnet");
401         char *cidr = safe_getenv("cidrroute");
402         if (ip && net && ifname) {
403                 char bcast[32];
404                 strcpy(bcast, ip);
405                 get_broadcast(bcast, net);
406                 eval("ifconfig", ifname, ip, "netmask", net, "broadcast", bcast,
407                      "multi");
408         }
409         if (cidr && ifname) {
410                 char *callbuffer = malloc(strlen(cidr) + 128);
411                 sprintf(callbuffer,
412                         "export cidrroute=\"%s\";export interface=\"%s\";/etc/cidrroute.sh",
413                         cidr, ifname);
414                 system(callbuffer);
415                 free(callbuffer);
416         }
417         return 0;
418 }
419
420 int udhcpc_tv_main(int argc, char **argv)
421 {
422         if (check_action() != ACT_IDLE)
423                 return -1;
424
425         if (!argv[1])
426                 return EINVAL;
427         else if (strstr(argv[1], "deconfig"))
428                 return 0;
429         else if (strstr(argv[1], "bound"))
430                 return bound_tv();
431         else if (strstr(argv[1], "renew"))
432                 return bound_tv();
433         else if (strstr(argv[1], "update"))
434                 return bound_tv();
435         else
436                 return EINVAL;
437 }
Note: See TracBrowser for help on using the browser.