Tomato 1.28
[tomato.git] / release / src / router / rc / misc.c
blobe287a871f1567bc4b88713496a0df64f73583ff2
1 /*
3 Tomato Firmware
4 Copyright (C) 2006-2009 Jonathan Zarate
6 */
8 #include "rc.h"
10 #include <stdarg.h>
11 #include <sys/ioctl.h>
12 #include <net/if_arp.h>
14 #include <bcmdevs.h>
15 #include <wlutils.h>
18 void usage_exit(const char *cmd, const char *help)
20 fprintf(stderr, "Usage: %s %s\n", cmd, help);
21 exit(1);
24 int modprobe(const char *mod)
26 #if 1
27 return eval("modprobe", "-s", (char *)mod);
28 #else
29 int r = eval("modprobe", "-s", (char *)mod);
30 cprintf("modprobe %s = %d\n", mod, r);
31 return r;
32 #endif
35 int modprobe_r(const char *mod)
37 #if 1
38 return eval("modprobe", "-r", (char *)mod);
39 #else
40 int r = eval("modprobe", "-r", (char *)mod);
41 cprintf("modprobe -r %s = %d\n", mod, r);
42 return r;
43 #endif
46 int _xstart(const char *cmd, ...)
48 va_list ap;
49 char *argv[16];
50 int argc;
51 int pid;
53 argv[0] = (char *)cmd;
54 argc = 1;
55 va_start(ap, cmd);
56 while ((argv[argc++] = va_arg(ap, char *)) != NULL) {
59 va_end(ap);
61 return _eval(argv, NULL, 0, &pid);
64 void run_nvscript(const char *nv, const char *arg1, int wtime)
66 FILE *f;
67 char *script;
68 char s[256];
69 char *argv[3];
70 int pid;
72 script = nvram_get(nv);
73 if ((script) && (*script != 0)) {
74 sprintf(s, "/tmp/%s.sh", nv);
75 if ((f = fopen(s, "w")) != NULL) {
76 fputs("#!/bin/sh\n", f);
77 fputs(script, f);
78 fputs("\n", f);
79 fclose(f);
80 chmod(s, 0700);
82 chdir("/tmp");
84 argv[0] = s;
85 argv[1] = (char *)arg1;
86 argv[2] = NULL;
87 if (_eval(argv, NULL, 0, &pid) != 0) {
88 pid = -1;
90 else {
91 while (wtime-- > 0) {
92 if (kill(pid, 0) != 0) break;
93 sleep(1);
97 chdir("/");
102 void setup_conntrack(void)
104 unsigned int v[10];
105 const char *p;
106 int i;
108 p = nvram_safe_get("ct_tcp_timeout");
109 if (sscanf(p, "%u%u%u%u%u%u%u%u%u%u",
110 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5], &v[6], &v[7], &v[8], &v[9]) == 10) { // lightly verify
111 f_write_string("/proc/sys/net/ipv4/ip_conntrack_tcp_timeouts", p, 0, 0);
114 p = nvram_safe_get("ct_udp_timeout");
115 if (sscanf(p, "%u%u", &v[0], &v[1]) == 2) {
116 f_write_string("/proc/sys/net/ipv4/ip_conntrack_udp_timeouts", p, 0, 0);
119 p = nvram_safe_get("ct_max");
120 i = atoi(p);
121 if ((i >= 128) && (i <= 10240)) {
122 f_write_string("/proc/sys/net/ipv4/ip_conntrack_max", p, 0, 0);
125 if (!nvram_match("nf_pptp", "0")) {
126 modprobe("ip_conntrack_proto_gre");
127 modprobe("ip_nat_proto_gre");
128 modprobe("ip_conntrack_pptp");
129 modprobe("ip_nat_pptp");
131 else {
132 modprobe_r("ip_nat_pptp");
133 modprobe_r("ip_conntrack_pptp");
134 modprobe_r("ip_nat_proto_gre");
135 modprobe_r("ip_conntrack_proto_gre");
138 if (!nvram_match("nf_h323", "0")) {
139 modprobe("ip_conntrack_h323");
140 modprobe("ip_nat_h323");
142 else {
143 modprobe_r("ip_nat_h323");
144 modprobe_r("ip_conntrack_h323");
147 if (!nvram_match("nf_rtsp", "0")) {
148 modprobe("ip_conntrack_rtsp");
149 modprobe("ip_nat_rtsp");
151 else {
152 modprobe_r("ip_nat_rtsp");
153 modprobe_r("ip_conntrack_rtsp");
156 if (!nvram_match("nf_ftp", "0")) {
157 modprobe("ip_conntrack_ftp");
158 modprobe("ip_nat_ftp");
160 else {
161 modprobe_r("ip_nat_ftp");
162 modprobe_r("ip_conntrack_ftp");
167 void set_mac(const char *ifname, const char *nvname, int plus)
169 int sfd;
170 struct ifreq ifr;
171 int up;
172 int j;
174 if ((sfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
175 _dprintf("%s: %s %d\n", ifname, __FUNCTION__, __LINE__);
176 return;
179 strcpy(ifr.ifr_name, ifname);
181 up = 0;
182 if (ioctl(sfd, SIOCGIFFLAGS, &ifr) == 0) {
183 if ((up = ifr.ifr_flags & IFF_UP) != 0) {
184 ifr.ifr_flags &= ~IFF_UP;
185 if (ioctl(sfd, SIOCSIFFLAGS, &ifr) != 0) {
186 _dprintf("%s: %s %d\n", ifname, __FUNCTION__, __LINE__);
190 else {
191 _dprintf("%s: %s %d\n", ifname, __FUNCTION__, __LINE__);
194 if (!ether_atoe(nvram_safe_get(nvname), (unsigned char *)&ifr.ifr_hwaddr.sa_data)) {
195 if (!ether_atoe(nvram_safe_get("et0macaddr"), (unsigned char *)&ifr.ifr_hwaddr.sa_data)) {
197 // goofy et0macaddr, make something up
198 nvram_set("et0macaddr", "00:01:23:45:67:89");
199 ifr.ifr_hwaddr.sa_data[0] = 0;
200 ifr.ifr_hwaddr.sa_data[1] = 0x01;
201 ifr.ifr_hwaddr.sa_data[2] = 0x23;
202 ifr.ifr_hwaddr.sa_data[3] = 0x45;
203 ifr.ifr_hwaddr.sa_data[4] = 0x67;
204 ifr.ifr_hwaddr.sa_data[5] = 0x89;
207 while (plus-- > 0) {
208 for (j = 5; j >= 3; --j) {
209 ifr.ifr_hwaddr.sa_data[j]++;
210 if (ifr.ifr_hwaddr.sa_data[j] != 0) break; // continue if rolled over
215 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
216 if (ioctl(sfd, SIOCSIFHWADDR, &ifr) == -1) {
217 _dprintf("Error setting %s address\n", ifname);
220 if (up) {
221 if (ioctl(sfd, SIOCGIFFLAGS, &ifr) == 0) {
222 ifr.ifr_flags |= IFF_UP|IFF_RUNNING;
223 if (ioctl(sfd, SIOCSIFFLAGS, &ifr) == -1) {
224 _dprintf("%s: %s %d\n", ifname, __FUNCTION__, __LINE__);
227 else {
228 _dprintf("%s: %s %d\n", ifname, __FUNCTION__, __LINE__);
232 close(sfd);
236 const char *default_wanif(void)
238 return ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
239 (check_hw_type() == HW_BCM4712)) ? "vlan1" : "eth1";
244 const char *default_wlif(void)
246 switch (check_hw_type()) {
247 case HW_BCM4702:
248 case HW_BCM4704_BCM5325F:
249 case HW_BCM4704_BCM5325F_EWC:
250 return "eth2";
252 return "eth1";
257 int _vstrsep(char *buf, const char *sep, ...)
259 va_list ap;
260 char **p;
261 int n;
263 n = 0;
264 va_start(ap, sep);
265 while ((p = va_arg(ap, char **)) != NULL) {
266 if ((*p = strsep(&buf, sep)) == NULL) break;
267 ++n;
269 va_end(ap);
270 return n;
273 void simple_unlock(const char *name)
275 char fn[256];
277 snprintf(fn, sizeof(fn), "/var/lock/%s.lock", name);
278 f_write(fn, NULL, 0, 0, 0600);
281 void simple_lock(const char *name)
283 int n;
284 char fn[256];
286 n = 5 + (getpid() % 10);
287 snprintf(fn, sizeof(fn), "/var/lock/%s.lock", name);
288 while (unlink(fn) != 0) {
289 if (--n == 0) {
290 syslog(LOG_DEBUG, "Breaking %s", fn);
291 break;
293 sleep(1);
297 void killall_tk(const char *name)
299 int n;
301 if (killall(name, SIGTERM) == 0) {
302 n = 5;
303 while ((killall(name, 0) == 0) && (n-- > 0)) {
304 _dprintf("%s: waiting name=%s n=%d\n", __FUNCTION__, name, n);
305 sleep(1);
307 if (n < 0) {
308 n = 5;
309 while ((killall(name, SIGKILL) == 0) && (n-- > 0)) {
310 _dprintf("%s: SIGKILL name=%s n=%d\n", __FUNCTION__, name, n);
311 sleep(2);
317 long fappend(FILE *out, const char *fname)
319 FILE *in;
320 char buf[1024];
321 int n;
322 long r;
324 if ((in = fopen(fname, "r")) == NULL) return -1;
325 r = 0;
326 while ((n = fread(buf, 1, sizeof(buf), in)) > 0) {
327 if (fwrite(buf, 1, n, out) != n) {
328 r = -1;
329 break;
331 else {
332 r += n;
335 fclose(in);
336 return r;