小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

3

 jijo 2008-12-09
netfilter中的conntrack內(nèi)核閱讀筆記(3)
2008-07-07 22:06
PREROUTINGip_conntrack_defrag à ip_conntrack_in

1,ip_conntrack_defrag:

通常當(dāng)IP報文被送至L4層處理時,如果該報文是分片報文,那么報文就會先被保存起來,直到所有分片到達后重組成一個完整報文后,再被分發(fā)到L4層。當(dāng)沒有啟動conntrack時,netfilterHOOK點對報文操作時,并不檢查該報文是否分片;但是如果啟動conntrack功能,則必須保證進入netfilter HOOK點的報文是一個完整的報文,因此ip_conntrack_defrag一般處于最前端的HOOK,負責(zé)將分片報文重組。

/* 若報文分片,則 調(diào)用ip_ct_gather_frags 組裝報文,如果所有分片均已到達,pskb指向新生成的報文,繼續(xù)沿著HOOK鏈進行下一步處理;否則為空,報文被緩存等待下一分片到來*/

if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {

     *pskb = ip_ct_gather_frags(*pskb,

                                hooknum == NF_IP_PRE_ROUTING ?

                      IP_DEFRAG_CONNTRACK_IN :

                      IP_DEFRAG_CONNTRACK_OUT);

     if (!*pskb)

          return NF_STOLEN;

}

return NF_ACCEPT;

ip_ct_gather_frags直接調(diào)用ip_defrag處理IP分片報文。對于分片報文的重組主要在ip_fragment.c中完成。

2ip_conntrack_in

當(dāng)報文到達ip_conntrack_in時,首先判斷系統(tǒng)連接跟蹤表中是否已經(jīng)存在該報文相應(yīng)的連接狀態(tài)ip_conntrack,若沒有,則建立相應(yīng)的數(shù)據(jù)結(jié)構(gòu),并初始化。獲取相應(yīng)的ip_conntrack后,用報文所攜帶的數(shù)據(jù),修改連接狀態(tài)。

/*1,檢查報文是否已經(jīng)經(jīng)過狀態(tài)檢測,nfct是指向相應(yīng)連接狀態(tài)數(shù)據(jù)結(jié)構(gòu)的指針*/

/* Previously seen (loopback or untracked)? Ignore. */

     if ((*pskb)->nfct) {

         CONNTRACK_STAT_INC(ignore);

         return NF_ACCEPT;

     }

/*2,檢查報文是否分片,從前面的分析可以看出,這種情況不可能發(fā)生;net_ratelimit用于保護內(nèi)核網(wǎng)絡(luò)調(diào)試信息的打印,當(dāng)它返回(TRUE)時則可以打印調(diào)試信息,返回零則禁止信息打印。*/

     /* Never happen */

     if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {

         if (net_ratelimit()) {

         printk(KERN_ERR "ip_conntrack_in: Frag of proto %u (hook=%u)\n",

                (*pskb)->nh.iph->protocol, hooknum);

         }

         return NF_DROP;

     }

/*3,根據(jù)ip報文所攜帶數(shù)據(jù)的協(xié)議號,獲取相應(yīng)的協(xié)議封裝,該數(shù)據(jù)結(jié)構(gòu)封裝了對協(xié)議私有數(shù)據(jù)處理的函數(shù)和屬性;調(diào)用該協(xié)議相應(yīng)的error處理函數(shù),檢查報文是否正確*/

        proto = __ip_conntrack_proto_find((*pskb)->nh.iph->protocol);

          /* It may be an special packet, error, unclean...

          * inverse of the return code tells to the netfilter

          * core what to do with the packet. */

          if (proto->error != NULL && (ret = proto->error(*pskb, &ctinfo, hooknum)) <= 0)

             CONNTRACK_STAT_INC(error);

             CONNTRACK_STAT_INC(invalid);

             return -ret;

           }

        /*4,在全局連接表中,查找與該報文相應(yīng)的連接狀態(tài),返回的是ip_conntrack的指針,用于描述和記錄連接的狀態(tài);若該連接尚不存在,則創(chuàng)建相應(yīng)的結(jié)構(gòu),并進行初始化*/

                if (!(ct = resolve_normal_ct(*pskb, proto,&set_reply,hooknum,&ctinfo))) {

              /* Not valid part of a connection */

              CONNTRACK_STAT_INC(invalid);

              return NF_ACCEPT;

           }

          

        /*5,調(diào)用相應(yīng)協(xié)議的packet處理函數(shù),判斷報文是否屬于有效連接,并更新連接狀態(tài);返回值若不為NF_ACCEPT,則報文不合法 */

           ret = proto->packet(ct, *pskb, ctinfo);

           if (ret < 0) {

             /* Invalid: inverse of the return code tells

            * the netfilter core what to do*/

             nf_conntrack_put((*pskb)->nfct);

             (*pskb)->nfct = NULL;

             CONNTRACK_STAT_INC(invalid);

             return -ret;

         }

/*6,根據(jù)4的結(jié)果,設(shè)置應(yīng)答位;ip_conntrack_event_cache,用戶要求對連接跟蹤進行更詳細的控制(數(shù)據(jù)包是REPLY),使用??event_cache機制??*/

          if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))

               ip_conntrack_event_cache(IPCT_STATUS, *pskb);

  

 

3, resolve_normal_ct

   resolve_normal_ct在全局連接表中,查找與該報文相應(yīng)的連接狀態(tài),返回的是ip_conntrack的指針,用于描述和記錄連接的狀態(tài);若該連接尚不存在,則創(chuàng)建相應(yīng)的結(jié)構(gòu),并進行初始化,設(shè)置連接狀態(tài)。

   /*1,將數(shù)據(jù)包的內(nèi)容轉(zhuǎn)化成相應(yīng)的tuple,對于和協(xié)議相關(guān)的部分,如端口,則調(diào)用相關(guān)協(xié)議的處理函數(shù)pkt_to_tuple*/

      if (!ip_ct_get_tuple(skb->nh.iph, skb, skb->nh.iph->ihl*4,

                   &tuple,proto))

         return NULL;

   /*2,在全局連接表中查找和tuple相同的hash項,全局連接表以tuple計算出相應(yīng)的hash值,每一個hash項所保存的元素也是相應(yīng)的tuple*/

      h = ip_conntrack_find_get(&tuple, NULL);

   /*3,若在全局連接表中無法查到tuple所對應(yīng)的hash項,即相應(yīng)的連接狀態(tài)不存在,系統(tǒng)調(diào)用init_conntrack創(chuàng)建并初始化ip_conntrack,并返回其相應(yīng)的tuple結(jié)構(gòu)指針*/

      if (!h) {

         h = init_conntrack(&tuple, proto, skb);

         if (!h)

              return NULL;

         if (IS_ERR(h))

              return (void *)h;

     }

   /*4,根據(jù)全局連接表所獲得tuple,獲取其對應(yīng)的ip_conntrack結(jié)構(gòu)*/

      ct = tuplehash_to_ctrack(h);

   /*5,判斷連接方向,若是reply方向,設(shè)置相應(yīng)的應(yīng)答標識和數(shù)據(jù)包狀態(tài)標識*/

      if (DIRECTION(h) == IP_CT_DIR_REPLY) {

         *ctinfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY;

         /* Please set reply bit if this packet OK */

         *set_reply = 1;

     } else {

   /*6, 若是origin方向,根據(jù)ip_conntrack中的status,設(shè)置相應(yīng)的應(yīng)答標識和數(shù)據(jù)包狀態(tài)標識*/

         /* Once we've had two way comms, always ESTABLISHED. */

         if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {

              DEBUGP("ip_conntrack_in: normal packet for %p\n",

                     ct);

                 *ctinfo = IP_CT_ESTABLISHED;

         } else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) {

              DEBUGP("ip_conntrack_in: related packet for %p\n",

                     ct);

              *ctinfo = IP_CT_RELATED;

         } else {

              DEBUGP("ip_conntrack_in: new packet for %p\n",

                     ct);

              *ctinfo = IP_CT_NEW;

         }

         *set_reply = 0;

     }

   /*7, 設(shè)置skb的對應(yīng)成員,數(shù)據(jù)包對應(yīng)的連接狀態(tài)結(jié)構(gòu)和數(shù)據(jù)包連接狀態(tài)標記*/

      skb->nfct = &ct->ct_general;

     skb->nfctinfo = *ctinfo;

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多