从内核模块中发送原始以太网数据包

11

我发现需要在内核模块中构建一个新的sk_buff结构体并将其传递给网络设备,但我无法弄清楚如何为简单的原始以太网数据包设置结构体变量。

这应该很简单,但如果有人能够提供一个将sk_buff组合在一起的示例代码,我会非常感激。

1个回答

11

请查看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;
}

如何获取套接字的任何想法? - James Talbert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接