10

我正在开发一个监控网络使用情况的应用程序。但是我注意到很多方法都不允许排除本地流量(例如,Time Machine)。

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

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

如何在 linux/Mac OSX 中获取网络适配器统计信息?给出了一种总结总使用量的有趣方式,但它没有帮助,因为它总结的使用量是接口统计信息。

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

4

8 回答 8

2

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

于 2011-02-25T16:37:46.023 回答
2

回答您有关哪些接口承载本地流量的评论实际上很复杂,因为这取决于您所说的本地流量的含义。

“本地”是什么意思

“本地流量”最简单的含义是不会离开机器产生的流量(例如,同一台机器上的两个程序相互通信)。这交通都过去了。这是人们说本地时的意思(以及我回答时的想法)。

下一个最简单的含义是“发往同一子网上的机器的 IP 流量”。那将是在本地子网内具有目标地址的流量。计算这一点的最简单方法是路由表(如果 Mac OS X 计算每个路由的流量统计信息,则各个网关上的路由将为您提供非本地流量)或使用防火墙规则。当他们说“本地交通”时,这可能不是任何人的意思。

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

另一个含义是“发往我组织中机器的 IP 流量”。这是一个合理的含义,具体取决于您的网络设置方式(例如,您的位置之间可能有快速光纤,但您的 Internet 连接速度要慢得多,或者按 GB 收费)。需要对网络有深入的了解才能确定目的地是否是本地的——而且,对于 VPN 之类的东西,这可能会随着时间而变化。

最后,“互联网流量”与任何这些都不相反。有时,例如,您的以太网网段上看似本地的机器实际上是通过 VPN,通过 Internet(这并不疯狂,当远程用户需要使用各种 Windows 服务时,它非常有用)。组织内部的流量可以轻松地通过 Internet VPN 传输。

在简单网络中作弊

如果网络很简单,只有一个内部子网,只有一个路由器,所有不到该内部子网的流量都是互联网流量,你可以作弊解决这个问题。这可能适用于绝大多数家庭网络,也适用于许多小型企业网络。

使用防火墙规则

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

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

或者:

  • 目标 IP 地址不在网络接口的子网内 默认路由出去

您可能可以创建一个防火墙规则来计算其中任何一个。至少可以使用 Linux iptables,而且我很确定 BSD pf,可能还有 Mac OS X。

替代方法:SNMP

最后,如果您不能使用防火墙规则(因为这需要 root),您可以希望默认网关响应 SNMP 社区公共,探索其所有接口,并找到一个具有子网外 IP 地址的接口,然后假设这是 Internet 链接。然后,您可以向路由器询问该接口上的流量计数。

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

于 2011-04-01T18:05:04.553 回答
1

最好的方法是通过 eth0、eth1 或任何对 ifconfig 进行系统调用的适配器来查找“外部”IP 地址。然后为任何系统(消息、系统日志等)提取日志,并为该外部 IP 地址编写一个过滤器。为了使它更好和更便携,编写一个正则表达式,它将仅过滤可公开路由的 IP,并仅过滤该“外部”IP 地址的消息日志。

于 2011-02-25T12:51:08.920 回答
0

我认为,一个近似的解决方案: getifaddrs 可用于获取网络使用情况的统计信息。

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

您可能会从以下位置找到更多信息:

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

于 2011-02-19T19:24:36.220 回答
0

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

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

10.33.52.123
netmask 255.255.255.0

这意味着每个具有源 IP 和目标 IP 10.33.52.xx 的 IP 数据包都是本地的。

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

于 2011-02-25T07:32:03.427 回答
0

不知道如何在objective-c中实现它,但想法是你得到你所在网络的地址(你可以从基于本地ip的网络类(A,B,C)或从如果它不是标准的网络掩码中的位),那么只需检查传出连接的地址。如果目的地不在您的本地网络中,请计算流量;如果它在,什么也不做。

于 2011-02-25T15:03:31.043 回答
0

不可路由的IP地址范围有3种,常用作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

于 2011-03-04T22:01:01.067 回答
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 配置等,但我希望看到有关此的建议。

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

于 2011-11-03T23:32:27.577 回答