【发布时间】:2010-12-24 02:44:20
【问题描述】:
我发现我需要在内核模块中构建一个新的sk_buff 结构并将其传递给我的网络设备,但我不知道如何为一个简单的原始以太网数据包设置结构变量.
这一定很简单,但如果有人能给我一个如何将sk_buff 放在一起的示例代码,我将不胜感激。
【问题讨论】:
标签: c sockets linux-kernel network-programming raw-sockets
我发现我需要在内核模块中构建一个新的sk_buff 结构并将其传递给我的网络设备,但我不知道如何为一个简单的原始以太网数据包设置结构变量.
这一定很简单,但如果有人能给我一个如何将sk_buff 放在一起的示例代码,我将不胜感激。
【问题讨论】:
标签: c sockets linux-kernel network-programming raw-sockets
查看net/packet/af_packet.c 中的函数packet_sendmsg_spkt 以获得灵感。如果您没有套接字,最困难的部分是获得struct sock...
编辑:添加了基本的代码外壳:
int sendpacket(struct socket *sock, struct net_device *dev, __be16 proto, void *data, size_t len)
{
struct sock *sk = sock->sk;
struct sk_buff *skb;
if (!(dev->flags & IFF_UP))
return -ENETDOWN;
if (len > dev->mtu + dev->hard_header_len)
return -EMSGSIZE;
skb = sock_wmalloc(sk, len + LL_RESERVED_SPACE(dev), 0, GFP_KERNEL);
if (skb == NULL)
return -ENOBUFS;
/* FIXME: Save some space for broken drivers that write a
* hard header at transmission time by themselves. PPP is the
* notable one here. This should really be fixed at the driver level.
*/
skb_reserve(skb, LL_RESERVED_SPACE(dev));
skb_reset_network_header(skb);
/* Try to align data part correctly */
if (dev->header_ops) {
skb->data -= dev->hard_header_len;
skb->tail -= dev->hard_header_len;
if (len < dev->hard_header_len)
skb_reset_network_header(skb);
}
memcpy(skb_put(skb, len), data, len);
skb->protocol = proto;
skb->dev = dev;
skb->priority = sk->sk_priority;
dev_queue_xmit(skb);
return len;
}
【讨论】: