4 Copyright (C) 2006-2009 Jonathan Zarate
11 #include <sys/ioctl.h>
12 #include <net/if_arp.h>
20 void usage_exit(const char *cmd
, const char *help
)
22 fprintf(stderr
, "Usage: %s %s\n", cmd
, help
);
26 int modprobe(const char *mod
)
29 return eval("modprobe", "-s", (char *)mod
);
31 int r
= eval("modprobe", "-s", (char *)mod
);
32 cprintf("modprobe %s = %d\n", mod
, r
);
37 int modprobe_r(const char *mod
)
40 return eval("modprobe", "-r", (char *)mod
);
42 int r
= eval("modprobe", "-r", (char *)mod
);
43 cprintf("modprobe -r %s = %d\n", mod
, r
);
48 int _xstart(const char *cmd
, ...)
55 argv
[0] = (char *)cmd
;
58 while ((argv
[argc
++] = va_arg(ap
, char *)) != NULL
) {
63 return _eval(argv
, NULL
, 0, &pid
);
66 int endswith (char *str
, char *cmp
)
68 int cmp_len
, str_len
, i
;
70 cmp_len
= strlen (cmp
);
71 str_len
= strlen (str
);
72 if (cmp_len
> str_len
)
74 for (i
= 0; i
< cmp_len
; i
++) {
75 if (str
[(str_len
- 1) - i
] != cmp
[(cmp_len
- 1) - i
])
82 static void execute_with_maxwait(char *const argv
[], int wtime
)
86 if (_eval(argv
, NULL
, 0, &pid
) != 0)
90 waitpid(pid
, NULL
, WNOHANG
); /* Reap the zombie if it has terminated. */
91 if (kill(pid
, 0) != 0) break;
94 //printf("killdon: errno: %d pid %d\n", errno, pid);
98 void run_userfile (char *folder
, char *extension
, const char *arg1
, int wtime
)
100 struct dirent
*entry
;
102 unsigned char buf
[128];
105 //printf("run_userfile: check %s for *%s\n", folder, extension);
106 directory
= opendir (folder
);
107 if (directory
== NULL
)
110 while ((entry
= readdir (directory
)) != NULL
) {
111 if (endswith (entry
->d_name
, extension
)) {
112 sprintf (buf
, "%s/%s", folder
, entry
->d_name
);
114 argv
[1] = (char *)arg1
;
116 execute_with_maxwait(argv
, wtime
);
119 closedir (directory
);
123 /* Run user-supplied script(s), with 1 argument.
124 * Return when the script(s) have finished,
125 * or after wtime seconds, even if they aren't finished.
127 * Extract NAME from nvram variable named as "script_NAME".
129 * The sole exception to the nvram item naming rule is sesx.
130 * That one is "sesx_script" rather than "script_sesx", due
131 * to historical accident.
133 * The other exception is time-scheduled commands.
134 * These have names that start with "sch_".
135 * No directories are searched for corresponding user scripts.
137 * Execute in this order:
138 * nvram item: nv (run as a /bin/sh script)
139 * All files with a suffix of ".NAME" in these directories:
147 At this time, the names/events are:
148 sesx SES/AOSS Button custom script.
149 brau "bridge/auto" button pushed.
150 fire When firewall service has been started or re-started.
151 shut At system shutdown, just before wan/lan/usb/etc. are stopped.
152 init At system startup, just before wan/lan/usb/etc. are started.
153 The root filesystem and /jffs are mounted, but not any USB devices.
154 usbmount After an auto-mounted USB drive is mounted.
155 usbumount Before an auto-mounted USB drive is unmounted.
156 usbhotplug When any USB device is attached or removed.
157 wanup After WAN has come up.
160 void run_nvscript(const char *nv
, const char *arg1
, int wtime
)
168 script
= nvram_get(nv
);
169 if ((script
) && (*script
!= 0)) {
170 sprintf(s
, "/tmp/%s.sh", nv
);
171 if ((f
= fopen(s
, "w")) != NULL
) {
172 fputs("#!/bin/sh\n", f
);
181 argv
[1] = (char *)arg1
;
184 //printf("Running: '%s %s'\n", argv[0], argv[1]? argv[1]: "");
185 execute_with_maxwait(argv
, wtime
);
190 sprintf(s
, ".%s", nv
);
191 if (strncmp("sch_c", nv
, 5) == 0) {
194 else if (strncmp("sesx_", nv
, 5) == 0) {
197 else if (strncmp("script_", nv
, 7) == 0) {
198 strcpy(&s
[1], &nv
[7]);
201 if (nvram_match("userfiles_disable", "1")) {
202 // backdoor to disable user scripts execution
206 if ((check_dirs
) && strcmp(s
, ".")) {
207 //printf("checking for user scripts: '%s'\n", s);
208 run_userfile("/etc/config", s
, arg1
, wtime
);
209 run_userfile("/jffs/etc/config", s
, arg1
, wtime
);
210 run_userfile("/opt/etc/config", s
, arg1
, wtime
);
211 run_userfile("/mmc/etc/config", s
, arg1
, wtime
);
212 run_userfile("/tmp/config", s
, arg1
, wtime
);
216 static void write_ct_timeout(const char *type
, const char *name
, unsigned int val
)
218 unsigned char buf
[128];
221 sprintf(buf
, "/proc/sys/net/ipv4/netfilter/ip_conntrack_%s_timeout%s%s",
222 type
, (name
&& name
[0]) ? "_" : "", name
? name
: "");
223 sprintf(v
, "%u", val
);
225 f_write_string(buf
, v
, 0, 0);
228 #ifndef write_tcp_timeout
229 #define write_tcp_timeout(name, val) write_ct_timeout("tcp", name, val)
232 #ifndef write_udp_timeout
233 #define write_udp_timeout(name, val) write_ct_timeout("udp", name, val)
236 static unsigned int read_ct_timeout(const char *type
, const char *name
)
238 unsigned char buf
[128];
239 unsigned int val
= 0;
242 sprintf(buf
, "/proc/sys/net/ipv4/netfilter/ip_conntrack_%s_timeout%s%s",
243 type
, (name
&& name
[0]) ? "_" : "", name
? name
: "");
244 if (f_read_string(buf
, v
, sizeof(v
)) > 0)
250 #ifndef read_tcp_timeout
251 #define read_tcp_timeout(name) read_ct_timeout("tcp", name)
254 #ifndef read_udp_timeout
255 #define read_udp_timeout(name) read_ct_timeout("udp", name)
258 void setup_conntrack(void)
265 p
= nvram_safe_get("ct_tcp_timeout");
266 if (sscanf(p
, "%u%u%u%u%u%u%u%u%u%u",
267 &v
[0], &v
[1], &v
[2], &v
[3], &v
[4], &v
[5], &v
[6], &v
[7], &v
[8], &v
[9]) == 10) { // lightly verify
268 write_tcp_timeout("established", v
[1]);
269 write_tcp_timeout("syn_sent", v
[2]);
270 write_tcp_timeout("syn_recv", v
[3]);
271 write_tcp_timeout("fin_wait", v
[4]);
272 write_tcp_timeout("time_wait", v
[5]);
273 write_tcp_timeout("close", v
[6]);
274 write_tcp_timeout("close_wait", v
[7]);
275 write_tcp_timeout("last_ack", v
[8]);
278 v
[1] = read_tcp_timeout("established");
279 v
[2] = read_tcp_timeout("syn_sent");
280 v
[3] = read_tcp_timeout("syn_recv");
281 v
[4] = read_tcp_timeout("fin_wait");
282 v
[5] = read_tcp_timeout("time_wait");
283 v
[6] = read_tcp_timeout("close");
284 v
[7] = read_tcp_timeout("close_wait");
285 v
[8] = read_tcp_timeout("last_ack");
286 sprintf(buf
, "0 %u %u %u %u %u %u %u %u 0",
287 v
[1], v
[2], v
[3], v
[4], v
[5], v
[6], v
[7], v
[8]);
288 nvram_set("ct_tcp_timeout", buf
);
291 p
= nvram_safe_get("ct_udp_timeout");
292 if (sscanf(p
, "%u%u", &v
[0], &v
[1]) == 2) {
293 write_udp_timeout(NULL
, v
[0]);
294 write_udp_timeout("stream", v
[1]);
297 v
[0] = read_udp_timeout(NULL
);
298 v
[1] = read_udp_timeout("stream");
299 sprintf(buf
, "%u %u", v
[0], v
[1]);
300 nvram_set("ct_udp_timeout", buf
);
303 p
= nvram_safe_get("ct_timeout");
304 if (sscanf(p
, "%u%u", &v
[0], &v
[1]) == 2) {
305 write_ct_timeout("generic", NULL
, v
[0]);
306 write_ct_timeout("icmp", NULL
, v
[1]);
309 v
[0] = read_ct_timeout("generic", NULL
);
310 v
[1] = read_ct_timeout("icmp", NULL
);
311 sprintf(buf
, "%u %u", v
[0], v
[1]);
312 nvram_set("ct_timeout", buf
);
315 p
= nvram_safe_get("ct_max");
317 if ((i
>= 128) && (i
<= 10240)) {
318 f_write_string("/proc/sys/net/ipv4/ip_conntrack_max", p
, 0, 0);
321 if (!nvram_match("nf_pptp", "0")) {
322 modprobe("ip_conntrack_proto_gre");
323 modprobe("ip_nat_proto_gre");
324 modprobe("ip_conntrack_pptp");
325 modprobe("ip_nat_pptp");
328 modprobe_r("ip_nat_pptp");
329 modprobe_r("ip_conntrack_pptp");
330 modprobe_r("ip_nat_proto_gre");
331 modprobe_r("ip_conntrack_proto_gre");
334 if (!nvram_match("nf_h323", "0")) {
335 modprobe("ip_conntrack_h323");
336 modprobe("ip_nat_h323");
339 modprobe_r("ip_nat_h323");
340 modprobe_r("ip_conntrack_h323");
343 if (!nvram_match("nf_rtsp", "0")) {
344 modprobe("ip_conntrack_rtsp");
345 modprobe("ip_nat_rtsp");
348 modprobe_r("ip_nat_rtsp");
349 modprobe_r("ip_conntrack_rtsp");
354 i
= nvram_get_int("ftp_port");
355 if (nvram_match("ftp_enable", "1") && (i
> 0) && (i
!= 21))
359 sprintf(ports
, "ports=21,%d", i
);
360 eval("modprobe", "-s", "ip_conntrack_ftp", ports
);
361 eval("modprobe", "-s", "ip_nat_ftp", ports
);
365 if (!nvram_match("nf_ftp", "0")
367 || nvram_match("ftp_enable", "1") // !!TB - FTP Server
370 modprobe("ip_conntrack_ftp");
371 modprobe("ip_nat_ftp");
374 modprobe_r("ip_nat_ftp");
375 modprobe_r("ip_conntrack_ftp");
380 void set_mac(const char *ifname
, const char *nvname
, int plus
)
387 if ((sfd
= socket(AF_INET
, SOCK_RAW
, IPPROTO_RAW
)) < 0) {
388 _dprintf("%s: %s %d\n", ifname
, __FUNCTION__
, __LINE__
);
392 strcpy(ifr
.ifr_name
, ifname
);
395 if (ioctl(sfd
, SIOCGIFFLAGS
, &ifr
) == 0) {
396 if ((up
= ifr
.ifr_flags
& IFF_UP
) != 0) {
397 ifr
.ifr_flags
&= ~IFF_UP
;
398 if (ioctl(sfd
, SIOCSIFFLAGS
, &ifr
) != 0) {
399 _dprintf("%s: %s %d\n", ifname
, __FUNCTION__
, __LINE__
);
404 _dprintf("%s: %s %d\n", ifname
, __FUNCTION__
, __LINE__
);
407 if (!ether_atoe(nvram_safe_get(nvname
), (unsigned char *)&ifr
.ifr_hwaddr
.sa_data
)) {
408 if (!ether_atoe(nvram_safe_get("et0macaddr"), (unsigned char *)&ifr
.ifr_hwaddr
.sa_data
)) {
410 // goofy et0macaddr, make something up
411 nvram_set("et0macaddr", "00:01:23:45:67:89");
412 ifr
.ifr_hwaddr
.sa_data
[0] = 0;
413 ifr
.ifr_hwaddr
.sa_data
[1] = 0x01;
414 ifr
.ifr_hwaddr
.sa_data
[2] = 0x23;
415 ifr
.ifr_hwaddr
.sa_data
[3] = 0x45;
416 ifr
.ifr_hwaddr
.sa_data
[4] = 0x67;
417 ifr
.ifr_hwaddr
.sa_data
[5] = 0x89;
421 for (j
= 5; j
>= 3; --j
) {
422 ifr
.ifr_hwaddr
.sa_data
[j
]++;
423 if (ifr
.ifr_hwaddr
.sa_data
[j
] != 0) break; // continue if rolled over
428 ifr
.ifr_hwaddr
.sa_family
= ARPHRD_ETHER
;
429 if (ioctl(sfd
, SIOCSIFHWADDR
, &ifr
) == -1) {
430 _dprintf("Error setting %s address\n", ifname
);
434 if (ioctl(sfd
, SIOCGIFFLAGS
, &ifr
) == 0) {
435 ifr
.ifr_flags
|= IFF_UP
|IFF_RUNNING
;
436 if (ioctl(sfd
, SIOCSIFFLAGS
, &ifr
) == -1) {
437 _dprintf("%s: %s %d\n", ifname
, __FUNCTION__
, __LINE__
);
441 _dprintf("%s: %s %d\n", ifname
, __FUNCTION__
, __LINE__
);
449 const char *default_wanif(void)
451 return ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
452 (check_hw_type() == HW_BCM4712)) ? "vlan1" : "eth1";
457 const char *default_wlif(void)
459 switch (check_hw_type()) {
461 case HW_BCM4704_BCM5325F:
462 case HW_BCM4704_BCM5325F_EWC:
470 int _vstrsep(char *buf
, const char *sep
, ...)
478 while ((p
= va_arg(ap
, char **)) != NULL
) {
479 if ((*p
= strsep(&buf
, sep
)) == NULL
) break;
486 void simple_unlock(const char *name
)
490 snprintf(fn
, sizeof(fn
), "/var/lock/%s.lock", name
);
491 f_write(fn
, NULL
, 0, 0, 0600);
494 void simple_lock(const char *name
)
499 n
= 5 + (getpid() % 10);
500 snprintf(fn
, sizeof(fn
), "/var/lock/%s.lock", name
);
501 while (unlink(fn
) != 0) {
503 syslog(LOG_DEBUG
, "Breaking %s", fn
);
510 void killall_tk(const char *name
)
514 if (killall(name
, SIGTERM
) == 0) {
516 while ((killall(name
, 0) == 0) && (n
-- > 0)) {
517 _dprintf("%s: waiting name=%s n=%d\n", __FUNCTION__
, name
, n
);
522 while ((killall(name
, SIGKILL
) == 0) && (n
-- > 0)) {
523 _dprintf("%s: SIGKILL name=%s n=%d\n", __FUNCTION__
, name
, n
);
530 long fappend(FILE *out
, const char *fname
)
537 if ((in
= fopen(fname
, "r")) == NULL
) return -1;
539 while ((n
= fread(buf
, 1, sizeof(buf
), in
)) > 0) {
540 if (fwrite(buf
, 1, n
, out
) != n
) {