1/*
2 * udhcpc scripts
3 *
4 * Copyright 2004, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11 *
12 * $Id: udhcpc.c,v 1.3 2009/03/03 02:39:54 james26_jang Exp $
13 */
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <sys/socket.h>
19#include <linux/if.h>
20#include <linux/route.h>
21#include <sys/socket.h>
22#include <netinet/in.h>
23#include <arpa/inet.h>
24#include <errno.h>
25#include <time.h>
26#include <unistd.h>
27
28#include <bcmnvram.h>
29#include <shutils.h>
30#include <rc.h>
31
32char udhcpstate[8];
33
34static int
35expires(char *wan_ifname, unsigned int in)
36{
37	time_t now;
38	FILE *fp;
39	char tmp[100];
40	int unit;
41
42	if ((unit = wan_ifunit(wan_ifname)) < 0)
43		return -1;
44
45	time(&now);
46	snprintf(tmp, sizeof(tmp), "/tmp/udhcpc%d.expires", unit);
47	if (!(fp = fopen(tmp, "w"))) {
48		perror(tmp);
49		return errno;
50	}
51	fprintf(fp, "%d", (unsigned int) now + in);
52	fclose(fp);
53	return 0;
54}
55
56/*
57 * deconfig: This argument is used when udhcpc starts, and when a
58 * leases is lost. The script should put the interface in an up, but
59 * deconfigured state.
60*/
61static int
62deconfig(void)
63{
64	char *wan_ifname = safe_getenv("interface");
65
66	if (nvram_invmatch("wan0_proto", "l2tp") && nvram_invmatch("wan0_proto", "pptp"))
67		ifconfig(wan_ifname, IFUP, "0.0.0.0", NULL);
68	else	// fix hang-up issue
69		logmessage("dhcp client", "skipping resetting IP address to 0.0.0.0");
70	expires(wan_ifname, 0);
71
72	wan_down(wan_ifname);
73
74	logmessage("dhcp client", "%s: lease is lost", udhcpstate);
75	wanmessage("lost IP from server");
76	dprintf("done\n");
77	return 0;
78}
79
80/*
81 * bound: This argument is used when udhcpc moves from an unbound, to
82 * a bound state. All of the paramaters are set in enviromental
83 * variables, The script should configure the interface, and set any
84 * other relavent parameters (default gateway, dns server, etc).
85*/
86static int
87bound(void)
88{
89	char *wan_ifname = safe_getenv("interface");
90	char *value;
91	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
92	int unit;
93#if 0
94	if ((unit = wan_ifunit(wan_ifname)) < 0)
95		return -1;
96
97	snprintf(prefix, sizeof(prefix), "wan%d_", unit);
98#endif
99
100	if ((unit = wan_ifunit(wan_ifname)) < 0)
101		strcpy(prefix, "wanx_");
102	else
103		snprintf(prefix, sizeof(prefix), "wan%d_", unit);
104
105	if ((value = getenv("ip")))
106		nvram_set(strcat_r(prefix, "ipaddr", tmp), trim_r(value));
107
108	if ((value = getenv("subnet")))
109		nvram_set(strcat_r(prefix, "netmask", tmp), trim_r(value));
110
111	if ((value = getenv("router")))
112		nvram_set(strcat_r(prefix, "gateway", tmp), trim_r(value));
113
114	if ((value = getenv("dns")))
115		nvram_set(strcat_r(prefix, "dns", tmp), trim_r(value));
116
117	if ((value = getenv("wins")))
118		nvram_set(strcat_r(prefix, "wins", tmp), trim_r(value));
119
120	nvram_set(strcat_r(prefix, "routes", tmp), getenv("routes"));
121	nvram_set(strcat_r(prefix, "msroutes", tmp), getenv("msroutes"));
122
123	//if ((value = getenv("hostname")))
124	//	sethostname(trim_r(value), strlen(value) + 1);
125
126	if ((value = getenv("domain")))
127		nvram_set(strcat_r(prefix, "domain", tmp), trim_r(value));
128	if ((value = getenv("lease"))) {
129		nvram_set(strcat_r(prefix, "lease", tmp), trim_r(value));
130		expires(wan_ifname, atoi(value));
131	}
132
133	ifconfig(wan_ifname, IFUP,
134			nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)),
135			nvram_safe_get(strcat_r(prefix, "netmask", tmp)));
136
137	wan_up(wan_ifname);
138
139	logmessage("dhcp client", "%s IP : %s from %s",
140			udhcpstate,
141			nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)),
142			nvram_safe_get(strcat_r(prefix, "gateway", tmp)));
143
144	wanmessage("");
145	dprintf("done\n");
146	return 0;
147}
148
149/*
150 * renew: This argument is used when a DHCP lease is renewed. All of
151 * the paramaters are set in enviromental variables. This argument is
152 * used when the interface is already configured, so the IP address,
153 * will not change, however, the other DHCP paramaters, such as the
154 * default gateway, subnet mask, and dns server may change.
155 */
156static int
157renew(void)
158{
159	char *wan_ifname = safe_getenv("interface");
160	char *value;
161	char tmp[100], prefix[] = "wanXXXXXXXXXX_";
162	int unit;
163
164	if ((unit = wan_ifunit(wan_ifname)) < 0)
165		strcpy(prefix, "wanx_");
166	else
167		snprintf(prefix, sizeof(prefix), "wan%d_", unit);
168
169	if (!(value = getenv("subnet")) || nvram_invmatch(strcat_r(prefix, "netmask", tmp), trim_r(value)))
170		return bound();
171	if (!(value = getenv("router")) || nvram_invmatch(strcat_r(prefix, "gateway", tmp), trim_r(value)))
172		return bound();
173	if ((value = getenv("dns")) && nvram_invmatch(strcat_r(prefix, "dns", tmp), trim_r(value))) {
174		nvram_set(strcat_r(prefix, "dns", tmp), trim_r(value));
175		update_resolvconf();
176	}
177	if ((value = getenv("wins")))
178		nvram_set(strcat_r(prefix, "wins", tmp), trim_r(value));
179
180	//if ((value = getenv("hostname")))
181	//	sethostname(trim_r(value), strlen(value) + 1);
182
183	if ((value = getenv("domain")))
184		nvram_set(strcat_r(prefix, "domain", tmp), trim_r(value));
185	if ((value = getenv("lease"))) {
186		nvram_set(strcat_r(prefix, "lease", tmp), trim_r(value));
187		expires(wan_ifname, atoi(value));
188	}
189
190	//logmessage("dhcp client", "%s IP : %s from %s",
191	//		udhcpstate,
192	//		nvram_safe_get(strcat_r(prefix, "ipaddr", tmp)),
193	//		nvram_safe_get(strcat_r(prefix, "gateway", tmp)));
194	wanmessage("");
195
196	dprintf("done\n");
197	return 0;
198}
199
200int
201udhcpc_main(int argc, char **argv)
202{
203	if(argv[1])
204		strcpy(udhcpstate, argv[1]);
205
206	if(!argv[1])
207		return EINVAL;
208	else if(strstr(argv[1], "deconfig"))
209		return deconfig();
210	else if(strstr(argv[1], "bound"))
211		return bound();
212	else if(strstr(argv[1], "renew"))
213		return renew();
214	else if (strstr(argv[1], "leasefail"))
215		return 0;
216	else
217		return deconfig();
218}
219