Objective c 监视网络使用情况(不包括本地流量)

Objective c 监视网络使用情况(不包括本地流量),objective-c,cocoa,networking,monitoring,sysctl,Objective C,Cocoa,Networking,Monitoring,Sysctl,我正在开发一个监控网络使用情况的应用程序。然而,我注意到很多方法都不允许排除本地流量(比如时间机器) 我正在寻找一种排除本地流量的方法,并且只监视直接进入/来自internet的使用情况 更新:感谢您的回复,现在我知道如何查找流量是否为本地流量,但我仍然不知道如何计算总的输入/输出字节数(如果我之前没有详细说明,请原谅)。我无法知道在一段时间内,或者操作系统启动后,本地(或互联网)发送/接收了多少字节。当操作系统运行时,进程被启动或终止,这使得这个问题更加复杂 这个问题的答案提供了一种总结总使用

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

我正在寻找一种排除本地流量的方法,并且只监视直接进入/来自internet的使用情况

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

这个问题的答案提供了一种总结总使用量的有趣方法,但它没有帮助,因为它总结的使用量是接口统计数据


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

我认为,一个近似的解决方案是:可以使用GetIFADRS获取网络使用情况的统计数据

它可以获得Wi-Fi和WWAN接口的单独统计数据

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


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

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

10.33.52.123
netmask 255.255.255.0
这意味着源IP和目标IP均为10.33.52.xx的每个IP数据包都是本地的


我不知道cocoa或objective-c,但您可能可以使用其中一些函数来帮助您从IP地址提取网络:

最好的方法是通过eth0、eth1或任何适配器找到“外部”IP地址,并对ifconfig进行系统调用。然后提取任何系统的日志(消息、系统日志等)并为该外部ip地址编写一个筛选器。为了使其更好、更可移植,请编写一个正则表达式,该正则表达式将只筛选可公开路由的ip,而只筛选该“外部”ip地址的消息日志。

不知道如何在objective-c中实现它,但其目的是获取所处网络的地址(您可以从基于本地ip的网络类(A、B、C)或netmask中的位(如果不是标准的)中找出这一点),然后只需检查传出连接的地址。如果目标不在本地网络中,则计算流量;如果在,则什么也不做。

您需要读取ifconfig(8)的源代码,它描述了如何获取每个连接的网络接口的状态

请特别注意in_status(),它获取接口的inet地址和网络掩码

当通信流中的源地址或目标地址与本地接口具有相同的主机时

int是本地的=

(src&&netmask)==(ifaddr&&netmask)

||(dst和网络掩码)==(ifaddr和网络掩码)

然后你可以确定它是本地的


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

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

“本地”是什么意思 “本地通信”最简单的含义是不让机器继续运行其生成的通信(例如,同一台机器上的两个程序相互通信)。这种通信都是通过lo进行的。这是人们说本地时的意思之一(也是我回答时的想法)

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

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

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

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

简单网络中的欺骗 如果网络非常简单,只有一个内部子网,只有一个路由器,并且所有不到该内部子网的流量都是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;
}