应给如何取得sk_buff的tcp的信息呢?

时间:2021-03-14 11:03:04
各位大侠,下面的几个方法都试了,就是不好用。

 struct tcphdr  *tchp;
 1、 tchp = (struct tcphdr *)skb_transport_header(pack); 
 2、 tchp = (struct tcphdr *)tcp_hdr(pack);
 3、 tchp = (struct tcphdr *)pack->data+20;

哪位给你取得tcp信息的例子,感激不尽!

6 个解决方案

#1


下面是这个程序出错的地方和代码序列:
unsigned int process_tcp(const struct sk_buff **pack)
{

    t_tcp_conn_clus_link *curr_peer,*new_peer;
    //myuminiint  pack_status = 0;
    t_singl_peer_link_node *curr_conn;
    struct iphdr _iph, *iph;
    struct tcphdr  *tcph,_tcph;
    int flag,nhoff;
    unsigned int retuvalu ;
    myuint  mini_pack_ip;

    unsigned int  *data;
    struct sk_buff *sk_buf;

    sk_buf = alloc_skb(sizeof(struct sk_buff), GFP_ATOMIC);

    skb_copy(sk_buf,GFP_ATOMIC);

    retuvalu = NF_ACCEPT;
    flag = LINK_EMPTY;  
    //nhoff = skb_network_offset(*pack);
   
    curr_peer = tcp_head;

    //iph = skb_header_pointer(*pack, nhoff, sizeof(_iph), &_iph);
    iph = ip_hdr(pack);
    //tcph = (struct tcphdr *)skb_transport_header(pack); //
    //tcph = (struct tcphdr *)tcp_hdr(pack);

    mini_pack_ip = iph->saddr < iph->daddr?
        iph->saddr:iph->daddr;

   data = (unsigned int) (*pack)->data; //+iph->ihl*4);
   下面这句话导致直接死机
   printk(KERN_EMERG"aaaa%d",ip_hdrlen(*pack));
  // tcph = skb_header_pointer((*pack), ip_hdrlen(*pack), sizeof(_tcph), &_tcph);

return NF_ACCEPT;

    while(curr_peer != NULL) 
    {
        if( ( 
            (iph->saddr == curr_peer->tcp_peer->sponsor_ip) 
            && (iph->daddr == curr_peer->tcp_peer->cooprator_ip) 
            )
            ||
            (
            (iph->saddr == curr_peer->tcp_peer->cooprator_ip) 
            && (iph->daddr == curr_peer->tcp_peer->sponsor_ip) 
            )
            )
        {   
            flag = IP_SAME;
            break;
        }

        if(mini_pack_ip 
            >= ( curr_peer->tcp_peer->sponsor_ip
            <curr_peer->tcp_peer->cooprator_ip
            ?curr_peer->tcp_peer->sponsor_ip:curr_peer->tcp_peer->cooprator_ip
               )
          )
        {
            flag = NOT_FIND_SAME_IP;
            curr_peer = curr_peer->pre;
            break;
        }
        curr_peer = curr_peer->next;
    }

    if(IP_SAME == flag)
    {  
        if(!reco_tcp_pack_peer(pack,curr_peer))
        {
            return NF_ACCEPT;
        }
    }else 
    {
 
        new_peer = crea_new_peer(pack);
        if(NULL != new_peer)
        {
            insert_tcp_new_peer(curr_peer,new_peer);
        }else
        {
             return NF_ACCEPT;
        }
    } 

    kfree_skb(sk_buf);
    
    return retuvalu;
    
}

unsigned int package_check(
                          unsigned int hooknum,
                          struct sk_buff **pack,
                          const struct net_device *in,
                          const struct net_device *out,
                          int (*okfn)(struct sk_buff *)
                          )
{
    
    unsigned int retuvalu = NF_ACCEPT;
    
    //struct ip  *ip_pack;
    //struct tcp *tcp_pack;
    struct iphdr _iph, *iph;
    //struct tcphdr  _tcph,*tcph;

    iph = ip_hdr(pack);
    if(!iph) return NF_ACCEPT;

#ifdef AATACKDOSARP
//    printk(KERN_EMERG"\n ARP_DOS:package_check sa= %s, da=%s, proto=%u \n",NIPQUAD(iph->saddr),NIPQUAD

(iph->daddr)
//        ,iph->protocol );
    printk(KERN_EMERG"\n ARP_DOS:package_check sa= %u, da=%u, proto=%u \n",iph->saddr,iph->daddr
        ,iph->protocol );

#endif

    
    if(iph->saddr == iph->daddr)
    {          
        return NF_DROP;
    }
    
    switch(iph->protocol)
    {
    case IPPROTO_TCP:

        retuvalu = process_tcp(pack);
        break;

    }
    
    return retuvalu;
    
}


int init_func(void)
{
    
    nfho.hook     = package_check;
    nfho.hooknum  = NF_INET_LOCAL_IN; 
    nfho.pf       = PF_INET;
    nfho.owner    = THIS_MODULE;
    nfho.priority = NF_IP_PRI_FILTER;  
    nf_register_hook(&nfho);
    
    return 0;
}


void cleanup_func(void)
{
    printk(KERN_EMERG"\n in the function of cleanup_func \n" );
    free_tcp_peers();
    nf_unregister_hook(&nfho);
}

module_init(init_func);
module_exit(cleanup_func);

#2


iph = ip_hdr(pack);应该是iph = ip_hdr(*pack);
程序中其余地方请检查 pack是sk_buff ** 所以*pack才是sk_buff指针

另外 你的输入sk_buff看起来像是完整的raw packet 所以 即使正确使用了*pack 你的第3种也不对
3、 tchp = (struct tcphdr *)pack->data+20;

应该是 (*pack)->data + 34

另外的14是以太网头

#3



/* reference to tcp.c */
struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
{
struct sk_buff *segs = ERR_PTR(-EINVAL);
struct tcphdr *th;
unsigned thlen;
unsigned int seq;
unsigned int delta;
unsigned int oldlen;
unsigned int len;

if (!pskb_may_pull(skb, sizeof(*th)))
goto out;

th = skb->h.th;
thlen = th->doff * 4;
if (thlen < sizeof(*th))
goto out;

if (!pskb_may_pull(skb, thlen))
goto out;

oldlen = (u16)~skb->len;
__skb_pull(skb, thlen);

if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
/* Packet is from an untrusted source, reset gso_segs. */
int type = skb_shinfo(skb)->gso_type;
int mss;

if (unlikely(type &
     ~(SKB_GSO_TCPV4 |
       SKB_GSO_DODGY |
       SKB_GSO_TCP_ECN |
       SKB_GSO_TCPV6 |
       0) ||
     !(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))))
goto out;

mss = skb_shinfo(skb)->gso_size;
skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;

segs = NULL;
goto out;
}

segs = skb_segment(skb, features);
if (IS_ERR(segs))
goto out;

len = skb_shinfo(skb)->gso_size;
delta = htonl(oldlen + (thlen + len));

skb = segs;
th = skb->h.th;
seq = ntohl(th->seq);

do {
th->fin = th->psh = 0;

th->check = ~csum_fold(th->check + delta);
if (skb->ip_summed != CHECKSUM_HW)
th->check = csum_fold(csum_partial(skb->h.raw, thlen,
   skb->csum));

seq += len;
skb = skb->next;
th = skb->h.th;

th->seq = htonl(seq);
th->cwr = 0;
} while (skb->next);

delta = htonl(oldlen + (skb->tail - skb->h.raw) + skb->data_len);
th->check = ~csum_fold(th->check + delta);
if (skb->ip_summed != CHECKSUM_HW)
th->check = csum_fold(csum_partial(skb->h.raw, thlen,
   skb->csum));

out:
return segs;
}
EXPORT_SYMBOL(tcp_tso_segment);

#4


我记得新版本内核的这个地方的声明
unsigned int package_check(
unsigned int hooknum,
struct sk_buff **pack,  应该是 sk_buff * pack的了
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *)
)

-----------------
不知道楼主用的那个版本的?编译的时候注意检查一下warning那些咯


我用过这样的代码是可以的

iph = ip_hdr(skb);
    if (iph->protocol == IPPROTO_TCP) {
        tcph = (void *) iph + iph->ihl * 4;

#5


现在的结果是,要么没取得正确数据,要么运行死机。不过感谢大家的帮助。

#6


学习啦...谢谢lz 和其他达 应给如何取得sk_buff的tcp的信息呢?人们

#1


下面是这个程序出错的地方和代码序列:
unsigned int process_tcp(const struct sk_buff **pack)
{

    t_tcp_conn_clus_link *curr_peer,*new_peer;
    //myuminiint  pack_status = 0;
    t_singl_peer_link_node *curr_conn;
    struct iphdr _iph, *iph;
    struct tcphdr  *tcph,_tcph;
    int flag,nhoff;
    unsigned int retuvalu ;
    myuint  mini_pack_ip;

    unsigned int  *data;
    struct sk_buff *sk_buf;

    sk_buf = alloc_skb(sizeof(struct sk_buff), GFP_ATOMIC);

    skb_copy(sk_buf,GFP_ATOMIC);

    retuvalu = NF_ACCEPT;
    flag = LINK_EMPTY;  
    //nhoff = skb_network_offset(*pack);
   
    curr_peer = tcp_head;

    //iph = skb_header_pointer(*pack, nhoff, sizeof(_iph), &_iph);
    iph = ip_hdr(pack);
    //tcph = (struct tcphdr *)skb_transport_header(pack); //
    //tcph = (struct tcphdr *)tcp_hdr(pack);

    mini_pack_ip = iph->saddr < iph->daddr?
        iph->saddr:iph->daddr;

   data = (unsigned int) (*pack)->data; //+iph->ihl*4);
   下面这句话导致直接死机
   printk(KERN_EMERG"aaaa%d",ip_hdrlen(*pack));
  // tcph = skb_header_pointer((*pack), ip_hdrlen(*pack), sizeof(_tcph), &_tcph);

return NF_ACCEPT;

    while(curr_peer != NULL) 
    {
        if( ( 
            (iph->saddr == curr_peer->tcp_peer->sponsor_ip) 
            && (iph->daddr == curr_peer->tcp_peer->cooprator_ip) 
            )
            ||
            (
            (iph->saddr == curr_peer->tcp_peer->cooprator_ip) 
            && (iph->daddr == curr_peer->tcp_peer->sponsor_ip) 
            )
            )
        {   
            flag = IP_SAME;
            break;
        }

        if(mini_pack_ip 
            >= ( curr_peer->tcp_peer->sponsor_ip
            <curr_peer->tcp_peer->cooprator_ip
            ?curr_peer->tcp_peer->sponsor_ip:curr_peer->tcp_peer->cooprator_ip
               )
          )
        {
            flag = NOT_FIND_SAME_IP;
            curr_peer = curr_peer->pre;
            break;
        }
        curr_peer = curr_peer->next;
    }

    if(IP_SAME == flag)
    {  
        if(!reco_tcp_pack_peer(pack,curr_peer))
        {
            return NF_ACCEPT;
        }
    }else 
    {
 
        new_peer = crea_new_peer(pack);
        if(NULL != new_peer)
        {
            insert_tcp_new_peer(curr_peer,new_peer);
        }else
        {
             return NF_ACCEPT;
        }
    } 

    kfree_skb(sk_buf);
    
    return retuvalu;
    
}

unsigned int package_check(
                          unsigned int hooknum,
                          struct sk_buff **pack,
                          const struct net_device *in,
                          const struct net_device *out,
                          int (*okfn)(struct sk_buff *)
                          )
{
    
    unsigned int retuvalu = NF_ACCEPT;
    
    //struct ip  *ip_pack;
    //struct tcp *tcp_pack;
    struct iphdr _iph, *iph;
    //struct tcphdr  _tcph,*tcph;

    iph = ip_hdr(pack);
    if(!iph) return NF_ACCEPT;

#ifdef AATACKDOSARP
//    printk(KERN_EMERG"\n ARP_DOS:package_check sa= %s, da=%s, proto=%u \n",NIPQUAD(iph->saddr),NIPQUAD

(iph->daddr)
//        ,iph->protocol );
    printk(KERN_EMERG"\n ARP_DOS:package_check sa= %u, da=%u, proto=%u \n",iph->saddr,iph->daddr
        ,iph->protocol );

#endif

    
    if(iph->saddr == iph->daddr)
    {          
        return NF_DROP;
    }
    
    switch(iph->protocol)
    {
    case IPPROTO_TCP:

        retuvalu = process_tcp(pack);
        break;

    }
    
    return retuvalu;
    
}


int init_func(void)
{
    
    nfho.hook     = package_check;
    nfho.hooknum  = NF_INET_LOCAL_IN; 
    nfho.pf       = PF_INET;
    nfho.owner    = THIS_MODULE;
    nfho.priority = NF_IP_PRI_FILTER;  
    nf_register_hook(&nfho);
    
    return 0;
}


void cleanup_func(void)
{
    printk(KERN_EMERG"\n in the function of cleanup_func \n" );
    free_tcp_peers();
    nf_unregister_hook(&nfho);
}

module_init(init_func);
module_exit(cleanup_func);

#2


iph = ip_hdr(pack);应该是iph = ip_hdr(*pack);
程序中其余地方请检查 pack是sk_buff ** 所以*pack才是sk_buff指针

另外 你的输入sk_buff看起来像是完整的raw packet 所以 即使正确使用了*pack 你的第3种也不对
3、 tchp = (struct tcphdr *)pack->data+20;

应该是 (*pack)->data + 34

另外的14是以太网头

#3



/* reference to tcp.c */
struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
{
struct sk_buff *segs = ERR_PTR(-EINVAL);
struct tcphdr *th;
unsigned thlen;
unsigned int seq;
unsigned int delta;
unsigned int oldlen;
unsigned int len;

if (!pskb_may_pull(skb, sizeof(*th)))
goto out;

th = skb->h.th;
thlen = th->doff * 4;
if (thlen < sizeof(*th))
goto out;

if (!pskb_may_pull(skb, thlen))
goto out;

oldlen = (u16)~skb->len;
__skb_pull(skb, thlen);

if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
/* Packet is from an untrusted source, reset gso_segs. */
int type = skb_shinfo(skb)->gso_type;
int mss;

if (unlikely(type &
     ~(SKB_GSO_TCPV4 |
       SKB_GSO_DODGY |
       SKB_GSO_TCP_ECN |
       SKB_GSO_TCPV6 |
       0) ||
     !(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))))
goto out;

mss = skb_shinfo(skb)->gso_size;
skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;

segs = NULL;
goto out;
}

segs = skb_segment(skb, features);
if (IS_ERR(segs))
goto out;

len = skb_shinfo(skb)->gso_size;
delta = htonl(oldlen + (thlen + len));

skb = segs;
th = skb->h.th;
seq = ntohl(th->seq);

do {
th->fin = th->psh = 0;

th->check = ~csum_fold(th->check + delta);
if (skb->ip_summed != CHECKSUM_HW)
th->check = csum_fold(csum_partial(skb->h.raw, thlen,
   skb->csum));

seq += len;
skb = skb->next;
th = skb->h.th;

th->seq = htonl(seq);
th->cwr = 0;
} while (skb->next);

delta = htonl(oldlen + (skb->tail - skb->h.raw) + skb->data_len);
th->check = ~csum_fold(th->check + delta);
if (skb->ip_summed != CHECKSUM_HW)
th->check = csum_fold(csum_partial(skb->h.raw, thlen,
   skb->csum));

out:
return segs;
}
EXPORT_SYMBOL(tcp_tso_segment);

#4


我记得新版本内核的这个地方的声明
unsigned int package_check(
unsigned int hooknum,
struct sk_buff **pack,  应该是 sk_buff * pack的了
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *)
)

-----------------
不知道楼主用的那个版本的?编译的时候注意检查一下warning那些咯


我用过这样的代码是可以的

iph = ip_hdr(skb);
    if (iph->protocol == IPPROTO_TCP) {
        tcph = (void *) iph + iph->ihl * 4;

#5


现在的结果是,要么没取得正确数据,要么运行死机。不过感谢大家的帮助。

#6


学习啦...谢谢lz 和其他达 应给如何取得sk_buff的tcp的信息呢?人们