使用linux-kernel模块发送的UDP数据包不使用套接字 [英] UDP packet send with linux-kernel module without using sockets

查看:178
本文介绍了使用linux-kernel模块发送的UDP数据包不使用套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个创建IP数据包的内核模块.现在,我想发送此数据包,但尚未为其传输创建任何套接字.

I am writing a kernel module which creates a IP packet. Now i want to send this packet but haven't created any socket for it's transmission.

有什么方法可以借助内核例程直接发送它.

is there any way to send it directly with the help of kernel routines.

由于我已经跟踪了Linux内核代码以进行数据包传输,因此在 net/core/dev.c 中定义了一个名为 dev_hard_start_xmit()的函数.我们可以使用它吗?

as i have tracked the linux kernel code for packet transmission there is a function defined in net/core/dev.c named as dev_hard_start_xmit(). can we use it?

实际上我不想使用套接字.

Actually i don't want to use sockets.

推荐答案

您不需要套接字就可以在内核中发送UDP数据包,只需要分配一个skb,并自己构造IP头和UDP头,最后通过dev_queue_xmit()将其发送出去.

You don't need a socket to send a UDP packet in kernel, you just need to allocate an skb, and construct the IP header and UDP header by yourself, and finally send it out by dev_queue_xmit().

skb = alloc_skb(len, GFP_ATOMIC);
if (!skb)
        return;

skb_put(skb, len);

skb_push(skb, sizeof(*udph));
skb_reset_transport_header(skb);
udph = udp_hdr(skb);
udph->source = htons(....);
udph->dest = htons(...);
udph->len = htons(udp_len);
udph->check = 0;
udph->check = csum_tcpudp_magic(local_ip,
                                remote_ip,
                                udp_len, IPPROTO_UDP,
                                csum_partial(udph, udp_len, 0));

if (udph->check == 0)
        udph->check = CSUM_MANGLED_0;

skb_push(skb, sizeof(*iph));
skb_reset_network_header(skb);
iph = ip_hdr(skb);

/* iph->version = 4; iph->ihl = 5; */
put_unaligned(0x45, (unsigned char *)iph);
iph->tos      = 0;
put_unaligned(htons(ip_len), &(iph->tot_len));
iph->id       = htons(atomic_inc_return(&ip_ident));
iph->frag_off = 0;
iph->ttl      = 64;
iph->protocol = IPPROTO_UDP;
iph->check    = 0;
put_unaligned(local_ip, &(iph->saddr));
put_unaligned(remote_ip, &(iph->daddr));
iph->check    = ip_fast_csum((unsigned char *)iph, iph->ihl);

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);

这篇关于使用linux-kernel模块发送的UDP数据包不使用套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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