UDP packet send with linux-kernel module without using sockets

后端 未结 1 1069
甜味超标
甜味超标 2021-02-04 19:54

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 i

1条回答
  •  说谎
    说谎 (楼主)
    2021-02-04 20:54

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

    0 讨论(0)
提交回复
热议问题