Tomato 1.28
[tomato.git] / release / src / router / httpd / ctnf.c
blobf65aa35c7ea0e62052ec2ed0f938f874915ed1e9
1 /*
3 Tomato Firmware
4 Copyright (C) 2006-2009 Jonathan Zarate
6 */
8 #include "tomato.h"
10 #include <ctype.h>
11 #include <sys/sysinfo.h>
12 #include <sys/stat.h>
13 #include <sys/ioctl.h>
14 #include <net/if.h>
15 #include <fcntl.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 #include <sys/types.h>
20 #include <time.h>
21 #include <dirent.h>
24 static void ctvbuf(FILE *f)
26 int n;
27 struct sysinfo si;
28 // meminfo_t mem;
30 #if 1
31 const char *p;
33 if ((p = nvram_get("ct_max")) != NULL) {
34 n = atoi(p);
35 if (n == 0) n = 2048;
36 else if (n < 1024) n = 1024;
37 else if (n > 10240) n = 10240;
39 else {
40 n = 2048;
42 #else
43 char s[64];
45 if (f_read_string("/proc/sys/net/ipv4/ip_conntrack_max", s, sizeof(s)) > 0) n = atoi(s);
46 else n = 1024;
47 if (n < 1024) n = 1024;
48 else if (n > 10240) n = 10240;
49 #endif
51 n *= 170; // avg tested
53 // get_memory(&mem);
54 // if (mem.maxfreeram < (n + (64 * 1024))) n = mem.maxfreeram - (64 * 1024);
56 sysinfo(&si);
57 if (si.freeram < (n + (64 * 1024))) n = si.freeram - (64 * 1024);
59 // cprintf("free: %dK, buffer: %dK\n", si.freeram / 1024, n / 1024);
61 if (n > 4096) {
62 // n =
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
74 FILE *f;
75 char s[512];
76 char *p;
77 int i;
78 int n;
79 int mode;
80 unsigned long rip;
81 unsigned long lan;
82 unsigned long mask;
84 if (argc != 1) return;
85 mode = atoi(argv[0]);
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"));
95 lan = rip & mask;
97 else {
98 rip = lan = mask = 0;
101 while (fgets(s, sizeof(s), f)) {
102 if (rip != 0) {
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;
111 if (mode == 0) {
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) {
116 count[i]++;
117 break;
121 else if (strncmp(s, "udp", 3) == 0) {
122 if (strstr(s, "[UNREPLIED]") != NULL) {
123 count[10]++;
125 else if (strstr(s, "[ASSURED]") != NULL) {
126 count[11]++;
129 count[12]++;
131 else {
132 // count connections per mark
133 if ((p = strstr(s, " mark=")) != NULL) {
134 n = atoi(p + 6) & 0xFF;
135 if (n <= 10) count[n]++;
140 fclose(f);
143 if (mode == 0) {
144 p = s;
145 for (i = 0; i < 12; ++i) {
146 p += sprintf(p, ",%d", count[i]);
148 web_printf("\nconntrack = [%d%s];\n", count[12], s);
150 else {
151 p = 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)
161 FILE *f;
162 char s[512];
163 char *p, *q;
164 int mark;
165 int findmark;
166 unsigned int proto;
167 unsigned int time;
168 char src[16];
169 char dst[16];
170 char sport[16];
171 char dport[16];
172 unsigned long rip;
173 unsigned long lan;
174 unsigned long mask;
175 char comma;
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"));
183 lan = rip & mask;
184 if (nvram_match("t_hidelr", "0")) rip = 0; // hide lan -> router?
186 web_puts("\nctdump = [");
187 comma = ' ';
188 if ((f = fopen("/proc/net/ip_conntrack", "r")) != NULL) {
189 ctvbuf(f);
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
202 else if (rip != 0) {
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;
211 else {
212 if (sscanf(p + 4, "%s dst=%s", src, dst) != 2) continue;
213 sport[0] = 0;
214 dport[0] = 0;
217 web_printf("%c[%u,%u,'%s','%s','%s','%s',%d]", comma, proto, time, src, dst, sport, dport, mark);
218 comma = ',';
221 web_puts("];\n");
224 void asp_qrate(int argc, char **argv)
226 FILE *f;
227 char s[256];
228 unsigned long rates[10];
229 unsigned long u;
230 char *e;
231 int n;
232 char comma;
233 char *a[1];
235 a[0] = "1";
236 asp_ctcount(1, a);
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) {
241 n = 1;
242 while (fgets(s, sizeof(s), f)) {
243 if (strncmp(s, "class htb 1:", 12) == 0) {
244 n = atoi(s + 12);
246 else if (strncmp(s, " rate ", 6) == 0) {
247 if ((n % 10) == 0) {
248 n /= 10;
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;
253 rates[n - 1] = u;
254 n = 1;
259 pclose(f);
262 comma = ' ';
263 web_puts("\nqrates = [0,");
264 for (n = 0; n < 10; ++n) {
265 web_printf("%c%lu", comma, rates[n]);
266 comma = ',';
268 web_puts("];");
271 static void layer7_list(const char *path, int *first)
273 DIR *dir;
274 struct dirent *de;
275 char *p;
276 char name[NAME_MAX];
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;
282 *p = 0;
283 web_printf("%s'%s'", *first ? "" : ",", name);
284 *first = 0;
286 closedir(dir);
290 void asp_layer7(int argc, char **argv)
292 int first = 1;
293 web_puts("\nlayer7 = [");
294 layer7_list("/etc/l7-extra", &first);
295 layer7_list("/etc/l7-protocols", &first);
296 web_puts("];\n");
299 void wo_expct(char *url)
301 f_write_string("/proc/net/expire_early", "15", 0, 0);