我正在开发一个监控网络使用情况的应用程序。然而,我注意到许多方法都不允许排除本地流量(例如,时间机器)。

我正在寻找一种排除本地流量的方法,并且仅监视直接进出互联网的使用情况。

更新:谢谢您的回复,现在我知道如何查找流量是否是本地的,但我仍然不知道如何计算总输入/输出字节(抱歉,如果我之前没有详细说明)。我无法知道在特定时间段内或自操作系统启动以来本地(或互联网)发送/接收了多少字节。由于操作系统运行时进程会启动或终止,这个问题变得更加复杂。

问题的答案 如何在 Linux/Mac OSX 中获取网络适配器统计信息? 提供了一种总结总使用情况的有趣方法,但它没有帮助,因为它总结的使用情况是接口统计信息。

更新2:我已经发布了我的最终解决方案。请向下滚动一点查看。

有帮助吗?

解决方案 8

我拥有的最终工作解决方案是使用 libpcap 为达到这个。当然,有一些缺点,其中包括它需要提高特权,并且必须捕获所有过滤的数据包以计算统计数据,但至少效果很好。

许多文档和教程 libpcap 我建议每个对此解决方案感兴趣的人都相当透彻和清晰,以相对较少的Google-Fu努力来查看那些。

另外,我的Internet流量过滤器仅仅是以下内容 - 可能会感兴趣 -

- (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;
}

该过滤器的设计具有有关“本地流量”的一些答案,我知道它不包括一些边缘案例,例如Double NAT配置等,但我想了解有关此的建议。

我知道 net = [net stringByReplacingOccurrencesOfString:@".0" withString:@""]; 只是一个快速的黑客,在某些特殊情况下很容易失败,但是嘿,没有人抱怨,至少还没有。

其他提示

回答您对哪种接口带来本地流量的评论实际上很复杂,因为这取决于您的本地流量的含义。

“本地”意味着什么

“本地流量”的最简单含义是流量不会使机器生成的计算机(例如,同一台计算机上的两个程序相互交谈)。这个流量全部结束了。当人们说本地时(以及我回答时我在想什么),这是一件事。

下一个最简单的含义将是“ IP流量,注定是同一子网上的机器”。那将是在本地子网内部具有目标地址的流量。最简单的计算方法将是路由表(如果MAC OS X计算每个路线的流量统计信息,则各种网关上的路由将为您提供非本地流量),也可以使用防火墙规则。 当他们说“本地流量”时,这可能不希望任何人意味着。

另一个含义将是“ IP流量注定要在此(物理)位置中的计算机”。例如,在我的办公室使用了几个子网,它们之间有路由器,但是从一个子网到另一个子网的流量显然仍然是本地的。您需要网络知识,以将本地与非本地流量区分开,并使用此定义。

另一个含义将是“ IP流量注定为我的组织中的机器”。这是一个合理的含义,具体取决于您的网络的设置方式(例如,您的位置之间的光纤也很快,但是您的互联网连接速度较慢,或者收费的每GB)。需要深入了解网络的知识,以确定目的地是否将是本地的,并且与VPN这样的事物 可能会随着时间的流逝而有所不同。

最后,“互联网流量”不是 任何 那些。有时,例如,以太网段上似乎是本地计算机上的本地计算机实际上是通过Internet上的VPN(这不是疯狂的,这对于远程用户需要使用各种Windows服务非常有用)。组织内部的流量可以轻松地通过Internet VPN旅行。

在简单网络中作弊

如果网络非常简单,只有一个内部子网,只有一个路由器,并且所有流量都不是内部子网作为互联网流量,则可以作弊并解决此问题。这可能适用于绝大多数家庭网络以及许多小型企业。

使用防火墙规则

在简单的网络设置中,您可能可以做出一些假设,并通过将流量视为非本地的流量来获得足够的答案:

  • 目标MAC地址是默认网关的MAC地址;和
  • 目标IP地址是 不是 默认网关的IP地址

或者:

  • 目标IP地址不在网络接口的子网中,默认路由输出

您可能可以创建一个防火墙规则来计算其中的任何一个。至少有了Linux Iptables,您可以肯定BSD PF,以及可能的Mac OSX。

替代方法:SNMP

最后,如果您不能使用防火墙规则(如需要根本),您可以希望默认网关对SNMP社区公开响应,探索其所有接口,并找到带有额外提议IP地址的一个界面,然后假设这是互联网链接。然后,您可以向路由器询问该接口的流量计数。

当然,您会发现许多SOHO路由器不支持SNMP,而那些可能没有打开的SOHO路由器。

最好的方法是通过ETH0,ETH1或使用系统调用IFConfig的任何适配器找到“外部” IP地址。然后为任何系统(消息,syslog等)提取日志,并为该外部IP地址编写过滤器。为了使其变得更好,更便携,请编写一条正则是将仅用于公开可路由IP的过滤,并且只需过滤消息登录该“外部” IP地址。

您需要阅读 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

我认为,一个大致的解决方案:GetifAddrs可用于获取有关网络使用的统计信息。

它可以获取Wi-Fi和WWAN接口的单独统计信息。

您可能会从:

http://www.gsp.com/cgi-bin/man.cgi?section=3&topic = getifaddrs

这取决于您如何定义“本地”,但是一个常见的定义是查看网络掩码。

例如,如果您的IP(即,您监视的接口的IP是

10.33.52.123
netmask 255.255.255.0

这意味着每个具有源-IP和destination-ip 10.33.52.xx的IP包都是本地的。

我不知道可可或Objective-C,但是您可能可以使用其中一些功能来帮助您从IP地址提取网络: http://developer.apple.com/library/mac/#documentation/darwin/reference/manpages/man3/inet_network.3.html

不知道如何在Objective-C中实现它,但是您的想法是您获得了您所处网络的地址(您可以从本地IP或从网络类(a,b,c)中弄清楚这一点netmask中的位,如果不是标准),请检查传出连接的地址。如果目的地不在您的本地网络中,请计算流量;如果它进去,那就什么也不做。

有三个不可用的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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top