Tomato 1.28
[tomato.git] / release / src / router / rc / dhcp.c
blob50270ac09b8bbf544391ac78aa98fc47a8108261
1 /*
3 Copyright 2003, CyberTAN Inc. All Rights Reserved
5 This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
6 the contents of this file may not be disclosed to third parties,
7 copied or duplicated in any form without the prior written
8 permission of CyberTAN Inc.
10 This software should be used as a reference only, and it not
11 intended for production use!
13 THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
14 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. CYBERTAN
15 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
16 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
21 Copyright 2005, Broadcom Corporation
22 All Rights Reserved.
24 THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
25 KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
26 SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
27 FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
32 Modified for Tomato Firmware
33 Portions, Copyright (C) 2006-2009 Jonathan Zarate
37 #include "rc.h"
39 #include <sys/sysinfo.h>
40 #include <sys/ioctl.h>
43 #define IFUP (IFF_UP | IFF_RUNNING | IFF_BROADCAST | IFF_MULTICAST)
45 static void expires(unsigned int seconds)
47 struct sysinfo info;
48 char s[32];
50 sysinfo(&info);
51 sprintf(s, "%u", (unsigned int)info.uptime + seconds);
52 f_write_string("/var/lib/misc/dhcpc.expires", s, 0, 0);
55 // copy env to nvram
56 // returns 1 if new/changed, 0 if not changed/no env
57 static int env2nv(char *env, char *nv)
59 char *value;
60 if ((value = getenv(env)) != NULL) {
61 if (!nvram_match(nv, value)) {
62 nvram_set(nv, value);
63 return 1;
66 return 0;
69 static void env2nv_gateway(const char *nv)
71 char *v;
72 char *b;
73 if ((v = getenv("router")) != NULL) {
74 if ((b = strdup(v)) != NULL) {
75 if ((v = strchr(b, ' ')) != NULL) *v = 0; // truncate multiple entries
76 nvram_set(nv, b);
77 free(b);
82 static const char renewing[] = "/var/lib/misc/dhcpc.renewing";
84 static int deconfig(char *ifname)
86 TRACE_PT("begin\n");
88 ifconfig(ifname, IFUP, "0.0.0.0", NULL);
90 nvram_set("wan_ipaddr", "0.0.0.0");
91 nvram_set("wan_netmask", "0.0.0.0");
92 nvram_set("wan_gateway", "0.0.0.0");
93 nvram_set("wan_get_dns", "");
94 nvram_set("wan_lease", "0");
95 expires(0);
97 // int i = 10;
98 // while ((route_del(ifname, 0, NULL, NULL, NULL) == 0) && (i-- > 0)) { }
100 TRACE_PT("end\n");
101 return 0;
104 static int renew(char *ifname)
106 char *a, *b;
107 int changed;
109 TRACE_PT("begin\n");
111 unlink(renewing);
113 changed = env2nv("ip", "wan_ipaddr");
114 changed |= env2nv("subnet", "wan_netmask");
115 if (changed) {
116 ifconfig(ifname, IFUP, nvram_safe_get("wan_ipaddr"), nvram_safe_get("wan_netmask"));
119 if (get_wan_proto() == WP_L2TP) {
120 env2nv_gateway("wan_gateway_buf");
122 else {
123 a = strdup(nvram_safe_get("wan_gateway"));
124 env2nv_gateway("wan_gateway");
125 b = nvram_safe_get("wan_gateway");
126 if ((a) && (strcmp(a, b) != 0)) {
127 route_del(ifname, 0, "0.0.0.0", a, "0.0.0.0");
128 route_add(ifname, 0, "0.0.0.0", b, "0.0.0.0");
129 changed = 1;
131 free(a);
134 changed |= env2nv("domain", "wan_get_domain");
135 changed |= env2nv("dns", "wan_get_dns");
137 if ((a = getenv("lease")) != NULL) {
138 nvram_set("wan_lease", a);
139 expires(atoi(a));
142 if (changed) {
143 set_host_domain_name();
144 start_dnsmasq(); // (re)start
147 TRACE_PT("wan_ipaddr=%s\n", nvram_safe_get("wan_ipaddr"));
148 TRACE_PT("wan_netmask=%s\n", nvram_safe_get("wan_netmask"));
149 TRACE_PT("wan_gateway=%s\n", nvram_safe_get("wan_gateway"));
150 TRACE_PT("wan_get_domain=%s\n", nvram_safe_get("wan_get_domain"));
151 TRACE_PT("wan_get_dns=%s\n", nvram_safe_get("wan_get_dns"));
152 TRACE_PT("wan_lease=%s\n", nvram_safe_get("wan_lease"));
153 TRACE_PT("end\n");
154 return 0;
157 static int bound(char *ifname)
159 TRACE_PT("begin\n");
161 unlink(renewing);
163 env2nv("ip", "wan_ipaddr");
164 env2nv("subnet", "wan_netmask");
165 env2nv_gateway("wan_gateway");
166 env2nv("dns", "wan_get_dns");
167 env2nv("domain", "wan_get_domain");
168 env2nv("lease", "wan_lease");
169 expires(atoi(safe_getenv("lease")));
171 TRACE_PT("wan_ipaddr=%s\n", nvram_safe_get("wan_ipaddr"));
172 TRACE_PT("wan_netmask=%s\n", nvram_safe_get("wan_netmask"));
173 TRACE_PT("wan_gateway=%s\n", nvram_safe_get("wan_gateway"));
174 TRACE_PT("wan_get_domain=%s\n", nvram_safe_get("wan_get_domain"));
175 TRACE_PT("wan_get_dns=%s\n", nvram_safe_get("wan_get_dns"));
176 TRACE_PT("wan_lease=%s\n", nvram_safe_get("wan_lease"));
179 ifconfig(ifname, IFUP, nvram_safe_get("wan_ipaddr"), nvram_safe_get("wan_netmask"));
181 if (get_wan_proto() == WP_L2TP) {
182 int i = 0;
184 /* Delete all default routes */
185 while ((route_del(ifname, 0, NULL, NULL, NULL) == 0) || (i++ < 10));
187 /* Set default route to gateway if specified */
188 route_add(ifname, 0, "0.0.0.0", nvram_safe_get("wan_gateway"), "0.0.0.0");
190 /* Backup the default gateway. It should be used if L2TP connection is broken */
191 nvram_set("wan_gateway_buf", nvram_get("wan_gateway"));
193 /* clear dns from the resolv.conf */
194 nvram_set("wan_get_dns","");
195 dns_to_resolv();
197 start_firewall();
198 start_l2tp();
200 else {
201 start_wan_done(ifname);
204 TRACE_PT("end\n");
205 return 0;
208 int dhcpc_event_main(int argc, char **argv)
210 char *ifname;
212 if (!wait_action_idle(10)) return 1;
214 if ((argc == 2) && (ifname = getenv("interface")) != NULL) {
215 TRACE_PT("event=%s\n", argv[1]);
217 if (strcmp(argv[1], "deconfig") == 0) return deconfig(ifname);
218 if (strcmp(argv[1], "bound") == 0) return bound(ifname);
219 if ((strcmp(argv[1], "renew") == 0) || (strcmp(argv[1], "update") == 0)) return renew(ifname);
222 return 1;
226 // -----------------------------------------------------------------------------
229 int dhcpc_release_main(int argc, char **argv)
231 TRACE_PT("begin\n");
233 if (!using_dhcpc()) return 1;
235 deconfig(nvram_safe_get("wan_ifname"));
236 killall("udhcpc", SIGUSR2);
237 unlink(renewing);
238 unlink("/var/lib/misc/wan.connecting");
240 TRACE_PT("end\n");
241 return 0;
244 int dhcpc_renew_main(int argc, char **argv)
246 int pid;
248 TRACE_PT("begin\n");
250 if (!using_dhcpc()) return 1;
252 if ((pid = pidof("udhcpc")) > 1) {
253 kill(pid, SIGUSR1);
254 f_write(renewing, NULL, 0, 0, 0);
256 else {
257 stop_dhcpc();
258 start_dhcpc();
261 TRACE_PT("end\n");
262 return 0;
266 // -----------------------------------------------------------------------------
269 void start_dhcpc(void)
271 char *argv[6];
272 int argc;
273 char *ifname;
275 TRACE_PT("begin\n");
277 nvram_set("wan_get_dns", "");
278 f_write(renewing, NULL, 0, 0, 0);
280 ifname = nvram_safe_get("wan_ifname");
281 if (get_wan_proto() != WP_L2TP) {
282 nvram_set("wan_iface", ifname);
285 argc = 0;
286 argv[1] = nvram_safe_get("wan_hostname");
287 if (*argv[1]) {
288 argv[0] = "-H";
289 argc = 2;
292 if (nvram_get_int("dhcpc_minpkt")) argv[argc++] = "-m";
294 if (nvram_contains_word("log_events", "dhcpc")) argv[argc++] = "-S";
295 argv[argc] = NULL;
297 xstart(
298 "udhcpc",
299 "-i", ifname,
300 "-s", "dhcpc-event",
301 argv[0], argv[1], // -H wan_hostname
302 argv[2], // -m
303 argv[3] // -S
305 TRACE_PT("end\n");
308 void stop_dhcpc(void)
310 TRACE_PT("begin\n");
312 killall("dhcpc-event", SIGTERM);
313 if (killall("udhcpc", SIGUSR2) == 0) { // release
314 sleep(2);
316 killall_tk("udhcpc");
317 unlink(renewing);
319 TRACE_PT("end\n");