Chinaunix首页 | 论坛 | 博客
  • 博客访问: 289064
  • 博文数量: 67
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 802
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-14 16:23
文章分类
文章存档

2011年(4)

2010年(18)

2009年(32)

2008年(13)

我的朋友

分类: LINUX

2008-11-20 19:41:45

前面讲到,register_netdev首先为网络设备接口分配一个名称,然后将dev插入到一个叫做dev_base的网络设备全局链表中。由此我们 不难想到,通过访问dev_base,就可以遍历到系统中的所有网络设备,而每一个网络设备接口都有一个net_device结构来表示。该结构中有一个 成员函数指针:
    struct net_device_stats* (*get_stats)(struct net_device *dev);
它返回一个struct net_device_stats结构,该结构保存了所在网络设备接口的详细的流量统计信息:

struct net_device_stats
    {
        unsigned long rx_packets; /* total packets received */
        unsigned long tx_packets; /* total packets transmitted */
        unsigned long rx_bytes; /* total bytes received */
        unsigned long tx_bytes; /* total bytes transmitted */
        unsigned long rx_errors; /* bad packets received */
        unsigned long tx_errors; /* packet transmit problems */
        unsigned long rx_dropped; /* no space in linux buffers */
        unsigned long tx_dropped;/* no space available in linux */
        unsigned long multicast; /* multicast packets received */
        unsigned long collisions;

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

    /* detailed tx_errors */
    unsigned long tx_aborted_errors;
    unsigned long tx_carrier_errors;
    unsigned long tx_fifo_errors;
    unsigned long tx_heartbeat_errors;
    unsigned long tx_window_errors;

    /* for cslip etc */
    unsigned long rx_compressed;
    unsigned long tx_compressed;
};

   OK,有了这些基础知识,我们就可以写一个网络流量统计的内核模块了,这是一个最简单的程序,它每次被插入到内核中时,会在日志文件中打出当前系统上的所 有网络设备接口的传输的和收到的字节数和包数。我们可以把它进一步改造,输出到/proc文件系统,再通过用户空间的一个程序计算单位时间的流量,就成为 一个真正的网络流量统计程序了。下面是代码:

/* netbase.c
 * helinqiang@hotmail.com
 * 2006-03-14
 */


#include <linux/init.h>
#include <linux/netdevice.h>

MODULE_AUTHOR("Linqiang He, Hangzhou China");
MODULE_LICENSE("Dual BSD/GPL");

static int __init netbase_init_module(void)
{
    struct net_device *dev = dev_base;
    struct net_device_stats *stats;
    while( dev != NULL ){
        printk(KERN_INFO "dev name: %s\n", dev->name);
        stats = dev->get_stats(dev);
        printk(KERN_INFO "\ttransmitted bytes: %lu\n", stats->tx_bytes);
        printk(KERN_INFO "\treceived bytes: %lu\n", stats->rx_bytes);
        printk(KERN_INFO "\ttransmitted packets: %lu\n", stats->tx_packets);
        printk(KERN_INFO "\treceived packets: %lu\n", stats->rx_packets);
        dev = dev->next;
    }
    return 0;
}

static void __exit netbase_exit_module(void)
{
}

module_init(netbase_init_module);
module_exit(netbase_exit_module);

下面是在我的电脑上的某一时刻的输出结果:
Mar 14 21:22:34 localhost kernel: dev name: lo
Mar 14 21:22:34 localhost kernel:       transmitted bytes: 4660
Mar 14 21:22:34 localhost kernel:       received bytes: 4660
Mar 14 21:22:34 localhost kernel:       transmitted packets: 61
Mar 14 21:22:34 localhost kernel:       received packets: 61
Mar 14 21:22:34 localhost kernel: dev name: sit0
Mar 14 21:22:34 localhost kernel:       transmitted bytes: 0
Mar 14 21:22:34 localhost kernel:       received bytes: 0
Mar 14 21:22:34 localhost kernel:       transmitted packets: 0
Mar 14 21:22:34 localhost kernel:       received packets: 0
Mar 14 21:22:34 localhost kernel: dev name: eth0
Mar 14 21:22:34 localhost kernel:       transmitted bytes: 437071
Mar 14 21:22:34 localhost kernel:       received bytes: 4046403
Mar 14 21:22:34 localhost kernel:       transmitted packets: 2607
Mar 14 21:22:34 localhost kernel:       received packets: 17773
阅读(3218) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2008-11-23 12:55:19

Linux技术沙龙群:72364642 专门提供Linux & Unix技术交流,欢迎加入! 您想拥有尊贵的华彩人生吗? 想让您的爱人和女友得到一份惊喜吗? 【施华洛世奇水晶】 http://shop36349441.taobao.com