新闻资讯
Group news
青岛广盛源肥业有限公司    您的位置: 首页  >  新闻资讯  >  正文

你了解Linux网络驱动之一:snull

2019年10月12日 文章来源:网络整理 热度:158℃ 作者:刘英

      snull是《Linux Device Drivers》中的一个网络驱动的例子。这里引用这个例子学习Linux网络驱动

因为snull的源码,网上已经更新到适合最新内核,而我自己用的还是2.6.22.6比较旧的内核。而网上好像找不到旧版的snull。因此结合《Linux Device Drivers》把最新的snull例子移植到2.6.22.6内核中。移植也相对简单,这里也提供移植好的代码。

估计不少网友看到《Linux Device Drivers》的网络驱动部分,一脸懵逼,包括我自己,不理解作者设计这个例子的真正目的,尽管有配图,仍然懵懂,甚至不知道为什么会用到6个IP地址。如图:

你了解Linux网络驱动之一:snull

其实作者的本意是想通过虚拟网卡来模拟实际的网卡和外部的网络设备的通信来讨论网络驱动。通过其中任何一个网络接口(sn0或sn1)发送数据,都在另一个网络接口(sn0或sn1)接收到。

因为sn0和sn1都不在同一个网段,所以sn0和sn1之间直接互ping是不行的,这中间必须必须做点转换。

例子:

理论上local0和remote0只能互ping,因为他们都在同一个网段:192.168.0.0,但事实上,local0在发出数据之后,local0的第3个字节最低有效位改取反,就变成了remote1,remote1的数据才能到达local1,因为他们在同一段IP。相反,local1在发出数据之后,local1的第3个字节最低有效位改取反,就变成了remote0,remote0的数据才能到达local0.

因此,在实验之前,需要添加一些配置:

在/etc/networks文件中添加如下网段IP:

snullnet0 192.168.2.0

snullnet1 192.168.3.0

在/etc/hosts文件中添加如下IP地址

192.168.2.8 local0

192.168.2.9 remote0

192.168.3.9 local1

192.168.3.8 remote1

注意: 1. 网段IP和IP地址的第三个字节的最低有效位是相反的

2. local0和remote1第四个字节必须一样,remote0和local1第四个字节必须一样

3. 如果开发板上的真正网卡用了的网段IP,就不能再用于本实验。如:我的开发板的DM9000网卡使用网段是192.168.1.0, 因此本实验不能再使用192.168.1.0作为网段,否则有冲突。

代码: snull.c, 其中snull.h没改动,因此不贴出来

/*
 * snull.c --  the Simple Network Utility
 *
 * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
 * Copyright (C) 2001 O'Reilly & Associates
 *
 * The source code in this file can be freely used, adapted,
 * and redistributed in source or binary form, so long as an
 * acknowledgment appears in derived source files.  The citaTIon
 * should list that the code comes from the book "Linux Device
 * Drivers" by Alessandro Rubini and Jonathan Corbet, published
 * by O'Reilly & Associates.  No warranty is attached;
 * we cannot take responsibility for errors or fitness for use.
 *
 * $Id: snull.c,v 1.21 2004/11/05 02:36:03 rubini Exp $
 */

#include
#include
#include

#include
#include /* printk() */
#include /* kmalloc() */
#include   /* error codes */
#include   /* size_t */
#include /* mark_bh */

#include
#include   /* struct device, and other headers */
#include /* eth_type_trans */
#include           /* struct iphdr */
#include         /* struct tcphdr */
#include

#include "snull.h"

#include
#include

MODULE_AUTHOR("Alessandro Rubini, Jonathan Corbet");
MODULE_LICENSE("Dual BSD/GPL");


/*
 * Transmitter lockup simulaTIon, normally disabled.
 */
staTIc int lockup = 0;
module_param(lockup, int, 0);

staTIc int timeout = SNULL_TIMEOUT;
module_param(timeout, int, 0);

/*
 * Do we run in NAPI mode?
 */
static int use_napi = 0;
module_param(use_napi, int, 0);


/*
 * A structure representing an in-flight packet.
 */
struct snull_packet {
    struct snull_packet *next;
    struct net_device *dev;
    int    datalen;
    u8 data[ETH_DATA_LEN];
};

int pool_size = 8;
module_param(pool_size, int, 0);

/*
 * This structure is private to each device. It is used to pass
 * packets in and out, so there is place for a packet
 */

struct snull_priv {
    struct net_device_stats stats;
    int status;
    struct snull_packet *ppool;
    struct snull_packet *rx_queue;  /* List of incoming packets */
    int rx_int_enabled;
    int tx_packetlen;
    u8 *tx_packetdata;
    struct sk_buff *skb;
    spinlock_t lock;
    struct net_device *dev;
    //struct napi_struct napi;
};

static void snull_tx_timeout(struct net_device *dev);
static void (*snull_interrupt)(int, void *, struct pt_regs *);

上一篇:一个Linux上分析死锁的简单方法


下一篇:作为Linux内核关键的调试技术,可以修改内核定时器来定位系统僵死问题

友情链接
Links