在内核模块中发送UDP数据包 [英] Sending a UDP packet within a kernel module

查看:95
本文介绍了在内核模块中发送UDP数据包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:我是UCSB的四年级计算机工程专业.我参加了网络和操作系统课程.我在用户空间中创建了一个程序,该程序将UDP数据包广播到子网中,并在临时网络中接收UDP数据包.我要完成的工作是将该程序转换为可在Angstrom Linux内核版本2.6.39的ARM嵌入式系统上运行的内核模块(x86到ARM体系结构的交叉编译又是一个问题).迁移到内核的原因是为了节省用户空间功能的一些开销,并使发送和接收部分尽可能快.

Background: I'm a fourth year computer engineering major at UCSB. I've taken networking and operating systems courses. I created a program in userspace that broadcasts UDP packets onto the subnet and receives UDP packets in an adhoc network. What I'm trying to accomplish is to convert this program into a kernel module that will work on an ARM embedded system with Angstrom Linux, kernel version 2.6.39 (the x86 to ARM architecture cross compilation is an issue for another day). The reason for this move to the kernel is to shed some of the overhead of userspace functions and to make the sending and receiving part as quick as possible.

在参加过的任何课程中,我从未做过类似的事情,所以请告诉我我说的是不正确的,无用的还是效率低下的!

I've never done anything like this before in any of the courses I've taken, so please tell me if anything I am saying is incorrect, useless or inefficient!

在与Google进行研究之后,我得出结论,典型的方法是完全取消套接字,并使用sockbuf结构并自己填写必要的标头.这会影响子网上广播数据包的能力吗? 我目前正在尝试遵循以下代码: 使用Linux内核模块发送的UDP数据包,无需使用套接字

After research with Google, I've concluded the typical way is to do away with sockets entirely and work with the sockbuf structure and fill in the necessary headers myself. Would this have an effect on the ability to broadcast packets on the subnet? I am currently trying to follow the code here: UDP packet send with linux-kernel module without using sockets

我已经弄清楚了大多数代码的背后原因,但最后一部分却让我感到困惑:

I've figured out the reasoning behind most of the code, but the last part is what confuses me:

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是什么?根据我的调查,它是指向与其关联的设备驱动程序的指针.根据我的理解,我希望它指向无线芯片设备驱动程序,因为我正在使用802.11进行通信.我必须为无线驱动程序创建自己的dev结构吗?如果是这样,那么有关如何实现此目标的任何指导?如果没有,如何访问现有的设备驱动程序并在内核模块中使用它?
    • All of the ethernet header seems to be constructed purely out of headers defined in the kernel besides the source MAC address, is this correct? I am going to be broadcasting my packets, so what exactly should be put into the destination MAC address field?
    • More importantly, what is dev in the skb->dev = dev; line? From my investigation, it is a pointer to the device driver it is associated with. From my understanding, I would want this to point to the wireless chip device driver as I am using 802.11 to communicate. Do I have to create my own dev struct for the wireless driver? If so, there any guidance on how to accomplish this? If not, how can I access the existing device driver and use this in a kernel module?
    • 我尝试注释掉开发行并运行代码,但是毫不奇怪,一旦执行dev_queue_xmit(skb);,我就会感到内核恐慌.

      I've tried commenting out the dev line and running the code but unsurprisingly I get a kernel panic once it executes dev_queue_xmit(skb);.

      同样,我以前从未做过这样的事情,因此即使是完全改变我的方法,任何建议也都将是有帮助的!我也知道这可能是一个小问题,但是任何形式的指导都值得赞赏!

      Again, I've never done anything like this before, so any advice would be helpful, even if it means changing my approach entirely! I also understand that this could be a niche of a question, but any sort of guidance is appreciated!

      提前谢谢!

      推荐答案

      最好的方法是,如果您不尝试修改协议,则不要干扰该协议.在较高的(套接字)层上工作.可以在net/socket.c中找到该API.

      The best way is not to interfere with the protocol if you are not trying to modify one. Work on a higher (socket) layer. This API can be found in net/socket.c

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

      This will help: (open in new browser tab/window to zoom)

      这篇关于在内核模块中发送UDP数据包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆