我正在开发一款监控网络使用情况的应用。但是我发现很多方法都不允许排除本地流量(例如,Time Machine)。
我正在寻找一种排除本地流量的方法,并且仅监控直接进出互联网的使用情况。
更新:感谢您的回复,现在我知道如何查找流量是否为本地,但我仍然不知道如何计算总输入/输出字节(对不起,如果我之前没有详细说明)。我无法知道在特定时间段内或自OS启动以来在本地(或互联网)发送/接收的字节数。当OS运行时启动或终止事实过程会使这个问题变得更加复杂。
问题How to get network adapter stats in linux/Mac OSX?的答案提供了一种总结使用量的有趣方法,但它没有帮助,因为它总结的用法是界面统计。
更新2 :我已经发布了我的最终解决方案。请向下滚动一下以查看。
答案 0 :(得分:2)
回答您对哪些接口带有本地流量的评论实际上很复杂,因为它取决于您对本地流量的含义。
“本地流量”最简单的含义是不会使机器生成的流量(例如,同一台机器上的两个程序相互通信)。这种流量都超过了。这是人们在说当地话时所说的一件事(当我回答时我想到的是什么)。
下一个最简单的含义是“发往同一子网上的计算机的IP流量”。那是在本地子网内有目的地址的流量。最简单的计算方法是路由表(如果Mac OS X计算每条路由的流量统计数据,各种网关上的路由将为您提供非本地流量)或者使用防火墙规则。 当他们说“本地流量”时,这可能不希望任何人意味着。
另一个含义是“用于此(物理)位置的机器的IP流量”。例如,在我的办公室,我们有几个正在使用的子网,它们之间有路由器,但是从一个子网到另一个子网的流量仍然是本地的。您需要网络知识来区分本地流量和非本地流量。
另一个含义是“发往我组织的机器的IP流量”。这是一个合理的含义,具体取决于您的网络设置方式(例如,您的位置之间可能有快速光纤,但您的Internet连接速度要慢得多,或按GB收费)。需要深入了解网络以确定目的地是否是本地目的 - 而且,对于像VPN这样的事情,可能会随着时间而变化。
最后,“互联网流量”并非与任何相反。有时候,例如,以太网网段上的本地计算机实际上是通过互联网上的VPN(这并不疯狂,它对于远程用户需要使用各种Windows服务时非常有用)。您组织内的流量可以轻松通过Internet VPN传输。
如果网络非常简单,只有一个内部子网,只有一个路由器,并且所有不属于该内部子网的流量都是互联网流量,您可以作弊并解决此问题。这可能适用于绝大多数家庭网络,以及许多小型企业网络。
在简单的网络设置中,您可以做出一些假设,并通过将流量计为非本地来获得足够接近的答案:
或者:
您可以创建防火墙规则来计算其中任何一个。至少可以使用Linux iptables,我很确定BSD pf,可能还有Mac OS X.
最后,如果您不能使用防火墙规则(因为它需要root),您可能希望默认网关响应SNMP社区公共,浏览其所有接口,并找到具有子网外的接口IP地址,然后假设是Internet链接。然后,您可以询问路由器在该接口上的流量计数。
当然,您会发现许多SOHO路由器不支持SNMP,而那些可能没有开启的SOHO路由器。
答案 1 :(得分:1)
最好的方法是通过eth0,eth1或任何具有系统调用ifconfig的适配器来查找“外部”ip地址。然后为任何系统(消息,系统日志,等等)拉日志,并为该外部IP地址编写过滤器。为了使它更好,更便携,编写一个正则表达式,只过滤可公共路由的IP,只过滤消息记录该“外部”IP地址。
答案 2 :(得分:1)
您需要阅读ifconfig(8)的源代码,它描述了如何获取每个连接的网络接口的状态。
特别注意in_status(),它获取接口的inet地址和网络掩码。
当流量中的源或目标地址与本地接口具有相同的主机时
int is_local =
(src && netmask) == (ifaddr && netmask)
|| (dst && netmask) == (ifaddr && netmask)
然后你可以确定它是本地的
http://www.opensource.apple.com/source/network_cmds/network_cmds-307/ifconfig.tproj/ifconfig.c
答案 3 :(得分:0)
我认为,近似解决方案:getifaddrs可用于获取有关网络使用情况的统计信息。
它可以获得Wi-Fi和WWAN接口的单独统计信息。
您可以从以下网址找到更多信息:
http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=getifaddrs
答案 4 :(得分:0)
这取决于你如何定义“本地”,但常见的定义是查看网络掩码。
例如,如果您的IP(即您监控的接口的IP是
)10.33.52.123
netmask 255.255.255.0
这意味着每个具有source-IP和destination-IP 10.33.52.xx的IP数据包都是本地的。
我不知道cocoa或objective-c,但您可以使用其中一些功能帮助您从IP地址中提取网络:http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/inet_network.3.html
答案 5 :(得分:0)
不知道如何在objective-c中实现它,但想法是你得到你所在网络的地址(你可以从你的本地网络类(A,B,C)中找到它) ip或来自网络掩码中的位(如果它不是标准的),然后只检查传出连接的地址。如果目的地不在您的本地网络中,则计算流量;如果它在,只是什么也不做。
答案 6 :(得分:0)
有三种不可路由的IP地址范围,它们通常用作NAT服务的地址范围。任何不可路由的地址范围内的地址都是外部地址。
当然,如果你不在NAT路由器后面,那么任务就更难了(从技术上讲,此时所有地址不足127.0.0.1都是外部的。)
不可路由的IP范围是:
10.0.0.0 - 10.255.255.255
172.16.0.0 - 172.31.255.255
192.168.0.0 - 192.168.255.255
答案 7 :(得分:0)
我的最终工作解决方案是使用libpcap
来实现这一目标。当然有一些缺点,包括它需要提升的权限,并且必须捕获所有过滤的数据包以计算统计数据,但至少它运行良好。
关于libpcap
的许多文档和教程都相当透彻和明确,我建议每个对这个解决方案感兴趣的人都要看看那些google-fu努力相对较少的人。
此外,我的网络流量过滤器可能只是以下几点 -
- (NSString *)_internetFilterStringForInterface:(AKNetworkInterface *)interface
inOrOut:(BOOL)inYesOutNo
{
if (![interface net] || ![interface mask] || IsEmpty([interface addresses]))
{
return nil;
}
NSString *hostType = inYesOutNo ? @"dst" : @"src";
NSString *host = nil;
for (NSString *hostComponent in [interface addresses])
{
if (IsEmpty(hostComponent)) continue;
if (!host)
host = [NSString stringWithFormat:@"(%@ host %@", hostType, hostComponent];
else
host = [host stringByAppendingFormat:@" or %@ host %@", hostType, hostComponent];
}
host = [host stringByAppendingString:@")"];
NSString *net = [interface netString];
net = [net stringByReplacingOccurrencesOfString:@".0" withString:@""];
NSString *filter = [NSString stringWithFormat:
@"ip and (not %@ net %@) and %@",
inYesOutNo ? @"src" : @"dst",
net, host];
return filter;
}
过滤器的设计有一些关于什么算作“本地流量”的答案,我知道它不包含一些边缘情况,如双NAT配置等,但我希望看到有关此的建议。 / p>
我知道net = [net stringByReplacingOccurrencesOfString:@".0" withString:@""];
只是一个快速的黑客攻击,在某些特殊情况下很容易失败但是没有人在抱怨,至少现在还没有。