4 Copyright (C) 2006-2009 Jonathan Zarate
15 #include <sys/ioctl.h>
17 #include <sys/socket.h>
18 #include <arpa/inet.h>
19 #include <sys/sysinfo.h>
20 #include <sys/types.h>
30 #define _dprintf cprintf
32 #define _dprintf(args...) do { } while(0)
36 int get_wan_proto(void)
38 const char *names
[] = { // order must be synced with def at shared.h
49 p
= nvram_safe_get("wan_proto");
50 for (i
= 0; names
[i
] != NULL
; ++i
) {
51 if (strcmp(p
, names
[i
]) == 0) return i
+ 1;
58 switch (get_wan_proto()) {
68 return ((nvram_match("wl_mode", "sta")) || (nvram_match("wl_mode", "wet")));
71 void notice_set(const char *path
, const char *format
, ...)
77 va_start(args
, format
);
78 vsnprintf(buf
, sizeof(buf
), format
, args
);
81 mkdir("/var/notice", 0755);
82 snprintf(p
, sizeof(p
), "/var/notice/%s", path
);
83 f_write_string(p
, buf
, 0, 0);
84 if (buf
[0]) syslog(LOG_INFO
, "notice[%s]: %s", path
, buf
);
88 // #define _x_dprintf(args...) syslog(LOG_DEBUG, args);
89 #define _x_dprintf(args...) do { } while (0);
101 proto
= get_wan_proto();
102 if (proto
== WP_DISABLED
) return 0;
104 if ((proto
== WP_PPTP
) || (proto
== WP_L2TP
) || (proto
== WP_PPPOE
)) {
105 if (f_read_string("/tmp/ppp/link", buf1
, sizeof(buf1
)) > 0) {
106 // contains the base name of a file in /var/run/ containing pid of a daemon
107 snprintf(buf2
, sizeof(buf2
), "/var/run/%s.pid", buf1
);
108 if (f_read_string(buf2
, buf1
, sizeof(buf1
)) > 0) {
109 name
= psname(atoi(buf1
), buf2
, sizeof(buf2
));
110 if (proto
== WP_PPPOE
) {
111 if (strcmp(name
, "pppoecd") == 0) up
= 1;
114 if (strcmp(name
, "pppd") == 0) up
= 1;
118 _dprintf("%s: error reading %s\n", __FUNCTION__
, buf2
);
121 unlink("/tmp/ppp/link");
122 _x_dprintf("required daemon not found, assuming link is dead\n");
126 _x_dprintf("%s: error reading %s\n", __FUNCTION__
, "/tmp/ppp/link");
129 else if (!nvram_match("wan_ipaddr", "0.0.0.0")) {
133 _x_dprintf("%s: default !up\n", __FUNCTION__
);
136 if ((up
) && ((f
= socket(AF_INET
, SOCK_DGRAM
, 0)) >= 0)) {
137 strlcpy(ifr
.ifr_name
, nvram_safe_get("wan_iface"), sizeof(ifr
.ifr_name
));
138 if (ioctl(f
, SIOCGIFFLAGS
, &ifr
) < 0) {
140 _x_dprintf("%s: SIOCGIFFLAGS\n", __FUNCTION__
);
143 if ((ifr
.ifr_flags
& IFF_UP
) == 0) {
145 _x_dprintf("%s: !IFF_UP\n", __FUNCTION__
);
153 const dns_list_t
*get_dns(void)
155 static dns_list_t dns
;
166 strlcpy(s
, nvram_safe_get("wan_dns"), sizeof(s
));
167 if ((nvram_get_int("dns_addget")) || (s
[0] == 0)) {
169 snprintf(s
+ n
, sizeof(s
) - n
, " %s", nvram_safe_get("wan_get_dns"));
172 n
= sscanf(s
, "%21s %21s %21s %21s", d
[0], d
[1], d
[2], d
[3]);
173 for (i
= 0; i
< n
; ++i
) {
176 if ((c
= strchr(d
[i
], ':')) != NULL
) {
178 if (((j
= atoi(c
)) < 1) || (j
> 0xFFFF)) continue;
182 if (inet_pton(AF_INET
, d
[i
], &ia
) > 0) {
183 for (j
= dns
.count
- 1; j
>= 0; --j
) {
184 if ((dns
.dns
[j
].addr
.s_addr
== ia
.s_addr
) && (dns
.dns
[j
].port
== port
)) break;
187 dns
.dns
[dns
.count
].port
= port
;
188 dns
.dns
[dns
.count
++].addr
.s_addr
= ia
.s_addr
;
189 if (dns
.count
== 3) break;
197 // -----------------------------------------------------------------------------
199 void set_action(int a
)
202 while (f_write("/var/lock/action", &a
, sizeof(a
), 0, 0) != sizeof(a
)) {
204 if (--r
== 0) return;
206 if (a
!= ACT_IDLE
) sleep(2);
209 int check_action(void)
214 while (f_read("/var/lock/action", &a
, sizeof(a
)) != sizeof(a
)) {
216 if (--r
== 0) return ACT_UNKNOWN
;
221 int wait_action_idle(int n
)
224 if (check_action() == ACT_IDLE
) return 1;
230 // -----------------------------------------------------------------------------
232 const char *get_wanip(void)
236 if (!check_wanup()) return "0.0.0.0";
237 switch (get_wan_proto()) {
250 return nvram_safe_get(p
);
253 long get_uptime(void)
264 return (wl_ioctl(nvram_safe_get("wl_ifname"), WLC_GET_RADIO
, &n
, sizeof(n
)) == 0) &&
265 ((n
& WL_RADIO_SW_DISABLE
) == 0);
268 void set_radio(int on
)
272 #ifndef WL_BSS_INFO_VERSION
273 #error WL_BSS_INFO_VERSION
276 #if WL_BSS_INFO_VERSION >= 108
277 n
= on
? (WL_RADIO_SW_DISABLE
<< 16) : ((WL_RADIO_SW_DISABLE
<< 16) | 1);
278 wl_ioctl(nvram_safe_get("wl_ifname"), WLC_SET_RADIO
, &n
, sizeof(n
));
284 n
= on
? 0 : WL_RADIO_SW_DISABLE
;
285 wl_ioctl(nvram_safe_get("wl_ifname"), WLC_SET_RADIO
, &n
, sizeof(n
));
292 int nvram_get_int(const char *key
)
294 return atoi(nvram_safe_get(key
));
298 long nvram_xget_long(const char *name, long min, long max, long def)
305 if ((p != NULL) && (*p != 0)) {
306 n = strtol(p, &e, 0);
307 if ((e != p) && ((*e == 0) || (*e == ' ')) && (n > min) && (n < max)) {
315 int nvram_get_file(const char *key
, const char *fname
, int max
)
323 p
= nvram_safe_get(key
);
326 if ((b
= malloc(base64_decoded_len(n
) + 128)) != NULL
) {
327 n
= base64_decode(p
, b
, n
);
328 if (n
> 0) r
= (f_write(fname
, b
, n
, 0, 0644) == n
);
338 p = nvram_safe_get(key);
341 n = base64_decode(p, b, n);
342 if (n > 0) return (f_write(fname, b, n, 0, 0700) == n);
348 int nvram_set_file(const char *key
, const char *fname
, int max
)
356 if ((len
= f_size(fname
)) > max
) return 0;
359 if (f_read_alloc(fname
, &in
, max
) == max
) {
360 if ((out
= malloc(base64_encoded_len(max
) + 128)) != NULL
) {
361 n
= base64_encode(in
, out
, max
);
375 if (((n = f_read(fname, &a, sizeof(a))) > 0) && (n <= max)) {
376 n = base64_encode(a, b, n);
385 int nvram_contains_word(const char *key
, const char *word
)
387 return (find_word(nvram_safe_get(key
), word
) != NULL
);
390 int nvram_is_empty(const char *key
)
393 return (((p
= nvram_get(key
)) == NULL
) || (*p
== 0));
396 void nvram_commit_x(void)
398 if (!nvram_get_int("debug_nocommit")) nvram_commit();
401 int connect_timeout(int fd
, const struct sockaddr
*addr
, socklen_t len
, int timeout
)
409 if (((flags
= fcntl(fd
, F_GETFL
, 0)) < 0) ||
410 (fcntl(fd
, F_SETFL
, flags
| O_NONBLOCK
) < 0)) {
411 _dprintf("%s: error in F_*ETFL %d\n", __FUNCTION__
, fd
);
415 if (connect(fd
, addr
, len
) < 0) {
416 // _dprintf("%s: connect %d = <0\n", __FUNCTION__, fd);
418 if (errno
!= EINPROGRESS
) {
419 _dprintf("%s: error in connect %d errno=%d\n", __FUNCTION__
, fd
, errno
);
428 r
= select(fd
+ 1, NULL
, &fds
, NULL
, &tv
);
430 _dprintf("%s: timeout in select %d\n", __FUNCTION__
, fd
);
434 if (errno
!= EINTR
) {
435 _dprintf("%s: error in select %d\n", __FUNCTION__
, fd
);
443 if ((getsockopt(fd
, SOL_SOCKET
, SO_ERROR
, &r
, &n
) < 0) || (r
!= 0)) {
444 _dprintf("%s: error in SO_ERROR %d\n", __FUNCTION__
, fd
);
452 if (fcntl(fd
, F_SETFL
, flags
) < 0) {
453 _dprintf("%s: error in F_*ETFL %d\n", __FUNCTION__
, fd
);
457 // _dprintf("%s: OK %d\n", __FUNCTION__, fd);
464 return time(0) > Y2K;