4 Copyright (C) 2006-2009 Jonathan Zarate
11 #include <sys/sysinfo.h>
13 #include <sys/ioctl.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 #include <sys/types.h>
24 static void ctvbuf(FILE *f
)
33 if ((p
= nvram_get("ct_max")) != NULL
) {
36 else if (n
< 1024) n
= 1024;
37 else if (n
> 10240) n
= 10240;
45 if (f_read_string("/proc/sys/net/ipv4/ip_conntrack_max", s
, sizeof(s
)) > 0) n
= atoi(s
);
47 if (n
< 1024) n
= 1024;
48 else if (n
> 10240) n
= 10240;
51 n
*= 170; // avg tested
54 // if (mem.maxfreeram < (n + (64 * 1024))) n = mem.maxfreeram - (64 * 1024);
57 if (si
.freeram
< (n
+ (64 * 1024))) n
= si
.freeram
- (64 * 1024);
59 // cprintf("free: %dK, buffer: %dK\n", si.freeram / 1024, n / 1024);
63 setvbuf(f
, NULL
, _IOFBF
, n
);
64 // cprintf("setvbuf = %d\n", n);
68 void asp_ctcount(int argc
, char **argv
)
70 static const char *states
[10] = {
71 "NONE", "ESTABLISHED", "SYN_SENT", "SYN_RECV", "FIN_WAIT",
72 "TIME_WAIT", "CLOSE", "CLOSE_WAIT", "LAST_ACK", "LISTEN" };
73 int count
[13]; // tcp(10) + udp(2) + total(1) = 13 / max classes = 10
84 if (argc
!= 1) return;
87 memset(count
, 0, sizeof(count
));
89 if ((f
= fopen("/proc/net/ip_conntrack", "r")) != NULL
) {
90 ctvbuf(f
); // if possible, read in one go
92 if (nvram_match("t_hidelr", "1")) {
93 mask
= inet_addr(nvram_safe_get("lan_netmask"));
94 rip
= inet_addr(nvram_safe_get("lan_ipaddr"));
101 while (fgets(s
, sizeof(s
), f
)) {
103 // src=x.x.x.x dst=x.x.x.x // DIR_ORIGINAL
104 if ((p
= strstr(s
+ 14, "src=")) == NULL
) continue;
105 if ((inet_addr(p
+ 4) & mask
) == lan
) {
106 if ((p
= strstr(p
+ 13, "dst=")) == NULL
) continue;
107 if (inet_addr(p
+ 4) == rip
) continue;
112 // count connections per state
113 if (strncmp(s
, "tcp", 3) == 0) {
114 for (i
= 9; i
>= 0; --i
) {
115 if (strstr(s
, states
[i
]) != NULL
) {
121 else if (strncmp(s
, "udp", 3) == 0) {
122 if (strstr(s
, "[UNREPLIED]") != NULL
) {
125 else if (strstr(s
, "[ASSURED]") != NULL
) {
132 // count connections per mark
133 if ((p
= strstr(s
, " mark=")) != NULL
) {
134 n
= atoi(p
+ 6) & 0xFF;
135 if (n
<= 10) count
[n
]++;
145 for (i
= 0; i
< 12; ++i
) {
146 p
+= sprintf(p
, ",%d", count
[i
]);
148 web_printf("\nconntrack = [%d%s];\n", count
[12], s
);
152 for (i
= 1; i
< 11; ++i
) {
153 p
+= sprintf(p
, ",%d", count
[i
]);
155 web_printf("\nnfmarks = [%d%s];\n", count
[0], s
);
159 void asp_ctdump(int argc
, char **argv
)
177 if (argc
!= 1) return;
179 findmark
= atoi(argv
[0]);
181 mask
= inet_addr(nvram_safe_get("lan_netmask"));
182 rip
= inet_addr(nvram_safe_get("lan_ipaddr"));
184 if (nvram_match("t_hidelr", "0")) rip
= 0; // hide lan -> router?
186 web_puts("\nctdump = [");
188 if ((f
= fopen("/proc/net/ip_conntrack", "r")) != NULL
) {
190 while (fgets(s
, sizeof(s
), f
)) {
191 if ((p
= strstr(s
, " mark=")) == NULL
) continue;
192 if ((mark
= (atoi(p
+ 6) & 0xFF)) > 10) mark
= 0;
193 if ((findmark
!= -1) && (mark
!= findmark
)) continue;
195 if (sscanf(s
, "%*s %u %u", &proto
, &time
) != 2) continue;
197 if ((p
= strstr(s
+ 14, "src=")) == NULL
) continue; // DIR_ORIGINAL
198 if ((inet_addr(p
+ 4) & mask
) != lan
) {
199 // make sure we're seeing int---ext if possible
200 if ((p
= strstr(p
+ 41, "src=")) == NULL
) continue; // DIR_REPLY
203 if ((q
= strstr(p
+ 13, "dst=")) == NULL
) continue;
204 // cprintf("%lx=%lx\n", inet_addr(q + 4), rip);
205 if (inet_addr(q
+ 4) == rip
) continue;
208 if ((proto
== 6) || (proto
== 17)) {
209 if (sscanf(p
+ 4, "%s dst=%s sport=%s dport=%s", src
, dst
, sport
, dport
) != 4) continue;
212 if (sscanf(p
+ 4, "%s dst=%s", src
, dst
) != 2) continue;
217 web_printf("%c[%u,%u,'%s','%s','%s','%s',%d]", comma
, proto
, time
, src
, dst
, sport
, dport
, mark
);
224 void asp_qrate(int argc
, char **argv
)
228 unsigned long rates
[10];
238 memset(rates
, 0, sizeof(rates
));
239 sprintf(s
, "tc -s class ls dev %s", nvram_safe_get("wan_iface"));
240 if ((f
= popen(s
, "r")) != NULL
) {
242 while (fgets(s
, sizeof(s
), f
)) {
243 if (strncmp(s
, "class htb 1:", 12) == 0) {
246 else if (strncmp(s
, " rate ", 6) == 0) {
249 if ((n
>= 1) && (n
<= 10)) {
250 u
= strtoul(s
+ 6, &e
, 10);
251 if (*e
== 'K') u
*= 1000;
252 else if (*e
== 'M') u
*= 1000 * 1000;
263 web_puts("\nqrates = [0,");
264 for (n
= 0; n
< 10; ++n
) {
265 web_printf("%c%lu", comma
, rates
[n
]);
271 static void layer7_list(const char *path
, int *first
)
278 if ((dir
= opendir(path
)) != NULL
) {
279 while ((de
= readdir(dir
)) != NULL
) {
280 strlcpy(name
, de
->d_name
, sizeof(name
));
281 if ((p
= strstr(name
, ".pat")) == NULL
) continue;
283 web_printf("%s'%s'", *first
? "" : ",", name
);
290 void asp_layer7(int argc
, char **argv
)
293 web_puts("\nlayer7 = [");
294 layer7_list("/etc/l7-extra", &first
);
295 layer7_list("/etc/l7-protocols", &first
);
299 void wo_expct(char *url
)
301 f_write_string("/proc/net/expire_early", "15", 0, 0);