是否可以计算Linux中每个接口发送/接收的ICMP数据包的数量?

时间:2013-12-09 12:25:20

标签: linux interface statistics icmp packets

是否可以检查Linux每个接口的统计信息,特别是ICMP数据包? ifconfig 命令它为接收和发送的数据包提供每个接口的统计信息:

-> /sbin/ifconfig eth1
eth1      Link encap:Ethernet  HWaddr BC:30:5B:ED:DE:54  
          UP BROADCAST RUNNING SLAVE MULTICAST  MTU:1500  Metric:1
          RX packets:412327300 errors:0 dropped:0 overruns:0 frame:0
          TX packets:765211747 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:327931865613 (312740.1 Mb)  TX bytes:803392590272 (766174.8 Mb)
          Memory:dcc00000-dcd00000 

但我正在寻找的是每个接口的一些特定类型的数据包(如ICMP)。

Linux也在提供这些统计数据,但在全球范围内 / proc / net / snmp

-> cat /proc/net/snmp
... log truncated ...
Icmp: InMsgs InErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps
Icmp: 29697 5 276 9 0 0 0 29409 3 0 0 0 0 29970 0 561 0 0 0 0 5 29404 0 0 0 0
IcmpMsg: InType0 InType3 InType8 InType11 OutType0 OutType3 OutType8
IcmpMsg: 3 276 29409 9 29404 561 5
... log truncated ...

使用 netstat -s 命令打印更漂亮(-s代表统计信息):

-> netstat -s
... log truncated ...
Icmp:
    29697 ICMP messages received
    5 input ICMP message failed.
    ICMP input histogram:
        destination unreachable: 276
        timeout in transit: 9
        echo requests: 29409
        echo replies: 3
    29970 ICMP messages sent
    0 ICMP messages failed
    ICMP output histogram:
        destination unreachable: 561
        echo request: 5
        echo replies: 29404
IcmpMsg:
        InType0: 3
        InType3: 276
        InType8: 29409
        InType11: 9
        OutType0: 29404
        OutType3: 561
        OutType8: 5
... log truncated ...

所以,问题是。有没有办法获取某些特定接口的ICMP统计信息,而不是Linux中整个系统的全局ICMP统计信息?

2 个答案:

答案 0 :(得分:3)

我认为内核不会为每个接口保留每个协议的计数器。看一下提供/proc/net/netstat(以及其他内容)的代码,我们可以找到rtnl_link_stats64中定义的include/uapi/linux/if_link.h的大量引用:

/* The main device statistics structure */
struct rtnl_link_stats64 {
        __u64   rx_packets;             /* total packets received       */
        __u64   tx_packets;             /* total packets transmitted    */
        __u64   rx_bytes;               /* total bytes received         */
        __u64   tx_bytes;               /* total bytes transmitted      */
        __u64   rx_errors;              /* bad packets received         */
        __u64   tx_errors;              /* packet transmit problems     */
        __u64   rx_dropped;             /* no space in linux buffers    */
        __u64   tx_dropped;             /* no space available in linux  */
        __u64   multicast;              /* multicast packets received   */
        __u64   collisions;

        /* detailed rx_errors: */
        __u64   rx_length_errors;
        __u64   rx_over_errors;         /* receiver ring buff overflow  */
        __u64   rx_crc_errors;          /* recved pkt with crc error    */
        __u64   rx_frame_errors;        /* recv'd frame alignment error */
        __u64   rx_fifo_errors;         /* recv'r fifo overrun          */
        __u64   rx_missed_errors;       /* receiver missed packet       */

        /* detailed tx_errors */
        __u64   tx_aborted_errors;
        __u64   tx_carrier_errors;
        __u64   tx_fifo_errors;
        __u64   tx_heartbeat_errors;
        __u64   tx_window_errors;

        /* for cslip etc */
        __u64   rx_compressed;
        __u64   tx_compressed;
};

如果我做对了,这就是这样的结构,即每个链接(或者每个接口在本文中在语义上是相同的东西)统计数据被保留,并且似乎没有特定于协议的计数器。

答案 1 :(得分:0)

当它增加计数器时查看实现本身,并且看起来Linux并没有像你提到的那样为特定协议的每个接口提供这些统计数据:

struct icmp_mib icmp_statistics;

...

static void icmp_out_count(int type)

{

        if(type>18)

               return;

        (*icmp_pointers[type].output)++;

        icmp_statistics.IcmpOutMsgs++;

}

...

int icmp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,

         __u32 daddr, unsigned short len,

         __u32 saddr, int redo, struct inet_protocol *protocol)

{
...
icmp_statistics.IcmpInMsgs++;
        if(len < sizeof(struct icmphdr))

        {

               icmp_statistics.IcmpInErrors++;
        ...
        }
...
}

等等。因此,似乎所有接口的一般统计数据,从未提及特定接口。