- 论坛徽章:
- 0
|
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/device.h>
- #include <linux/string.h>
- #include <linux/slab.h>
- #include <linux/module.h>
- #include <linux/netdevice.h>
- #include <linux/kernel.h>
- #include <linux/etherdevice.h>
- struct net_device *virtualNIC;
- int virtualNIC_open(struct net_device *dev) {
- printk("virtualNIC_open called\n");
- return 0;
- }
- int virtualNIC_release(struct net_device *dev) {
- printk("virtualNIC_release called\n");
- netif_stop_queue(dev);
- return 0;
- }
- int virtualNIC_xmit(struct sk_buff *skb, struct net_device *dev) {
- printk("dummy xmit function called...\n");
- dev_kfree_skb(skb);
- return 0;
- }
- int virtualNIC_init(struct net_device *dev) {
- printk("virtualNIC device initialized\n");
- return 0;
- };
- const struct net_device_ops my_netdev_ops = {
- .ndo_init = virtualNIC_init,
- .ndo_open = virtualNIC_open,
- .ndo_stop = virtualNIC_release,
- .ndo_start_xmit = virtualNIC_xmit,
- };
- //static void ether_setup(struct net_device *dev){
- // dev->netdev_ops = &my_netdev_ops;
- //}
- int virtualNIC_init_module(void) {
- int result;
- char mac[6] = {0x12,0x34,0x56,0x78,0x90,0xab};
- virtualNIC = alloc_etherdev(0);
- if(!virtualNIC){
- return -1;
- }
- virtualNIC->netdev_ops = &my_netdev_ops;
-
- memcpy(virtualNIC->dev_addr, mac, virtualNIC->addr_len);
- if((result = register_netdev(virtualNIC))) {
- printk("virtualNIC: Error %d initalizing card ...", result);
- return result;
- }
- return 0;
- }
- static ssize_t vnet_recv(struct class *cls, struct class_attribute *attr, const char *_buf, size_t _count)
- {
- struct sk_buff *skb = dev_alloc_skb(_count+2);
- if(!skb){
- printk("Out of mem!\n");
- goto out;
- }
- skb_reserve(skb, 2);
- memcpy(skb_put(skb, _count), _buf, _count);
- skb->dev = virtualNIC;
- skb->protocol = eth_type_trans(skb, virtualNIC);
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- //skb->pkt_type = PACKET_HOST;
-
- printk("%d %d %d\n",skb->pkt_type, ntohs(skb->protocol), netif_rx_ni(skb));
- out:
- return _count;
- }
- static struct class *vnet_class = NULL;
- static CLASS_ATTR(recv, 0220, NULL, vnet_recv);
- int __init vnet_init (void)
- {
- virtualNIC_init_module();
- vnet_class = class_create(THIS_MODULE, "vnet");
- if (IS_ERR(vnet_class))
- {
- printk("Create class vnet_class failed.\n");
- return -ENOMEM;
- }
- class_create_file(vnet_class, &class_attr_recv);
- return 0;
- }
- void __exit
- vnet_exit (void)
- {
- class_remove_file(vnet_class, &class_attr_recv);
- class_destroy(vnet_class);
- unregister_netdev(virtualNIC);
- free_netdev(virtualNIC);
- vnet_class = NULL;
- }
- module_init (vnet_init);
- module_exit (vnet_exit);
- MODULE_AUTHOR("None");
- MODULE_LICENSE ("GPL");
复制代码
我注册了个netdev, 以及sys一个入口文件,应用层负责构建完整的以太网帧写到入口文件,然后模块把这个以太网帧传给内核。wireshark抓包看包很正常,各项参数都对,目的mac是我的虚拟接口的,ip checksum,udp checksum都对,但是应用层的udp socket收不到。netif_rx返回0. 求大佬指教哪里有问题。
|
|