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

Revision 12387, 10.3 kB (checked in by BrainSlayer, 5 months ago)

should be more simple

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",temp_wan_netmask, "up");
237         else
238                 eval("ifconfig", wan_ifname, nvram_safe_get("wan_ipaddr"),
239                      "netmask", nvram_safe_get("wan_netmask"), "up");
240
241         /*
242          * We only want to exec bellow functions after dhcp get ip if the
243          * wan_proto is heartbeat
244          */
245 #ifdef HAVE_HEARTBEAT
246         if (nvram_match("wan_proto", "heartbeat")) {
247                 int i = 0;
248
249                 /*
250                  * Delete all default routes
251                  */
252                 while (route_del(wan_ifname, 0, NULL, NULL, NULL) == 0
253                        || i++ < 10) ;
254
255                 /*
256                  * Set default route to gateway if specified
257                  */
258                 route_add(wan_ifname, 0, "0.0.0.0",
259                           nvram_safe_get("wan_gateway"), "0.0.0.0");
260
261                 /*
262                  * save dns to resolv.conf
263                  */
264                 dns_to_resolv();
265                 stop_udhcpd();
266                 start_udhcpd();
267                 start_firewall();
268                 stop_wland();
269                 start_wshaper();
270                 start_wland();
271                 start_heartbeat_boot();
272         }
273 #else
274         if (0) {
275                 // nothing
276         }
277 #endif
278 #ifdef HAVE_PPTP
279         else if (nvram_match("wan_proto", "pptp")
280                  && nvram_match("pptp_use_dhcp", "1")) {
281                 char pptpip[64];
282                 struct dns_lists *dns_list = NULL;
283
284                 dns_to_resolv();
285
286                 dns_list = get_dns_list();
287                 int i = 0;
288
289                 if (dns_list) {
290                         for (i = 0; i < dns_list->num_servers; i++)
291                                 route_add(wan_ifname, 0,
292                                           dns_list->dns_server[i],
293                                           nvram_safe_get("wan_gateway"),
294                                           "255.255.255.255");
295                         free(dns_list);
296                 }
297                 route_add(wan_ifname, 0, "0.0.0.0",
298                           nvram_safe_get("wan_gateway"), "0.0.0.0");
299
300                 nvram_set("wan_gateway_buf", nvram_get("wan_gateway"));
301
302                 getIPFromName(nvram_safe_get("pptp_server_name"), pptpip);
303                 nvram_set("pptp_server_ip", pptpip);
304
305                 // Add the route to the PPTP server on the wan interface for pptp
306                 // client to reach it
307                 if (nvram_match("wan_gateway", "0.0.0.0")
308                     || nvram_match("wan_netmask", "0.0.0.0"))
309                         route_add(wan_ifname, 0,
310                                   nvram_safe_get("pptp_server_ip"),
311                                   nvram_safe_get("wan_gateway"),
312                                   "255.255.255.255");
313                 else
314                         route_add(wan_ifname, 0,
315                                   nvram_safe_get("pptp_server_ip"),
316                                   nvram_safe_get("wan_gateway"),
317                                   nvram_safe_get("wan_netmask"));
318
319         }
320 #endif
321 #ifdef HAVE_L2TP
322         else if (nvram_match("wan_proto", "l2tp")) {
323                 int i = 0;
324
325                 /*
326                  * Delete all default routes
327                  */
328                 while (route_del(wan_ifname, 0, NULL, NULL, NULL) == 0
329                        || i++ < 10) ;
330
331                 /*
332                  * Set default route to gateway if specified
333                  */
334                 route_add(wan_ifname, 0, "0.0.0.0",
335                           nvram_safe_get("wan_gateway"), "0.0.0.0");
336
337                 /*
338                  * Backup the default gateway. It should be used if L2TP connection
339                  * is broken
340                  */
341                 nvram_set("wan_gateway_buf", nvram_get("wan_gateway"));
342
343                 /*
344                  * clear dns from the resolv.conf
345                  */
346                 nvram_set("wan_get_dns", "");
347                 dns_to_resolv();
348                 start_firewall();
349                 start_l2tp_boot();
350         }
351 #endif
352         else {
353                 cprintf("start wan done\n");
354                 start_wan_done(wan_ifname);
355         }
356         nvram_set("dhcpc_done", "1");
357         cprintf("done\n");
358         return 0;
359 }
360
361 /*
362  * renew: This argument is used when a DHCP lease is renewed. All of
363  * the paramaters are set in enviromental variables. This argument is
364  * used when the interface is already configured, so the IP address,
365  * will not change, however, the other DHCP paramaters, such as the
366  * default gateway, subnet mask, and dns server may change.
367  */
368 static int renew(void)
369 {
370         bound();
371
372         cprintf("done\n");
373         return 0;
374 }
375
376 int udhcpc_main(int argc, char **argv)
377 {
378         if (check_action() != ACT_IDLE)
379                 return -1;
380
381         if (!argv[1])
382                 return EINVAL;
383         else if (strstr(argv[1], "deconfig"))
384                 return deconfig();
385         else if (strstr(argv[1], "bound"))
386                 return bound();
387         else if (strstr(argv[1], "renew"))
388                 return renew();
389         else if (strstr(argv[1], "update"))
390                 return update_value();
391         else
392                 return EINVAL;
393 }
394
395 static int bound_tv(void)
396 {
397         char *ifname = safe_getenv("interface");
398         char *ip = safe_getenv("ip");
399         char *net = safe_getenv("subnet");
400         char *cidr = safe_getenv("cidrroute");
401         if (ip && net && ifname) {
402                 char bcast[32];
403                 strcpy(bcast, ip);
404                 get_broadcast(bcast, net);
405                 eval("ifconfig", ifname, ip, "netmask", net, "broadcast", bcast,"multi");
406                 nvram_set("tvnicaddr",ip);
407         }
408         if (cidr && ifname) {
409                 char *callbuffer = malloc(strlen(cidr) + 128);
410                 sprintf(callbuffer,
411                         "export cidrroute=\"%s\";export interface=\"%s\";/etc/cidrroute.sh",
412                         cidr, ifname);
413                 system(callbuffer);
414                 free(callbuffer);
415         }
416         return 0;
417 }
418
419 int udhcpc_tv_main(int argc, char **argv)
420 {
421         if (check_action() != ACT_IDLE)
422                 return -1;
423
424         if (!argv[1])
425                 return EINVAL;
426         else if (strstr(argv[1], "deconfig"))
427                 return 0;
428         else if (strstr(argv[1], "bound"))
429                 return bound_tv();
430         else if (strstr(argv[1], "renew"))
431                 return bound_tv();
432         else if (strstr(argv[1], "update"))
433                 return bound_tv();
434         else
435                 return EINVAL;
436 }
Note: See TracBrowser for help on using the browser.