我们知道,Linux下的驱动分为字符设备驱动、块设备驱动和网络设备驱动,网络设备是通过socket通信实现对数据的接收和传递,并不会像字符设备一样会打开某一个文件。网络设备驱动中包含着对网卡等内部比较复杂的硬件操作和各种协议,所以现在暂时还实现不了像之前字符设备块设备一样从头到尾对着某个网卡来写一个完整的驱动程序,现在就构造一个虚拟网卡,重点是弄清楚网卡驱动的基本框架.

网卡驱动在系统中的框架如图:

网卡驱动程序_第1张图片

如图所示,应用程序通过socket编程需要实现网络包的发送和接收,需要发送的消息内容需要经过若干层网络协议的包装,构造成一个sk_buff结构体,再由驱动程序中的hard_start_xmit函数发送出去,接包时则是使用驱动程序中对应的netif_rx函数。

怎么写网卡驱动程序?

a. 分配一个net_device结构体

b. 设置:

(1) 发包函数: hard_start_xmit

(2) 收到数据时(在中断处理函数里)用netif_rx上报数据

(3) 其他设置

c. 注册: register_netdevice

程序的框架还是挺简单的,重点和难点在于对网卡的硬件设置和协议(此略)。

例子:构造一个虚拟网卡,实现ping通同一网段的ip(例子主要是为了弄清楚框架,并不能实现真正的网卡功能)

网卡驱动程序_第2张图片

网卡驱动程序_第3张图片

测试该驱动程序:

  1. 装载驱动程序

  2. ifconfig查看网卡信息

  3. 用ifconfig vir0 2.2.2.2构造一个虚拟网卡,通过ifconfig命令即可看到比之前多了一个vir0网卡

  4. 通过ping 2.2.2.3可以ping通,并且看到hard_start_xmit被调用。

  5. 网卡驱动程序_第4张图片

    网卡驱动程序_第5张图片

    注意:如果驱动程序中没有实现对应的hard_start_xmit函数,则当ping同一网段的ip时,系统会被卡死。通过实现的net_device结构体中对应成员,还可以实现设置mask地址、显示发送/接收包的数量。