这是一个虚拟网卡实现的初级代码。。其中功能还有待改善。。先贴出来再说
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
MODULE_LICENSE("Dual BSD/GPL");
static LIST_HEAD(zzh_nic_list);
static int zzh_nic_open(struct net_device *dev)
{
printk("zzh_nic_open run\n");
return 1;
}
static int zzh_nic_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
printk("zzh_nic_start_xmit run\n");
kfree_skb(skb);
return 1;
}
static int zzh_nic_close(struct net_device *dev)
{
printk("zzh_nic_close run!\n");
return 1;
}
struct zzh_nic_struct{
struct list_head list;
struct net_device *dev;
};
static const struct net_device_ops zzh_nic_netdev_ops={
.ndo_open = zzh_nic_open,
.ndo_stop = zzh_nic_close,
.ndo_start_xmit = zzh_nic_start_xmit,
};
void zzh_nic_setup(struct net_device *dev)
{
struct zzh_nic_struct *zzh_nic = netdev_priv(dev);
ether_setup(dev);
dev->netdev_ops = &zzh_nic_netdev_ops;
random_ether_addr(dev->dev_addr);
zzh_nic->dev=dev;
list_add(&zzh_nic->list,&zzh_nic_list);
}
struct net_device *zzh_nic_setup_dev(void)
{
struct net_device *dev;
dev = alloc_netdev(sizeof(struct zzh_nic_struct),"zzh_nic%d",zzh_nic_setup);
if (dev == NULL){
printk("alloc net device failed\n");
return NULL;
}
if (register_netdev(dev) != 0){
printk("register net device failed\n");
return NULL;
}
return dev;
}
int zzh_nic_shutdown_dev(void){
struct zzh_nic_struct *zzh_nic;
struct zzh_nic_struct *next;
list_for_each_entry_safe(zzh_nic,next,&zzh_nic_list,list){
list_del(&zzh_nic->list);
unregister_netdev(zzh_nic->dev);
free_netdev(zzh_nic->dev);
}
return 0;
}
static int zzh_nic_init(void)
{
struct net_device *dev;
printk("zzh_nic_init run\n");
if ((dev = zzh_nic_setup_dev()) == NULL){
printk("setup net device failed\n");
return -1;
}
return 0;
}
static void zzh_nic_exit(void)
{
printk("zzh_nic_exit run\n");
if (zzh_nic_shutdown_dev() == -1)
printk("shutdown net device failed\n");
}
module_init(zzh_nic_init);
module_exit(zzh_nic_exit);
Makefile内容:
ifneq ($(KERNELRELEASE),)
obj-m :=zzh_nic.o
else
PWD :=$(shell pwd)
KDIR :=/lib/modules/$(shell uname -r)/build
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
endif
/*
KERNELRELEASE
是在内核源码的顶层Makefile中定义的一个变量,在第一次读取执行此Makefile时,KERNELRELEASE没有被定义,
所以make将读取执行else之后的内容。如果make的目标是clean,直接执行clean操作,然后结束。当make的目标为all时,-C
$(KDIR) 指明跳转到内核源码目录下读取那里的Makefile;M=$(PWD)
表明然后返回到当前目录继续读入、执行当前的Makefile。当从内核源码目录返回时,KERNELRELEASE已被被定义,kbuild也被启动去
解析kbuild语法的语句,make将继续读取else之前的内容。else之前的内容为kbuild语法的语句,
指明模块源码中各文件的依赖关系,以及要生成的目标模块名。。obj-m :=
zzh_nic.o表示编译连接后将生成mytest.o模块。
*/
编译完后;
insmod zzh_nic.ko
可以查看是否加入:
cat /proc/net/dev
可以看到咱们的网卡已经加入
sudo ifconfig zzh_nic0 192.168.4.1 netmask 255.255.255.0 up
然后
ifconfig zzh_nic0
可以看到相关信息