3 IPTraffic monitoring extensions for Tomato
4 Copyright (C) 2011-2012 Augusto Bott
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>
25 #include "iptraffic.h"
27 void asp_iptraffic(int argc
, char **argv
) {
31 char ip
[INET_ADDRSTRLEN
];
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");
46 iptraffic_conntrack_init();
49 char name
[] = "/proc/net/ipt_account/lanX";
51 web_puts("\n\niptraffic=[");
54 for(br
=0 ; br
<=3 ; br
++) {
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
)) {
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
);
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
);
90 TREE_FORWARD_APPLY(&tree
, _Node
, linkage
, Node_housekeeping
, NULL
);
93 void iptraffic_conntrack_init() {
94 unsigned int a_time
, a_proto
;
95 char a_src
[INET_ADDRSTRLEN
];
96 char a_dst
[INET_ADDRSTRLEN
];
97 char b_src
[INET_ADDRSTRLEN
];
98 char b_dst
[INET_ADDRSTRLEN
];
109 unsigned long rip
[4];
110 unsigned long lan
[4];
111 unsigned long mask
[4];
112 unsigned short int br
;
114 for(br
=0 ; br
<=3 ; br
++) {
115 char bridge
[2] = "0";
120 sprintf(sa
, "lan%s_ifname", bridge
);
122 if (strcmp(nvram_safe_get(sa
), "") != 0) {
123 sprintf(sa
, "lan%s_ipaddr", bridge
);
124 rip
[br
] = inet_addr(nvram_safe_get(sa
));
125 sprintf(sa
, "lan%s_netmask", bridge
);
126 mask
[br
] = inet_addr(nvram_safe_get(sa
));
127 lan
[br
] = rip
[br
] & mask
[br
];
128 // _dprintf("rip[%d]=%lu\n", br, rip[br]);
129 // _dprintf("mask[%d]=%lu\n", br, mask[br]);
130 // _dprintf("lan[%d]=%lu\n", br, lan[br]);
138 const char conntrack
[] = "/proc/net/ip_conntrack";
140 if ((a
= fopen(conntrack
, "r")) == NULL
) return;
142 ctvbuf(a
); // if possible, read in one go
144 while (fgets(sa
, sizeof(sa
), a
)) {
145 if (sscanf(sa
, "%*s %u %u", &a_proto
, &a_time
) != 2) continue;
147 if ((a_proto
!= 6) && (a_proto
!= 17)) continue;
149 if ((p
= strstr(sa
, "src=")) == NULL
) continue;
150 if (sscanf(p
, "src=%s dst=%s %n", a_src
, a_dst
, &x
) != 2) continue;
153 if ((p
= strstr(p
, "src=")) == NULL
) continue;
154 if (sscanf(p
, "src=%s dst=%s", b_src
, b_dst
) != 2) continue;
156 snprintf(sb
, sizeof(sb
), "%s %s %s %s", a_src
, a_dst
, b_src
, b_dst
);
157 remove_dups(sb
, sizeof(sb
));
159 char ipaddr
[INET_ADDRSTRLEN
], *next
= NULL
;
162 foreach(ipaddr
, sb
, next
) {
164 for(br
=0 ; br
<=3 ; br
++) {
165 if ((mask
[br
] != 0) && ((inet_addr(ipaddr
) & mask
[br
]) == lan
[br
])) {
170 if (skip
== 1) continue;
172 strncpy(tmp
.ipaddr
, ipaddr
, INET_ADDRSTRLEN
);
173 ptr
= TREE_FIND(&tree
, _Node
, linkage
, &tmp
);
176 _dprintf("%s: new ip: %s\n", __FUNCTION__
, ipaddr
);
177 TREE_INSERT(&tree
, _Node
, linkage
, Node_new(ipaddr
));
178 ptr
= TREE_FIND(&tree
, _Node
, linkage
, &tmp
);
180 if (a_proto
== 6) ++ptr
->tcp_conn
;
181 if (a_proto
== 17) ++ptr
->udp_conn
;