扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
伪网络设备驱动的传送例程int ednet_tx(struct sk_buff *skb, struct net_device *dev)将把要发送的网络数据包写入字符设备ed[ED_TX_DEVICE]。在发送完毕数据包的时候,dev_kfree_skb() Kernel API释放由上层协议栈分配的sk_buff数据块。伪网络接口在进行硬件传输的时候,需要为网络数据包打上时间戳。如果传送数据包的时候超时,将调用超时处理例程ednet_tx_timeout()超时处理例程。例程ednet_tx()调用真正的"硬件"传送例程ednet_hw_tx()在实际的网卡驱动程序中,就是真正向特定的网络硬件设备写数据的程序。我们看到,我们的"硬件"就是本文前面描述的字符设备,字符设备的操作例程. kernel_write()在ednet_hw_tx()将被调用。
如果我们希望使用ifconfig看到伪网络接口的统计信息,那么系统就调用 struct net_device_stats *ednet_stats(struct net_device *dev)。我们看到,网络接口的统计信息被放到设备的私有数据指针指向的内存。网络数据信息的统计结构被放在内核结构struct net_device_stats中。
在TCP会话中,也许要协商MTU的大小,int ednet_change_mtu(struct net_device *dev, int new_mtu)可以随时改变MTU的大小。比如在使用FTP协议的时候,在传送数据库的时候,MTU可能被协商为最大,以提高网络传送吞吐量。由于改变了MTU,存放网络数据的字符设备初始化分配的缓存区就要重新被分配,并把已经存放数据的旧的缓存区的内容拷贝到新的缓存区中,所以,当MTU改变大小的时候,那么就要使用kmalloc(new_mtu ,GFP_KERNEL)重新分配缓存区。读者可以根据自己的需要定义新的缓存区大小。kfree()是内核API,负责释放内核空间的内存,它的使用方法和用户空间的free()系统调用一致,这里就不列举ed_realloc()函数的源程序了。
IP数据包在被网络接口发送前,需要构建其以太网头信息int ednet_header(struct sk_buff *skb,struct net_device *dev,unsigned short type,void *daddr,void *saddr,unsigned int len)例程完成此功能,我们看到网络数据包的以太源、目的地址,都是从发送这个数据包的网络接口设备数据结构struct net_device中得到的。源地址和目的地址信息是从网络设备结构得到的。在编译本程序的时候,如果发现htons()这个函数没有定义,可以这样定义htons()为:#define htons(x) ((x>>8) | (x<<8)) 。
因为伪网络接口没有使用ARP获得硬件地址,所以我们可以把我们自己定义的伪硬件地址复制到数据包的以太网包头。Linux2.4.x使用设备方法hard_header()代替设备
方法rebuild_header()。Linux2.x使用的rebuild_header()例程在本文的附加源程序中,这里不再说明。
编写用户空间串口通信程序
控制串口的server应用程序完成非常简单的打包和拆包的工作,它没有差错控制,没有重发机制,在实际应用中,需要加上适当的控制协议。server创建的子进程负责从串口读取数据并把数据传送到receiving device /dev/ed_rec;父进程则负责从sending device /dev/ed_tx 读取需要发送的网络数据包,然后从串口发送出去。子进程和父进程都是用轮询方式读取和写入设备。Server的程序流图如图所示。
图 7
传送的frame按照SLIP定义的格式:数据的两头都是END字符(0300),如图8所示。
图 8
特殊控制字符的定义如下:
|
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者