网卡驱动"/>
最简网卡驱动
在内核注册自定义的网卡驱动,并通过打印用户空间和内核的交互数据,可以更深层次的理解网络协议。
驱动代码:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/string.h>
#include <linux/etherdevice.h>
#include <linux/mm_types.h>
#include <linux/slab.h>struct net_device *mydev;static int test_start_xmit(struct sk_buff *skb, struct net_device *dev) {print_hex_dump(KERN_NOTICE,"",0,16,1,(void*)skb->data,skb->len,false);kfree_skb(skb);return NETDEV_TX_OK;
}
static int start(struct net_device *dev) {return 0;
}static int stop (struct net_device *dev) {return 0;
}
static void stats(struct net_device *dev, struct rtnl_link_stats64 *storage) {printk(KERN_ALERT "get stats\n");u64 packets, bytes;dev_lstats_read(dev, &packets, &bytes);storage->rx_packets = packets;storage->tx_packets = packets;storage->rx_bytes = bytes;storage->tx_bytes = bytes;
}
static struct net_device_ops net_dev_ops = {.ndo_start_xmit = test_start_xmit,.ndo_open = start,.ndo_stop = stop,.ndo_get_stats64 = stats,
};
void add_myself_netdev(void) {int ret;mydev = alloc_netdev(0, "pan%d", NET_NAME_UNKNOWN, ether_setup);if (!mydev) {goto out;}mydev->netdev_ops = &net_dev_ops;ret = register_netdev(mydev);if (ret) {printk(KERN_ALERT "register failed\n");free_netdev(mydev);}
out:printk(KERN_ALERT "add myself net dev failed\n");
}
EXPORT_SYMBOL(add_myself_netdev);static int hello_init(void) {printk(KERN_ALERT "init fishing\n");add_myself_netdev();//dump_stack();return 0;
}static void hello_exit(void) {unregister_netdev(mydev);free_netdev(mydev);printk(KERN_ALERT "exit fishing\n");
}
//subsys_initcall(hello_init);
module_init(hello_init);
module_exit(hello_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("shakespeare");
Makefile文件:
ifneq ($(KERNELRELEASE),)
$(info "2nd")obj-m := fishing.oelse
#kdir := /lib/modules/$(shell uname -r)/build
kdir := /usr/src/linux-headers-$(shell uname -r)
pwd := $(shell pwd)all:$(info "1st")make -C $(kdir) M=$(pwd) modulesclean:rm *.ko *.o *.order *.mod.c *.symvers *.mod
endif
安装系统头文件,即可进行编译,然后加载到内核
其中,需要配置ip地址
sudo ip link set pan0 up
sudo ip addr add 192.168.90.1/24 dev pan0
使用该网卡发送数据包
nc -u 192.168.90.12 8080
使用tcpdump抓包
sudo tcpdum -i pan0 -nneX
因为192.168.90.12地址的mac不在arp缓存,所以内核会发送arp广播请求。
通过对比内核打印的skb->data内容和tcpdump抓取的报文可知,skb->data的前12个字节是mac地址,接着的0806是arp协议。
更多推荐
最简网卡驱动
发布评论