- 论坛徽章:
- 0
|
本帖最后由 llhao86 于 2011-11-18 09:27 编辑
我写了一个简单的虚拟设备驱动,想用来接收IP包,在代码中我只实现了dev这个结构体,并把它注册到系统上去,之后用路由命令让IP层把包发送到该设备上,看看系统是否调用了sim_dri_start_xmit()这个接收函数.
在编译完该程序,我把该模块加载到系统上,而且在/proc/net/dev中也能查看到该设备,说明设备应该正确注册到系统了.
接着我用
sudo ifconfig sim_dri0 192.168.4.1 netmask 255.255.255.0 up
配置该设备的IP并激活它,在系统消息中可以看到系统调用了sim_dri_open()这个函数.
但当我
ping 192.168.4.1
时,虽然可以ping得通,但系统并没调用sim_dri_start_xmit()这个接收函数.
而且,当我想指定一条路由到该设备时
sudo route add 192.168.155.155 dev sim_dri0
它总是提示"SIOCADDRT: Network is down"
我想请教下,我在代码里的做法是不是有问题,在做这个dev结构的时候是不是还有些东西没考虑呀,导致系统一直没调用我写的接收函数,谢谢!
环境:VMware+内核版本2.6.32.46- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/netdevice.h>
- #include <linux/etherdevice.h>
- #include <linux/ethtool.h>
- MODULE_LICENSE("Dual BSD/GPL");
- static int sim_dri_open (struct net_device *dev);
- static int sim_dri_start_xmit (struct sk_buff *skb, struct net_device *dev);
- static int sim_dri_close (struct net_device *dev);
- static LIST_HEAD(sim_dri_list);
- static int sim_dri_open (struct net_device *dev)
- {
- printk(KERN_ALERT "sim_dri_open run\n");
- return 1;
- }
- static int sim_dri_start_xmit (struct sk_buff *skb, struct net_device *dev)
- {
- printk(KERN_ALERT "sim_dri_start_xmit run\n");
- kfree_skb(skb);
- return 1;
- }
- static int sim_dri_close (struct net_device *dev)
- {
- printk(KERN_ALERT "sim_dri_close run\n");
- return 1;
- }
- //设备私有数据
- struct sim_dri_struct{
- struct list_head list; //设备链表
- struct net_device *dev; //net_device
- };
- //设备操作函数
- static const struct net_device_ops sim_dri_netdev_ops = {
- .ndo_open = sim_dri_open,
- .ndo_stop = sim_dri_close,
- .ndo_start_xmit = sim_dri_start_xmit,
- };
- //设置设备
- void sim_dri_setup(struct net_device *dev){
- struct sim_dri_struct *sim_dri = netdev_priv(dev); //获取net_device私有数据
- ether_setup(dev); //设置设备为以太网设备,定义部分以太网络的参数
- /*
- 以下为设置网络设备的操作函数
- */
- dev->netdev_ops = &sim_dri_netdev_ops;
-
- random_ether_addr(dev->dev_addr); //随机源地址
- sim_dri->dev = dev; //设置私有数据的net_device成员
- list_add(&sim_dri->list, &sim_dri_list); //将新建sim_dri_struct加入到设备链表
- }
- //申请,设置,注册设备
- struct net_device *sim_dri_setup_dev(void){
- struct net_device *dev;
- //分配net_device,并调用初始化函数sim_dri_setup()
- dev = alloc_netdev(sizeof(struct sim_dri_struct), "sim_dri%d", sim_dri_setup);
- if(dev == NULL){
- printk(KERN_ALERT "alloc net device failed\n");
- return NULL;
- }
- if(register_netdev(dev) != 0){ //注册网络设备
- printk(KERN_ALERT "register net device failed\n");
- return NULL;
- }
- return dev;
- }
- //卸载设备
- int sim_dri_shutdown_dev(void){
- struct sim_dri_struct *sim_dri;
- struct sim_dri_struct *next;
- list_for_each_entry_safe(sim_dri, next, &sim_dri_list, list){ //遍历所有sim_dri_struct
- list_del(&sim_dri->list); //将当前sim_dri_struct从队列中删除
- unregister_netdev(sim_dri->dev); //注销网络设备
- free_netdev(sim_dri->dev); //释放网络设备
- }
- return 0;
- }
- static int sim_driver_init(void)
- {
- printk(KERN_ALERT "sim_driver_init run\n");
- struct net_device *dev;
- if((dev = sim_dri_setup_dev()) == NULL){
- printk(KERN_ALERT "setup net device failed\n");
- return -1;
- }
- return 0;
- }
- static void sim_driver_exit(void)
- {
- printk(KERN_ALERT"sim_driver_exit run\n");
- if(sim_dri_shutdown_dev() == -1){
- printk(KERN_ALERT "shutdown net device failed\n");
- }
- }
- module_init(sim_driver_init);
- module_exit(sim_driver_exit);
复制代码 |
|