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

1、网卡驱动程序框,直接上图:

从图中可以知道,首先应用层通过socket编程调用若干的网络协议层,而这网络协议层完成时纯软件的概念,是通过软件分层的。软件层与相关的网卡驱动程序的接口都是通过hard_start_xmit发包函数与netif_rx 收包函数函数联系起来的。而他们传送的数据包的结构是sk_buff结构体。

对于网卡相关的驱动程序,可以直接参考drivers\net\cs89x0.c文件。它的大致的使用过程如下:

首先入口函数init_module分配了一个net_device结构体。然后调用cs89x0_probe1函数,在这个函数中设置了hard_start_xmit发包函数等信息,最后调用register_netdev注册分配的net_device结构体。

接着看到net_interrupt函数,这是一个中断入口函数,它最终调用了netif_rx函数用于接收从网卡芯片中传输过来的数据,上报给网路协议层。

init_module

alloc_etherdev

cs89x0_probe1

dev->hard_start_xmit =net_send_packet;

register_netdev

net_interrupt

net_rx

netif_rx

从以上分析,可以大胆的推测出网卡驱动程序的编写步骤:

1、分配一个net_device结构体

2、设置

a、提供发包函数:hard_start_xmit

(*hard_start_xmit) (struct sk_buff *skb,struct net_device *dev);

b、提供收包的功能:收到数据时在中断处理函数里用netif_rx上报数据

c、其他设置

3、注册:register_netdev

4、硬件相关

2、虚拟网卡驱动程序的编写以及测试

直接贴上代码,此驱动程序的功能可以ping通在同一网段内的不同IP的虚拟设备。

1、首先分析下入口函数Virt_net_init,它分配了vnet_dev结构体,并且设置了结构中的hard_start_xmit 函数为virt_net_sendpacket,设置了MAC地址等信息,最后注册。

2、virt_net_sendpacket函数主要做了发送包信息的统计以及将自己发送出去的包回环给了自己,做到了自发自收的功能,调用函数emulator_rx_packet

3、emulator_rx_packet函数主要将发送包的mac地址与ip地址的目标、源对调,这样做就可以实现自发自收。最后调用netif_rx上传给上层协议层

/** 参考drivers\net\cs89x0.c*/#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include

static struct net_device *vnet_dev;static void emulator_rx_packet(struct sk_buff *skb, struct net_device *dev)

{/*参考LDD3*/unsignedchar *type;struct iphdr *ih;

__be32*saddr, *daddr, tmp;

unsignedchartmp_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(structethhdr));

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(structiphdr);//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_buff

rx_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_sendpacket(struct sk_buff *skb, struct net_device *dev)

{static int cnt = 0;

printk("virt_net_sendpacket 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);/*2、设置*/vnet_dev->hard_start_xmit =virt_net_sendpacket;/*设置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_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("andy");

MODULE_LICENSE("GPL");

接着将代码编译后进行测试:注意在测试时网络设备需要存在lo网络才能实现自发自收

1、insmod virt_net.ko

2、ifconfig vnet0 3.3.3.3

ifconfig //查看

3、ping 3.3.3.3 //成功(只有从网络文件系统启动才可以成功,猜是只有有lo网络才行)

4、ping 3.3.3.4 //成功

到这里,虚拟网卡驱动程序测试成功。

linux 3.10 网卡驱动程序示例,网卡驱动程序框架以及虚拟网卡驱动程序的实现相关推荐

  1. 删除Windows中隐藏的物理网卡和网络虚拟化失败后的虚拟网卡

    Windows环境下,在更换硬件服务器主板和网卡等硬件.恢复操作系统或者网络虚拟化失败后,可能会出现网卡方面的问题.例如,设备管理器中多了不应该存在的网卡:因命名冲突无法重命名当前网络连接:IP地址冲 ...

  2. hyper服务器虚拟网卡和实际网卡,关于Hyper-V虚拟机中的vEthernet虚拟网卡不能联网的问题...

    Hyper-V虚拟机在我电脑里面已经有一年了,当初是因为windows8系统里面需要装Hyper-V,这样才能不让win8死机,就折腾了一整子,结果碰到vEthernet网卡不能联网,网上相关的资料少 ...

  3. 服务器虚拟网卡卸载不掉,怎么彻底卸载虚拟网卡设备。 彻底卸载虚拟网卡设备的方法。...

    今天给大家带来怎么彻底卸载虚拟网卡设备.,彻底卸载虚拟网卡设备的方法.,让您轻松解决问题.网友求助:求助如何卸载虚拟网卡? 具体方法如下:1 使用Win+R调出运行,在其中输入:devmgmt.msc ...

  4. 虚拟网卡是什么?教教大家添加虚拟网卡的方法

    不少用户都发出疑问虚拟网卡是什么?其实虚拟网卡就是通过软件模拟出来的电脑网卡,微软操作系统都具备这一功能.那么下面小编就来教教大家Windows10系统添加虚拟网卡的方法,非常简单. Windows1 ...

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

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

  6. linux里添加网卡,Linux添加虚拟网卡的多种方法

    Linux添加虚拟网卡的多种方法有时候,一台服务器需要设置多个ip,但又不想添加多块网卡,那就需要设置虚拟网卡.这里介绍几种方式在linux服务器上添加虚拟网卡.我们 有时候,一台服务器需要设置多个i ...

  7. linux 虚拟网卡与物理网卡关系,Linux Macvlan的虚拟网卡与宿主物理网卡之间的Bridge通信问题...

    周末的时候写了一篇关于Docker底层支撑技术的文章: 以firejail sandbox解析Docker核心原理依赖的四件套 : https://blog.csdn.net/dog250/artic ...

  8. Linux虚拟网卡bond配置

    目录 一.bond概述 1.1.bond的优点 二.bond模式 2.1.mode=0 2.2.mode=1 2.3.mode=2 2.4.mode=3 2.5.mode=4 2.6.mode=5 2 ...

  9. Linux Macvlan的虚拟网卡与宿主物理网卡之间的Bridge通信问题

    周末的时候写了一篇关于Docker底层支撑技术的文章: 以firejail sandbox解析Docker核心原理依赖的四件套:https://blog.csdn.net/dog250/article ...

最新文章

  1. VS.net2008正式版发布了
  2. 七、内存优化(4)性能计数器
  3. 各种浏览器的userAgent
  4. 用window.location.href实现刷新另个框架页面
  5. 洛谷 P3865 【模板】ST表
  6. 通过配置ssh深刻理解puppet的语法及工作机制
  7. 倒计时5天:5G还是6G?
  8. DOCKER存储驱动之DEVICE MAPPER简介
  9. access根据所属院系修改学号_2012年计算机等考二级Access模拟试题四
  10. 麒麟ARM版:不能使用U盘安装,只能使用光盘
  11. 自己做量化交易软件(22)小白量化之MetaTrader5自动交易1
  12. Visio 2010导入中UML2.2模板说明
  13. 几句代码让Ios系统内核崩溃
  14. 服务器raid卡维修,服务器Raid卡故障|服务器RAID卡坏恢复数据
  15. 五分钟科普:微信 PC 端多开的秘密
  16. 搜索插件像百度那样的智能感知效果
  17. 白钢条用什么可以切割_白钢用什么切割?
  18. android从应用到驱动之—camera(2)---cameraHAL的实现
  19. 试题2-12:数据库设计与操作
  20. springboot杂谈

热门文章

  1. JSTL和Ajax小计
  2. python有趣小程序春节祝福-轻松玩转Python发送新春祝福给指定好友
  3. html春节祝福烟花,《烟花AR》用ARkit带来浪漫情人节和新春祝福
  4. CAP原理,分布式一致性算法,两阶段提交,三阶段提交,Paxos,Raft,zookeeper的选主过程,zab协议,顺序一致性,数据写入流程,节点状态,节点的角色
  5. 第二十二章 SQL函数 CAST(一)
  6. POI 解析Excel,以及引用公式、计算公式的正常解析
  7. 黑客不讲武德,苹果好自为之
  8. 2021年熔化焊接与热切割模拟试题及熔化焊接与热切割模拟考试
  9. INTERLLij IDEA 修改背景颜色护眼
  10. Day7 T1 直角三角形