Changes to update Tomato RAF.
[tomato.git] / release / src / router / httpd / iptraffic.c
blob9b395aa97bb378ddfb36bfec5cba0bffbd96b7c8
1 /*
3 IPTraffic monitoring extensions for Tomato
4 Copyright (C) 2011-2012 Augusto Bott
6 Tomato Firmware
7 Copyright (C) 2006-2009 Jonathan Zarate
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2
13 of the License, or (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
22 #include <arpa/inet.h>
23 #include <tomato.h>
24 #include <shared.h>
25 #include "iptraffic.h"
27 void asp_iptraffic(int argc, char **argv) {
28 char comma;
29 char sa[256];
30 FILE *a;
31 char ip[INET_ADDRSTRLEN];
33 char *exclude;
35 unsigned long tx_bytes, rx_bytes;
36 unsigned long tp_tcp, rp_tcp;
37 unsigned long tp_udp, rp_udp;
38 unsigned long tp_icmp, rp_icmp;
39 unsigned int ct_tcp, ct_udp;
41 exclude = nvram_safe_get("cstats_exclude");
43 Node tmp;
44 Node *ptr;
46 iptraffic_conntrack_init();
48 char br;
49 char name[] = "/proc/net/ipt_account/lanX";
51 web_puts("\n\niptraffic=[");
52 comma = ' ';
54 for(br=0 ; br<=3 ; br++) {
55 char bridge[2] = "0";
56 if (br!=0)
57 bridge[0]+=br;
58 else
59 strcpy(bridge, "");
61 sprintf(name, "/proc/net/ipt_account/lan%s", bridge);
63 if ((a = fopen(name, "r")) == NULL) continue;
65 fgets(sa, sizeof(sa), a); // network
66 while (fgets(sa, sizeof(sa), a)) {
67 if(sscanf(sa,
68 "ip = %s bytes_src = %lu %*u %*u %*u %*u packets_src = %*u %lu %lu %lu %*u bytes_dst = %lu %*u %*u %*u %*u packets_dst = %*u %lu %lu %lu %*u time = %*u",
69 ip, &tx_bytes, &tp_tcp, &tp_udp, &tp_icmp, &rx_bytes, &rp_tcp, &rp_udp, &rp_icmp) != 9 ) continue;
70 if (find_word(exclude, ip)) continue ;
71 if ((tx_bytes > 0) || (rx_bytes > 0)){
72 strncpy(tmp.ipaddr, ip, INET_ADDRSTRLEN);
73 ptr = TREE_FIND(&tree, _Node, linkage, &tmp);
74 if (!ptr) {
75 ct_tcp = 0;
76 ct_udp = 0;
77 } else {
78 ct_tcp = ptr->tcp_conn;
79 ct_udp = ptr->udp_conn;
81 web_printf("%c['%s', %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu]",
82 comma, ip, rx_bytes, tx_bytes, rp_tcp, tp_tcp, rp_udp, tp_udp, rp_icmp, tp_icmp, ct_tcp, ct_udp);
83 comma = ',';
86 fclose(a);
88 web_puts("];\n");
90 TREE_FORWARD_APPLY(&tree, _Node, linkage, Node_housekeeping, NULL);
91 TREE_INIT(&tree, Node_compare);
94 void iptraffic_conntrack_init() {
95 unsigned int a_time, a_proto;
96 char a_src[INET_ADDRSTRLEN];
97 char a_dst[INET_ADDRSTRLEN];
98 char b_src[INET_ADDRSTRLEN];
99 char b_dst[INET_ADDRSTRLEN];
101 char sa[256];
102 char sb[256];
103 FILE *a;
104 char *p;
105 int x;
107 Node tmp;
108 Node *ptr;
110 unsigned long rip[4];
111 unsigned long lan[4];
112 unsigned long mask[4];
113 unsigned short int br;
115 for(br=0 ; br<=3 ; br++) {
116 char bridge[2] = "0";
117 if (br!=0)
118 bridge[0]+=br;
119 else
120 strcpy(bridge, "");
121 sprintf(sa, "lan%s_ifname", bridge);
123 if (strcmp(nvram_safe_get(sa), "") != 0) {
124 sprintf(sa, "lan%s_ipaddr", bridge);
125 rip[br] = inet_addr(nvram_safe_get(sa));
126 sprintf(sa, "lan%s_netmask", bridge);
127 mask[br] = inet_addr(nvram_safe_get(sa));
128 lan[br] = rip[br] & mask[br];
129 // _dprintf("rip[%d]=%lu\n", br, rip[br]);
130 // _dprintf("mask[%d]=%lu\n", br, mask[br]);
131 // _dprintf("lan[%d]=%lu\n", br, lan[br]);
132 } else {
133 mask[br] = 0;
134 rip[br] = 0;
135 lan[br] = 0;
139 const char conntrack[] = "/proc/net/ip_conntrack";
141 if ((a = fopen(conntrack, "r")) == NULL) return;
143 ctvbuf(a); // if possible, read in one go
145 while (fgets(sa, sizeof(sa), a)) {
146 if (sscanf(sa, "%*s %u %u", &a_proto, &a_time) != 2) continue;
148 if ((a_proto != 6) && (a_proto != 17)) continue;
150 if ((p = strstr(sa, "src=")) == NULL) continue;
151 if (sscanf(p, "src=%s dst=%s %n", a_src, a_dst, &x) != 2) continue;
152 p += x;
154 if ((p = strstr(p, "src=")) == NULL) continue;
155 if (sscanf(p, "src=%s dst=%s", b_src, b_dst) != 2) continue;
157 snprintf(sb, sizeof(sb), "%s %s %s %s", a_src, a_dst, b_src, b_dst);
158 remove_dups(sb, sizeof(sb));
160 char ipaddr[INET_ADDRSTRLEN], *next = NULL;
161 char skip;
163 foreach(ipaddr, sb, next) {
164 skip = 1;
165 for(br=0 ; br<=3 ; br++) {
166 if ((mask[br] != 0) && ((inet_addr(ipaddr) & mask[br]) == lan[br])) {
167 skip = 0;
168 break;
171 if (skip == 1) continue;
173 strncpy(tmp.ipaddr, ipaddr, INET_ADDRSTRLEN);
174 ptr = TREE_FIND(&tree, _Node, linkage, &tmp);
176 if (!ptr) {
177 _dprintf("%s: new ip: %s\n", __FUNCTION__, ipaddr);
178 TREE_INSERT(&tree, _Node, linkage, Node_new(ipaddr));
179 ptr = TREE_FIND(&tree, _Node, linkage, &tmp);
181 if (a_proto == 6) ++ptr->tcp_conn;
182 if (a_proto == 17) ++ptr->udp_conn;
185 fclose(a);
186 // Tree_info();