一、virt_net.c

/** 参考 drivers\net\cs89x0.c*/#include <linux/module.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/ip.h>#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>static struct net_device *vnet_dev;static void emulator_rx_packet(struct sk_buff *skb, struct net_device *dev)
{/* 参考LDD3 */unsigned char *type;struct iphdr *ih;__be32 *saddr, *daddr, tmp;unsigned char    tmp_dev_addr[ETH_ALEN];struct ethhdr *ethhdr;struct sk_buff *rx_skb;// 从硬件读出/保存数据/* 对调"源/目的"的mac地址 */ethhdr = (struct ethhdr *)skb->data;memcpy(tmp_dev_addr, ethhdr->h_dest, ETH_ALEN);memcpy(ethhdr->h_dest, ethhdr->h_source, ETH_ALEN);memcpy(ethhdr->h_source, tmp_dev_addr, ETH_ALEN);/* 对调"源/目的"的ip地址 */    ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));saddr = &ih->saddr;daddr = &ih->daddr;tmp = *saddr;*saddr = *daddr;*daddr = tmp;//((u8 *)saddr)[2] ^= 1; /* change the third octet (class C) *///((u8 *)daddr)[2] ^= 1;type = skb->data + sizeof(struct ethhdr) + sizeof(struct iphdr);//printk("tx package type = %02x\n", *type);// 修改类型, 原来0x8表示ping*type = 0; /* 0表示reply */ih->check = 0;           /* and rebuild the checksum (ip needs it) */ih->check = ip_fast_csum((unsigned char *)ih,ih->ihl);// 构造一个sk_buffrx_skb = dev_alloc_skb(skb->len + 2);skb_reserve(rx_skb, 2); /* align IP on 16B boundary */    memcpy(skb_put(rx_skb, skb->len), skb->data, skb->len);/* Write metadata, and then pass to the receive level */rx_skb->dev = dev;rx_skb->protocol = eth_type_trans(rx_skb, dev);rx_skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */dev->stats.rx_packets++;dev->stats.rx_bytes += skb->len;// 提交sk_buff
    netif_rx(rx_skb);
}static int virt_net_send_packet(struct sk_buff *skb, struct net_device *dev)
{static int cnt = 0;printk("virt_net_send_packet cnt = %d\n", ++cnt);/* 对于真实的网卡, 把skb里的数据通过网卡发送出去 */netif_stop_queue(dev); /* 停止该网卡的队列 *//* ...... */           /* 把skb的数据写入网卡 *//* 构造一个假的sk_buff,上报 */emulator_rx_packet(skb, dev);dev_kfree_skb (skb);   /* 释放skb */netif_wake_queue(dev); /* 数据全部发送出去后,唤醒网卡的队列 *//* 更新统计信息 */dev->stats.tx_packets++;dev->stats.tx_bytes += skb->len;return 0;
}static int virt_net_init(void)
{/* 1. 分配一个net_device结构体 */vnet_dev = alloc_netdev(0, "vnet%d", ether_setup);;  /* alloc_etherdev *//* 2. 设置 */vnet_dev->hard_start_xmit = virt_net_send_packet;/* 设置MAC地址 */vnet_dev->dev_addr[0] = 0x08;vnet_dev->dev_addr[1] = 0x89;vnet_dev->dev_addr[2] = 0x89;vnet_dev->dev_addr[3] = 0x89;vnet_dev->dev_addr[4] = 0x89;vnet_dev->dev_addr[5] = 0x11;/* 设置下面两项才能ping通 */vnet_dev->flags           |= IFF_NOARP;vnet_dev->features        |= NETIF_F_NO_CSUM;    /* 3. 注册 *///register_netdevice(vnet_dev);
    register_netdev(vnet_dev);return 0;
}static void virt_net_exit(void)
{unregister_netdev(vnet_dev);free_netdev(vnet_dev);
}module_init(virt_net_init);
module_exit(virt_net_exit);MODULE_AUTHOR("thisway.diy@163.com,17653039@qq.com");
MODULE_LICENSE("GPL");

二、Makefile

KERN_DIR = /work/system/linux-2.6.22.6all:make -C $(KERN_DIR) M=`pwd` modules clean:make -C $(KERN_DIR) M=`pwd` modules cleanrm -rf modules.orderobj-m    += virt_net.o

转载于:https://www.cnblogs.com/liulipeng/p/3378812.html

网卡驱动程序之编写虚拟网卡(二)相关推荐

  1. linux 3.10 网卡驱动程序示例,网卡驱动程序框架以及虚拟网卡驱动程序的实现

    LINUX驱动程序分三大块:字符驱动程序.块设备驱动程序.网络驱动程序.其中网络驱动程序分为好多层协议层+与硬件相关的层.这篇主要介绍网络驱动中与硬件相关的层的框架:网卡驱动程序. 1.网卡驱动程序框 ...

  2. 虚拟网卡如何安装 电脑虚拟网卡怎么安装详细的说明

    虚拟网卡如何安装 电脑虚拟网卡怎么安装详细的说明 一.在控制面板打开"设备管理" 二.在打开的界面中,找到并选中"网络适配器" 三.点击上面的"操作& ...

  3. 什么叫有效物理网卡_如何区分虚拟网卡和物理网卡?-阿里云开发者社区

    一.什么是物理网卡和虚拟网卡? 图示如下:红色部分包含VMWare的为虚拟网卡. 通常,我们部署VMWare虚拟机.VMSphere虚拟集群.XenCenter虚拟集群是都会涉及虚拟网卡. 二.辨别物 ...

  4. 什么叫有效物理网卡_如何区分虚拟网卡和物理网卡?

    一.什么是物理网卡和虚拟网卡? 图示如下:红色部分包含VMWare的为虚拟网卡. 通常,我们部署VMWare虚拟机.VMSphere虚拟集群.XenCenter虚拟集群是都会涉及虚拟网卡. 二.辨别物 ...

  5. linux虚拟网卡上网,Linux添加虚拟网卡的多种方法

    有时候,一台服务器需要设置多个ip,但又不想添加多块网卡,那就需要设置虚拟网卡.这里介绍几种方式在linux服务器上添加虚拟网卡. 我们向eth0中添加一块虚拟网卡: 第一种方法:快递创建\删除虚拟网 ...

  6. win10安装vbox没有虚拟网卡_消失的虚拟网卡

    之前用的win8.1,现在升级到了win10,win10的ios系统软件是放在电脑上直接双击安装的系统,安装时选择了 保留个人文件,win8.1时装了virtualbox同时也产生了virtualbo ...

  7. linux ping 虚拟网卡_Linux下添加虚拟网卡,实现一块物理网卡绑定多个IP地址

    前言: 这个功能在实际生产环境中可能没有意义,但是在虚拟机里做实验的时候还是蛮实用的,可以直接在一个网卡上模拟出多个网段,这样就不用再添加单独的网卡啦. 配置方法: 以当前网卡的配置文件为模板创建虚拟 ...

  8. Qt获取IP地址、MAC地址等网卡信息,区分本地网卡、无线网卡和虚拟网卡

    1.只有一个本地网卡 此时获取IP地址最简单的方法如下所示,但是这种方法只能获取IP地址.需包含头文件#include <QNetworkInterface>,.pro文件中加入netwo ...

  9. linux虚拟网卡tun,Centos7 创建虚拟网卡(tun/tap)

    创建网卡.创建网桥并建立桥接 [root@kolla ~]# cat create.sh create_br(){ tunctl -t storage -u root brctl addbr virb ...

最新文章

  1. iOS开发:沙盒机制以及利用沙盒存储字符串、数组、字典等数据
  2. 让AI精准识别盗版,脸书开源数据增强库:支持图文音视频,提供100多种增强方式...
  3. 链表用java实现简单单链表linkedlist
  4. 数据优化:求求你别再用offset和limit分页了
  5. 从主机名谈Hadoop集群管理
  6. Python之Eclipse环境下安装与配置
  7. 5.数据中台 --- 数据汇聚联通:打破企业数据孤岛
  8. BigDecimal 加减乘除及对比
  9. Atitit.远程文件技术 webdav ftp scp ssh-sftp http nfs smb 的区别与总结
  10. Windows下利用Python自动切换IP/DNS
  11. 兽药销售终端如何摆脱客情困局
  12. 宁德时代发布第一代钠离子电池;联泰科技与赢创联合研发实验室成立;霍尼韦尔高管人事变动 | 能动...
  13. 名校400门免费人文社科公开课视频合集!
  14. 终于申请自己的博客了
  15. 自定义ListView实现任意View跑马灯效果
  16. 10个重要的算法C语言实现源代码(留着以后看)
  17. 计算机英语哪个教材好,我想买一本英语入门的英语?
  18. 小观插值逼近的龙格现象
  19. 【从0到1搭建LoRa物联网】17、LoRa连接到chirpstack
  20. J-Link在keil软件找不到芯片 与 软件提示dll错误

热门文章

  1. python源码笔记_python源码学习笔记(二)
  2. background 互联网图片_cssbackground-image和layer-background-image的区别
  3. mysql数据库中的int类型_MySQL中int(M)和tinyint(M)数值类型中M值的意义
  4. 使用计算机的女士,3款女性专用PC 将美丽进行到底
  5. 线性单链表存储结构c语言代码,单链表定义-(线性表的链表存储结构)
  6. 虚拟空间独立服务器哪个好,共享虚拟主机和独立哪个好
  7. 【渝粤教育】国家开放大学2018年春季 0579-22T电路及磁路(2)(一) 参考试题
  8. lora近几年发展的具体介绍
  9. emacs c语言,如何利用Emacs来调试C++程序
  10. php生成网页按钮,JavaScript实现自动生成网页元素功能(按钮、文本等)_javascript技巧...