【问题标题】:Is it possible to count number of ICMP packets sent/received per interface in Linux?是否可以计算 Linux 中每个接口发送/接收的 ICMP 数据包数量?
【发布时间】:2013-12-26 13:31:12
【问题描述】:

是否可以在 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 统计信息?

【问题讨论】:

    标签: linux interface statistics icmp packets


    【解决方案1】:

    当它增加计数器时查看实现本身,似乎 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++;
            ...
            }
    ...
    }
    

    等等。所以似乎所有接口的统计数据都是通用的,从不提及具体的接口。

    【讨论】:

      【解决方案2】:

      我认为内核不会为每个接口的每个协议保留计数器。查看提供/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;
      };
      

      如果我猜对了,这就是每个链接(或在这种情况下语义上相同的每个接口)统计信息的结构,并且似乎没有特定于协议的计数器。

      【讨论】:

      • 感谢您的回答,事实上我还仔细检查了实现本身(更新了我的问题),看来您的回答完全正确。
      • 其实你指出的统计信息可以在 /sys/class/net//statistics 中检索到。
      猜你喜欢
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 2012-12-14
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      • 2013-07-18
      • 2011-08-09
      相关资源
      最近更新 更多