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
);
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
];
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";
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]);
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;
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
;
163 foreach(ipaddr
, sb
, next
) {
165 for(br
=0 ; br
<=3 ; br
++) {
166 if ((mask
[br
] != 0) && ((inet_addr(ipaddr
) & mask
[br
]) == lan
[br
])) {
171 if (skip
== 1) continue;
173 strncpy(tmp
.ipaddr
, ipaddr
, INET_ADDRSTRLEN
);
174 ptr
= TREE_FIND(&tree
, _Node
, linkage
, &tmp
);
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
;