世事皆虚幻 发表于 2016-05-07 11:22

本帖最后由 世事皆虚幻 于 2016-05-07 11:50 编辑

回复 10# 世事皆虚幻


    目前最新进展:调用以下函数,可以向上层发送 SYN 报文,服务端会向客户端发送 SYN+ACK, 但是该函数会卡在 dst_input, 这个函数出不来,咋回事儿呢?
int SendTcpPacket(__be32 sip, __be16 sport, __be32 dip, __be16 dport, __be32 seq, __u8 syn, __u8 fin, __u8 rst, __u8 ack, __be32 seq_ack)
{
    struct dst_entry* dest = NULL;
    struct sk_buff *skb;
    struct tcphdr* tcph;
    struct iphdr *iph;
    int ip_payload_size;
    int result;

    skb = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC|__GFP_ZERO);
    if (skb == NULL)
    {
      printk(KERN_ALERT"Failed to alloc_skb\n");
      return -1;
    }
    skb_reserve(skb, sizeof(struct iphdr) + sizeof(struct tcphdr));

    // TCP header
    tcph = (struct tcphdr *)skb_push(skb, sizeof(struct tcphdr));
    tcph->source= sport;
    tcph->dest    = dport;
    tcph->doff    = (sizeof(struct tcphdr) >> 2);
    tcph->psh   = 0;
    tcph->seq   = seq;
    tcph->syn   = syn;
    tcph->fin   = fin;
    tcph->rst   = rst;
    tcph->ack   = ack;
    tcph->ack_seq = seq_ack;
    tcph->window= htons(0xFFFF);
    skb_reset_transport_header(skb);

    // IP Header
    iph = (struct iphdr *)skb_push(skb, sizeof(struct iphdr));
    iph->ihl      = (sizeof(struct iphdr) >> 2);
    iph->version= 4;
    iph->tot_len= htons(skb->len);
    iph->ttl      = 64;
    iph->tos      = 0;
    iph->protocol = IPPROTO_TCP;
    iph->saddr    = sip;
    iph->daddr    = dip;
    ip_send_check(iph);
    skb_reset_network_header(skb);

    ip_payload_size = skb->len - sizeof(struct iphdr);
    skb->csum = skb_checksum(skb, sizeof(struct iphdr), ip_payload_size, 0);
    tcph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, ip_payload_size, iph->protocol, skb->csum);
    skb->ip_summed = CHECKSUM_UNNECESSARY;
    //skb->ip_summed = CHECKSUM_NONE;
    skb->pkt_type = PACKET_HOST;

    {
      struct rtable *rt;                /* Route to the other host */
      struct flowi fi;

      memset(&fi, 0, sizeof(struct flowi));
      fi.fl4_dst = sip;
      //fi.proto = IPPROTO_IPIP;

      if (0 != ip_route_output_key(&init_net, &rt, &fi))
      {
            return -1;
      }

      if (NULL == rt)
      {
            return -1;
      }

      dest = &rt->u.dst;
      //dev_hold(dest->dev);
    }

    skb->dev = dest->dev;
    skb_dst_set(skb, dest);

    result = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dest->dev);
    if (unlikely(result))
    {
      // Host Unreachable
      printk(KERN_ALERT"Failed to ip_route_input\n");
      return -1;
    }

    result = dst_input(skb);
    if (result != NET_RX_SUCCESS)
    {
      kfree_skb(skb);
      printk(KERN_ALERT"Failed to send packet. ErrCode=%d\n", result);
    }
    else
    {
      printk(KERN_ALERT"Send packet succeeded from %pI4:%d to %pI4:%d\n", &sip, ntohs(sport), &dip, ntohs(dport));
    }

    return 0;
}

世事皆虚幻 发表于 2016-05-07 12:32

结贴,已搞定,多谢关注~

Godbach 发表于 2016-05-08 21:15

回复 12# 世事皆虚幻

欢迎分享一下解决的方法。


   

nswcfd 发表于 2016-05-09 20:29

卡在?
难道产生了递归调用,要不然总会有个结果出来吧?
(没有跟踪具体上下文)
页: 1 [2]
查看完整版本: 在模块加载时构造SYN包并发送到本机