当前位置:  技术问答>linux和unix

【求助】怎么填充一个sk_buffer,发送一个UDP包?

    来源: 互联网  发布时间:2016-08-04

    本文导语:  请问哪位大侠有在内核态,申请sk_buffer空间,并填充,发送UDP包的代码?借来学习学习,研究了1个星期了,还没发送成功过。 | 内核里面本来就有这种代码,见netpoll实现 void netpoll_send_udp(str...

请问哪位大侠有在内核态,申请sk_buffer空间,并填充,发送UDP包的代码?借来学习学习,研究了1个星期了,还没发送成功过。

|
内核里面本来就有这种代码,见netpoll实现

void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
{
        int total_len, eth_len, ip_len, udp_len;
        struct sk_buff *skb;
        struct udphdr *udph;
        struct iphdr *iph;
        struct ethhdr *eth;

        udp_len = len + sizeof(*udph);
        ip_len = eth_len = udp_len + sizeof(*iph);
        total_len = eth_len + ETH_HLEN + NET_IP_ALIGN;

        skb = find_skb(np, total_len, total_len - len);
        if (!skb)
                return;

        skb_copy_to_linear_data(skb, msg, len);
        skb->len += len;

        skb_push(skb, sizeof(*udph));
        skb_reset_transport_header(skb);
        udph = udp_hdr(skb);
        udph->source = htons(np->local_port);
        udph->dest = htons(np->remote_port);
        udph->len = htons(udp_len);
        udph->check = 0;
        udph->check = csum_tcpudp_magic(np->local_ip,
                                        np->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       = 0;
        iph->frag_off = 0;
        iph->ttl      = 64;
        iph->protocol = IPPROTO_UDP;
        iph->check    = 0;
        put_unaligned(np->local_ip, &(iph->saddr));
        put_unaligned(np->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, np->dev->dev_addr, ETH_ALEN);
        memcpy(eth->h_dest, np->remote_mac, ETH_ALEN);

        skb->dev = np->dev;

        netpoll_send_skb(np, skb);
}


|
参数UDP的发送过程嘛。

|
去看源码吧吗,应该在ip_input.c

|
一个发送 tcp rst 的例子
改改就好了
void send_reset(struct sk_buff *oldskb)
{
struct sk_buff *nskb;
const struct iphdr *oiph;
struct iphdr *niph;
const struct tcphdr *oth;
struct tcphdr _otcph, *tcph;
struct ethhdr *neth;
char   *pad;
int    len;
int    padlen = 0;
int    tcplen = 0;
//struct dst_entry *dst = NULL;
//struct rtable *rt = NULL;
struct net_device *odev = NULL;

/* IP header checks: fragment. */
if ( giph( oldskb )->frag_off & htons(IP_OFFSET))
return;

//oth = skb_header_pointer(oldskb, giph( oldskb ) dev = odev;
//nskb->pkt_type = PACKET_HOST;
//nskb->protocol = __constant_htons( ETH_P_IP );
// 取得ethhdr地址,
skb_reset_mac_header(nskb);
neth = (struct ethhdr *)skb_put(nskb, sizeof( struct ethhdr ) );
/*
if ( skb_mac_header_was_set( oldskb ) ) {

memcpy( neth->h_dest, eth_hdr( oldskb )->h_source, ETH_ALEN );
memcpy( neth->h_source, eth_hdr( oldskb )->h_dest, ETH_ALEN );
neth->h_proto = eth_hdr( oldskb )->h_proto;
}
*/

niph = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
niph->version = 4;
niph->ihl = sizeof(struct iphdr) / 4;
niph->tos = 0;
niph->id = 0;
niph->frag_off = htons(IP_DF);
niph->protocol = IPPROTO_TCP;
niph->check = 0;

niph->saddr = oiph->daddr;
niph->daddr = oiph->saddr;

#if 0
niph->saddr = MKNL( 192, 168, 1, 12 );
//niph->daddr = MKNL( 8, 8, 8, 8 );
niph->daddr = MKNL( 192, 168, 1, 18 );
#endif

tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
memset(tcph, 0, sizeof(*tcph));
tcph->source = oth->dest;
tcph->dest = oth->source;
tcph->doff = sizeof(struct tcphdr) / 4;

if (oth->ack)
tcph->seq = oth->ack_seq;
else {
tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +
      oldskb->len - ip_hdrlen(oldskb) -
      (oth->doff rst = 1;

pad = NULL;
//pad = skb_put( nskb, padlen );
//memset( pad, 0x0, padlen );

tcplen = sizeof(struct tcphdr) + padlen ;
tcph->check = 0;
tcph->check = tcp_v4_check( tcplen,
       niph->saddr, niph->daddr,
       csum_partial(tcph,
    tcplen, 0));

niph->ttl = oiph->ttl;

#if 0
niph->tot_len = htons( len - ETH_HLEN );
niph->check = 0;
niph->check = ip_fast_csum( ( u8 * )niph, niph->ihl );
#endif
// 查找output route     
if ( ip_route_out( nskb, niph ) != 0 ) {
goto free_nskb;
}

// 设置skb networker layer地址
__skb_pull( nskb, ETH_HLEN );
skb_reset_network_header(nskb);

//xmit_enqueue( nskb );
//local_out_enqueue( nskb );
ip_local_out(nskb);
return;

free_nskb:
trace( "free nskb.n" );
kfree_skb(nskb);     
return ;
}

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 求助,udp文件传输发送端发送完了,接收端却接受到一半就bad address?
  • [求助]请问socket编程中send()函数可以发送整形数据吗?
  • 求助:有关串口发送字符串问题
  • 求助:根据波特率(bps)比较均匀的发送数据包的解决办法
  • 高分求助(今天结帐):怎样设置自己的smtp发送javamail?
  • 100分紧急求助:java程序在linux下不能发送邮件,windows下正常。
  • 求助!!!linux tcp发送 xp tcp接收 出现的问题
  • 【求助】linux/Unix下创建子进程,向父进程发送信号,子进程也能收到改信号,此时如何让子进程不收到信号
  • 高分求助高分求助高分求助高分求助高分求助高分求助
  • 怎样读取HZK24S前十区的内容啊???求助求助
  • 紧急求助!紧急求助!
  • 【求助】iplanet问题,求助高手解答!
  • 菜鸟求助,solaris下计算问题求助
  • 【求助】SOS紧急求助..............极为简单的问题...跪求....
  • 高分求助啊!求助SUSE 10.0 不能上网.
  • 急急急急急急急啊,紧急求助啊!!!!!满分求助啊!!!!!!
  • 求助:linux下 vim的配置(高分求助)
  • red hat怎么安装gcc啊!总是出错,求助求助啊!!!yum源怎么改啊!!
  • 求助~~求助 ~~linux文件读写问题
  • 求助:信号 --13 进程中断
  • 求助,安装了红帽子后进不了
  • 新装linux求助
  • linux的 iptables问题求助
  • (高分求助)请问,那里有软件开发的<设计文档>
  • 一个简单的问题,高分求助!!!
  • 紧急求助:Unix下给文件夹重命名用什么命令?谢谢!!!!
  • VJ的一个问题,高分求助,熟悉VJ得请进!
  • 高分求助


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3