在内核模块中发送UDP数据包

时间:2014-02-21 05:19:18

标签: network-programming udp kernel linux-device-driver

背景:我是加州大学圣地亚哥分校的第四年计算机工程专业。我参加了网络和操作系统课程。我在用户空间中创建了一个程序,它将UDP数据包广播到子网上,并在一个adhoc网络中接收UDP数据包。我想要完成的是将这个程序转换成一个内核模块,该模块可以在带有Angstrom Linux的ARM嵌入式系统上运行,内核版本为2.6.39(x86到ARM架构交叉编译是另一天的问题)。迁移到内核的原因是为了减少用户空间功能的一些开销,并使发送和接收部分尽可能快。

在我参加的任何课程之前,我从未做过这样的事情,所以请告诉我,如果我说的话不正确,无用或效率低下!

经过与Google的研究,我得出结论,典型的方法是完全取消套接字并使用sockbuf结构并自行填写必要的标题。这会对在子网上广播数据包的能力产生影响吗? 我目前正在尝试按照此处的代码: UDP packet send with linux-kernel module without using sockets

我已经找到了大部分代码背后的原因,但最后一部分让我感到困惑:

eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
skb_reset_mac_header(skb);
skb->protocol = eth->h_proto = htons(ETH_P_IP);
memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
memcpy(eth->h_dest, remote_mac, ETH_ALEN);

skb->dev = dev;


dev_queue_xmit(skb);
  • 除了源MAC地址之外,所有的以太网头似乎都是纯粹由内核中定义的头构建的,这是正确的吗?我将要广播我的数据包,那么究竟应该将哪些内容放入目标MAC地址字段?
  • 更重要的是,skb->dev = dev;行中的dev是什么?从我的调查来看,它是指向与之关联的设备驱动程序的指针。根据我的理解,我希望这指向无线芯片设备驱动程序,因为我使用8​​02.11进行通信。我是否必须为无线驱动程序创建自己的dev结构?如果是这样,有任何指导如何实现这一目标?如果没有,我如何访问现有设备驱动程序并在内核模块中使用它?

我已经尝试评论开发行并运行代码但不出所料,一旦执行dev_queue_xmit(skb);我就会遇到内核恐慌。

同样,我之前从未做过这样的事情,所以任何建议都会有所帮助,即使这意味着完全改变我的方法!我也明白这可能是一个问题的利基,但任何形式的指导都值得赞赏!

提前谢谢!

1 个答案:

答案 0 :(得分:1)

如果您不想修改协议,最好的办法是不干扰协议。在更高(套接字)层上工作。此API可以在net / socket.c中找到。

这将有助于:(在新的浏览器标签/窗口中打开以进行缩放) Linux Kernel Network Flow