背景:我是 UCSB 计算机工程专业的四年级学生。我参加过网络和操作系统课程。我在用户空间中创建了一个程序,它将 UDP 数据包广播到子网上,并在自组织网络中接收 UDP 数据包。我想要完成的任务是将这个程序转换为一个内核模块,该模块将在具有 Angstrom Linux 内核版本 2.6.39 的 ARM 嵌入式系统上运行(x86 到 ARM 架构的交叉编译是另一天的问题)。迁移到内核的原因是为了减少用户空间函数的一些开销,并使发送和接收部分尽可能快。
我以前从未在我所学的任何课程中做过这样的事情,所以请告诉我我所说的是否不正确、无用或低效!
经过与 Google 的研究后,我得出的结论是,典型的方法是完全取消套接字并使用sockbuf
结构并自己填写必要的标题。这会影响子网上广播数据包的能力吗?
我目前正在尝试遵循此处的代码:使用linux内核模块发送UDP数据包而不使用套接字
我已经弄清楚了大部分代码背后的原因,但最后一部分让我感到困惑:
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 地址字段中到底应该放入什么内容呢?
- 更重要的是,dev 是什么?
skb->dev = dev;
线?根据我的调查,它是一个指向与其关联的设备驱动程序的指针。根据我的理解,我希望它指向无线芯片设备驱动程序,因为我使用 802.11 进行通信。我必须创建自己的吗dev
无线驱动程序的结构?如果是这样,有关于如何实现这一目标的指导吗?如果没有,我如何访问现有的设备驱动程序并在内核模块中使用它?
我尝试注释掉 dev 行并运行代码,但毫不奇怪,一旦执行,我就会出现内核恐慌dev_queue_xmit(skb);
.
再说一次,我以前从未做过这样的事情,所以任何建议都会有帮助,即使这意味着完全改变我的方法!我也知道这可能是一个小问题,但任何形式的指导都是值得赞赏的!
先感谢您!