亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12下一頁
最近訪問板塊 發(fā)新帖
查看: 5610 | 回復: 16
打印 上一主題 下一主題

Netfliter狀態(tài)跟蹤之動態(tài)協(xié)議的實現(xiàn)淺析(tftp實現(xiàn)) [復制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2006-10-15 22:56 |只看該作者 |倒序瀏覽
之所以叫“淺析”,主要是分析其流程,很多細節(jié)的地方?jīng)]有一一注解出來,之所以以tftp為范本來剖析,主要是因為它簡單,呵呵,這篇貼子,作為舊貼
http://72891.cn/viewthread.php?tid=815129&extra=page%3D1%26filter%3Ddigest
的一個補充,好為對Netfliter的狀態(tài)跟蹤分析的結(jié)束……也希望,下一步“Netfliter的地址轉(zhuǎn)換的實現(xiàn)”能早點寫出來……

注:這些貼子,包括iptables,Netfilter的包過濾,Netfliter的狀態(tài)檢測,都只是筆記性質(zhì)的貼子,供有共同興趣的朋友一起討論,其中有不少錯誤的地方,希望大家指正,(并不是謙虛,我自己也在不斷地改正和完善)!另,照舊,源碼版本是2.6.12

1、模塊的注冊

源碼在ip_conntrack_tftp.c中:
init函數(shù)中定義了
  1. static struct ip_conntrack_helper tftp[MAX_PORTS];
復制代碼
并初始化它,并注冊它:
  1. memset(&tftp[i], 0, sizeof(struct ip_conntrack_helper));
  2. ……
  3. ret=ip_conntrack_helper_register(&tftp[i]);
復制代碼


tftp是一個數(shù)組,最大允許MAX_PORTS個,并且變量ports_c決定其個數(shù),因為它做為注冊時for循環(huán)的終值,目前,只注冊了一個tftp。

tftp是一個ip_conntrack_helper類型,我在后文中,會把它叫做“helper”模塊,也就是說,初始化函數(shù)中,調(diào)用ip_conntrack_helper_register函數(shù)注冊了一個tftp的helper模塊。

在tftp的成員的賦初始化值的時候,我們可以對照理解struct ip_conntrack_helper結(jié)構(gòu)的許多重要的成員:
  1.         tftp[i].tuple.dst.protonum = IPPROTO_UDP;                //協(xié)議
  2.         tftp[i].tuple.src.u.udp.port = htons(ports[i]);                //目標端口,即69,這樣,UDP:69成為認識tftp的唯一標志
  3.         tftp[i].mask.dst.protonum = 0xFF;                        //目標地址掩碼,以及下面一個源端口掩碼,以做比較之用
  4.         tftp[i].mask.src.u.udp.port = 0xFFFF;
  5.         tftp[i].max_expected = 1;                                //最大expect,這是什么東東?后面會詳解
  6.         tftp[i].timeout = 5 * 60; /* 5 minutes */                //超時時間
  7.         tftp[i].me = THIS_MODULE;
  8.         tftp[i].help = tftp_help;                                //這個函數(shù)指針是最重要的東東了,后面再來分析它的具體作用       
復制代碼


ip_conntrack_helper_register函數(shù)實質(zhì)上是把該模塊添加進以全局變量helpers為首的鏈表中去:

  1. int ip_conntrack_helper_register(struct ip_conntrack_helper *me)
  2. {
  3.         BUG_ON(me->timeout == 0);
  4.         WRITE_LOCK(&ip_conntrack_lock);
  5.         list_prepend(&helpers, me);
  6.         WRITE_UNLOCK(&ip_conntrack_lock);

  7.         return 0;
  8. }
復制代碼


OK,tftp的helper模塊被注冊了,它什么時候被調(diào)用?以及它有什么用呢??

回憶在連接跟蹤的初時化時,注冊的兩個鉤子:
/*連接跟蹤初始化時,注冊helper Hook*/
static struct nf_hook_ops ip_conntrack_helper_out_ops = {
        .hook                = ip_conntrack_help,
        .owner                = THIS_MODULE,
        .pf                = PF_INET,
        .hooknum        = NF_IP_POST_ROUTING,
        .priority        = NF_IP_PRI_CONNTRACK_HELPER,        /*此優(yōu)先級比同Hook上的ip_confirm的高*/
};

static struct nf_hook_ops ip_conntrack_helper_in_ops = {
        .hook                = ip_conntrack_help,
        .owner                = THIS_MODULE,
        .pf                = PF_INET,
        .hooknum        = NF_IP_LOCAL_IN,
        .priority        = NF_IP_PRI_CONNTRACK_HELPER,
};

對于中轉(zhuǎn)包過濾來講,我們關(guān)心第一個鉤子,它注冊在NF_IP_POST_ROUTING Hook上,并且,比我們講過的ip_confirm優(yōu)先級要高。
這樣,也就是數(shù)據(jù)包經(jīng)過這個Hook點時,ip_conntrack_help 函數(shù)將被調(diào)用。

2.我的例子
結(jié)合一個實際的tftp傳輸來分析代碼,先來看這個例子(該例取自《TCP/IP詳解卷一》p161)

  1. 1.        192.168.0.1:1106        ->        192.168.1.1:69                udp        19        PRQ        "test1.c"
  2. 2.        192.168.1.1:1077        ->        192.168.0.1:1106        udp        516
  3. 3.        192.168.0.1:1106        ->        192.168.1.1:1077        udp        4
  4. 4.        192.168.1.1:1077        ->        192.168.0.1:1106        udp        454
  5. 5.        192.168.0.1:1106        ->        192.168.1.1:1077        udp        4
復制代碼


第1行,是192.168.0.1發(fā)出了一個“讀請求”,文件名是test1.c;
第2行是,192.168.1.1 回應了讀請求,將文件的數(shù)據(jù),共516字節(jié)發(fā)送給請求者,注意,這里的來源端口不是69,而變成了1077;
第3行是一個回應包
第4,5行類似;

對于第1行,即新請求一個連接,回憶我前一次的描述,連接跟蹤模塊會執(zhí)行以下函數(shù):
在NF_IP_PRE_ROUTING Hook處調(diào)用鉤子函數(shù)ip_conntrack_in,接著進入resolve_normal_ct函數(shù),由于這是個新連接,所以,找不
到與之對應的tuple,于是進入了init_conntrack,初始化一個連接。

  1. static struct ip_conntrack_tuple_hash *
  2. init_conntrack(const struct ip_conntrack_tuple *tuple,
  3.                struct ip_conntrack_protocol *protocol,
  4.                struct sk_buff *skb)
  5. {
  6.         struct ip_conntrack_expect *exp;
  7.        
  8.         ……
  9.         exp = find_expectation(tuple);       

  10.         if (exp) {
  11.                 DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
  12.                         conntrack, exp);
  13.                 /* Welcome, Mr. Bond.  We've been expecting you... */
  14.                 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
  15.                 conntrack->master = exp->master;
  16. #if CONFIG_IP_NF_CONNTRACK_MARK
  17.                 conntrack->mark = exp->master->mark;
  18. #endif
  19.                 nf_conntrack_get(&conntrack->master->ct_general);
  20.                 CONNTRACK_STAT_INC(expect_new);
  21.         } else {
  22.                 conntrack->helper = ip_ct_find_helper(&repl_tuple);

  23.                 CONNTRACK_STAT_INC(new);
  24.         }
  25.         ……
  26. }
復制代碼


exp是一個struct ip_conntrack_expect類型,find_expectation看樣子應該是根據(jù)該數(shù)據(jù)包對應的tuple,查找一個struct ip_conntrack_expect類型的節(jié)點,expect是什么東東?暫時不管它,因為我們目前還沒有提到它,所以,find_expectation什么也查不到,那么接下來那個if...else...則會進入else判斷:

  1. else
  2. {
  3.      conntrack->helper = ip_ct_find_helper(&repl_tuple);
  4.      CONNTRACK_STAT_INC(new);
  5. }
復制代碼


ip_ct_find_helper函數(shù)根據(jù)當前數(shù)據(jù)包對應的repl_tuple,在helpers鏈表中查找是否有相應的helper模塊:
PS:當前數(shù)據(jù)包的tuple是:
192.168.0.1:1106        192.168.1.1:69        udp
則repl_tuple為:
192.168.1.1:69 192.168.0.1:1106 udp

  1. static struct ip_conntrack_helper *ip_ct_find_helper(const struct ip_conntrack_tuple *tuple)
  2. {
  3.         return LIST_FIND(&helpers, helper_cmp,
  4.                          struct ip_conntrack_helper *,
  5.                          tuple);
  6. }
復制代碼


比較函數(shù)是helper_cmp:
  1. static inline int helper_cmp(const struct ip_conntrack_helper *i,
  2.                              const struct ip_conntrack_tuple *rtuple)
  3. {
  4.         return ip_ct_tuple_mask_cmp(rtuple, &i->tuple, &i->mask);
  5. }
復制代碼


實際轉(zhuǎn)向給了ip_ct_tuple_mask_cmp函數(shù):
  1. static inline int ip_ct_tuple_mask_cmp(const struct ip_conntrack_tuple *t,
  2.                                        const struct ip_conntrack_tuple *tuple,
  3.                                        const struct ip_conntrack_tuple *mask)
  4. {
  5.         return !(((t->src.ip ^ tuple->src.ip) & mask->src.ip)
  6.                  || ((t->dst.ip ^ tuple->dst.ip) & mask->dst.ip)
  7.                  || ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all)
  8.                  || ((t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all)
  9.                  || ((t->dst.protonum ^ tuple->dst.protonum)
  10.                      & mask->dst.protonum));
  11. }
復制代碼


對照一下tftp模塊初始化時的helper的各成員值和當前數(shù)據(jù)包repl_tuple(192.168.1.1:69 192.168.0.1:1106 udp),可以發(fā)現(xiàn),最終tftp注冊的helper模塊將被正確地查找出來!
這樣,當前tftp的連接conntrack的helper指針就指向了tftp模塊。這一點非常重要。
  1. conntrack->helper = ip_ct_find_helper(&repl_tuple);
復制代碼


這個數(shù)據(jù)包繼續(xù)前進,當它進入NF_IP_POST_ROUTING Hook點時,會進入ip_conntrack_help函數(shù):

/*根據(jù)數(shù)據(jù)包,查找對應的連接,如果此連接有關(guān)鏈的helper模塊,則調(diào)用help函數(shù)*/
  1. static unsigned int ip_conntrack_help(unsigned int hooknum,
  2.                                       struct sk_buff **pskb,
  3.                                       const struct net_device *in,
  4.                                       const struct net_device *out,
  5.                                       int (*okfn)(struct sk_buff *))
  6. {
  7.         struct ip_conntrack *ct;
  8.         enum ip_conntrack_info ctinfo;

  9.         /* This is where we call the helper: as the packet goes out. */
  10.         ct = ip_conntrack_get(*pskb, &ctinfo);
  11.         if (ct && ct->helper) {
  12.                 unsigned int ret;
  13.                 ret = ct->helper->help(pskb, ct, ctinfo);
  14.                 if (ret != NF_ACCEPT)
  15.                         return ret;
  16.         }
  17.         return NF_ACCEPT;
  18. }
復制代碼


這個函數(shù)只有一件事,就是發(fā)現(xiàn)了tftp的這個連接(192.168.0.1:1106        192.168.1.1:69        udp),有相應的helper模塊,于是,調(diào)用helper模塊的help函數(shù),于是,我們再回來看ip_conntrack_tftp.c中,這個help函數(shù)的實現(xiàn):
  1. static int tftp_help(struct sk_buff **pskb,
  2.                      struct ip_conntrack *ct,
  3.                      enum ip_conntrack_info ctinfo)
  4. {
  5.         struct tftphdr _tftph, *tfh;
  6.         struct ip_conntrack_expect *exp;
  7.         unsigned int ret = NF_ACCEPT;

  8.         tfh = skb_header_pointer(*pskb,
  9.                                  (*pskb)->nh.iph->ihl*4+sizeof(struct udphdr),
  10.                                  sizeof(_tftph), &_tftph);
  11.         if (tfh == NULL)
  12.                 return NF_ACCEPT;

  13.         switch (ntohs(tfh->opcode)) {
  14.         /* RRQ and WRQ works the same way */
  15.         case TFTP_OPCODE_READ:
  16.         case TFTP_OPCODE_WRITE:
  17.                 DEBUGP("");
  18.                 DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
  19.                 DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);

  20.                 exp = ip_conntrack_expect_alloc();
  21.                 if (exp == NULL)
  22.                         return NF_DROP;

  23.                 exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
  24.                 exp->mask.src.ip = 0xffffffff;
  25.                 exp->mask.dst.ip = 0xffffffff;
  26.                 exp->mask.dst.u.udp.port = 0xffff;
  27.                 exp->mask.dst.protonum = 0xff;
  28.                 exp->expectfn = NULL;
  29.                 exp->master = ct;

  30.                 DEBUGP("expect: ");
  31.                 DUMP_TUPLE(&exp->tuple);
  32.                 DUMP_TUPLE(&exp->mask);
  33.                 if (ip_nat_tftp_hook)
  34.                         ret = ip_nat_tftp_hook(pskb, ctinfo, exp);
  35.                 else if (ip_conntrack_expect_related(exp) != 0) {
  36.                         ip_conntrack_expect_free(exp);
  37.                         ret = NF_DROP;
  38.                 }
  39.                 break;
  40.         case TFTP_OPCODE_DATA:
  41.         case TFTP_OPCODE_ACK:
  42.                 DEBUGP("Data/ACK opcode\n");
  43.                 break;
  44.         case TFTP_OPCODE_ERROR:
  45.                 DEBUGP("Error opcode\n");
  46.                 break;
  47.         default:
  48.                 DEBUGP("Unknown opcode\n");
  49.         }
  50.         return NF_ACCEPT;
  51. }
復制代碼


這個函數(shù)很簡單,它只關(guān)注tftp操作碼的讀和寫,發(fā)現(xiàn),如果是這兩個操作碼的話,就先分配一個struct ip_conntrack_expect結(jié)構(gòu):
  1.         exp = ip_conntrack_expect_alloc();
復制代碼


然后,初始化它:
  1.         exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
  2.         exp->mask.src.ip = 0xffffffff;
  3.         exp->mask.dst.ip = 0xffffffff;
  4.         exp->mask.dst.u.udp.port = 0xffff;
  5.         exp->mask.dst.protonum = 0xff;
  6.         exp->expectfn = NULL;
  7.         exp->master = ct;
復制代碼


最后,將它注冊:
  1.         ip_conntrack_expect_related(exp) != 0
復制代碼

       
是到了解釋expect的時候了:
        對于tftp來講,它的請求連接是:
        192.168.0.1:1106        ->        192.168.1.1:69                udp
        我們希望它同其它普通協(xié)議一樣,應答包是:
        192.168.1.1:69        ->        192.168.0.1:1106        udp
        而不是:
        192.168.1.1:1077        ->        192.168.0.1:1106        udp
       
所以,這個expect就用來存儲,該連接所“期望”的應答包,僅此而已,這也是給它的成員tuple初始化時,初始化的是當前連接的應答的tuple的原因:
  1. exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
復制代碼

后面的那些mask,用于比較用。master指針讓expect指向了當前連接。

至于注冊,它與注冊helper一樣,是一個插入鏈表的過程:

  1. int ip_conntrack_expect_related(struct ip_conntrack_expect *expect)
  2. {
  3.         struct ip_conntrack_expect *i;
  4.         int ret;

  5.         DEBUGP("ip_conntrack_expect_related %p\n", related_to);
  6.         DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple);
  7.         DEBUGP("mask:  "); DUMP_TUPLE(&expect->mask);

  8.         WRITE_LOCK(&ip_conntrack_lock);
  9.         list_for_each_entry(i, &ip_conntrack_expect_list, list) {
  10.                 if (expect_matches(i, expect)) {
  11.                         /* Refresh timer: if it's dying, ignore.. */
  12.                         if (refresh_timer(i)) {
  13.                                 ret = 0;
  14.                                 /* We don't need the one they've given us. */
  15.                                 ip_conntrack_expect_free(expect);
  16.                                 goto out;
  17.                         }
  18.                 } else if (expect_clash(i, expect)) {
  19.                         ret = -EBUSY;
  20.                         goto out;
  21.                 }
  22.         }

  23.         /* Will be over limit? */
  24.         if (expect->master->helper->max_expected &&
  25.             expect->master->expecting >= expect->master->helper->max_expected)
  26.                 evict_oldest_expect(expect->master);

  27.         ip_conntrack_expect_insert(expect);
  28.         ret = 0;
  29. out:
  30.         WRITE_UNLOCK(&ip_conntrack_lock);
  31.         return ret;
  32. }
復制代碼

首先看是否已經(jīng)有相應節(jié)點,如沒有,則插入之,不同的是,這次的鏈表首部是ip_conntrack_expect_list。

OK,數(shù)據(jù)包
192.168.0.1:1106        ->        192.168.1.1:69                udp
接下來就進入ip_confirm,然后離開本機。

當回來的數(shù)據(jù)傳輸?shù)陌M入Netfliter:
  1. 192.168.1.1:1077        ->        192.168.0.1:1106        udp
復制代碼


因為端口已經(jīng)變成了1077,而不是69,所以它不會同第一條連接的repl_tuple匹配(廢話,當然不匹配了,否則還用搞這么復雜),所以,當然沒有屬于它的連接,數(shù)據(jù)包也會進入init_conntrack,初始化一個連接:

  1. static struct ip_conntrack_tuple_hash *
  2. init_conntrack(const struct ip_conntrack_tuple *tuple,
  3.                struct ip_conntrack_protocol *protocol,
  4.                struct sk_buff *skb)
  5. {
  6.         struct ip_conntrack_expect *exp;
  7.        
  8.         ……
  9.         exp = find_expectation(tuple);       

  10.         if (exp) {
  11.                 DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
  12.                         conntrack, exp);
  13.                 /* Welcome, Mr. Bond.  We've been expecting you... */
  14.                 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
  15.                 conntrack->master = exp->master;
  16. #if CONFIG_IP_NF_CONNTRACK_MARK
  17.                 conntrack->mark = exp->master->mark;
  18. #endif
  19.                 nf_conntrack_get(&conntrack->master->ct_general);
  20.                 CONNTRACK_STAT_INC(expect_new);
  21.         } else {
  22.                 conntrack->helper = ip_ct_find_helper(&repl_tuple);

  23.                 CONNTRACK_STAT_INC(new);
  24.         }
  25.         ……
  26. }
復制代碼

這一次,find_expectation函數(shù)根據(jù)當前數(shù)據(jù)包的tuple,查找有沒有對應的expect,很幸運,我們剛才注冊的expect被查到了:
  1. static struct ip_conntrack_expect *
  2. find_expectation(const struct ip_conntrack_tuple *tuple)
  3. {
  4.         struct ip_conntrack_expect *i;

  5.         list_for_each_entry(i, &ip_conntrack_expect_list, list) {
  6.                 /* If master is not in hash table yet (ie. packet hasn't left
  7.                    this machine yet), how can other end know about expected?
  8.                    Hence these are not the droids you are looking for (if
  9.                    master ct never got confirmed, we'd hold a reference to it
  10.                    and weird things would happen to future packets). */
  11.                 if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)
  12.                     && is_confirmed(i->master)
  13.                     && del_timer(&i->timeout)) {
  14.                         unlink_expect(i);
  15.                         return i;
  16.                 }
  17.         }
  18.         return NULL;
  19. }
復制代碼

比較函數(shù)仍然是ip_ct_tuple_mask_cmp,再來看一遍它的代碼:

  1. static inline int ip_ct_tuple_mask_cmp(const struct ip_conntrack_tuple *t,
  2.                                        const struct ip_conntrack_tuple *tuple,
  3.                                        const struct ip_conntrack_tuple *mask)
  4. {
  5.         return !(((t->src.ip ^ tuple->src.ip) & mask->src.ip)
  6.                  || ((t->dst.ip ^ tuple->dst.ip) & mask->dst.ip)
  7.                  || ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all)
  8.                  || ((t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all)
  9.                  || ((t->dst.protonum ^ tuple->dst.protonum)
  10.                      & mask->dst.protonum));
  11. }
復制代碼

回憶初始化tftp的expect時,作為比較用的mask的源端口并沒有被賦值:
  1.                 exp->mask.src.ip = 0xffffffff;
  2.                 exp->mask.dst.ip = 0xffffffff;
  3.                 exp->mask.dst.u.udp.port = 0xffff;
  4.                 exp->mask.dst.protonum = 0xff;
  5.                 exp->expectfn = NULL;
復制代碼

所以,對于這條應答的包來講,盡管它的來源端口是1077,而不是我們希望的69,但
((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all)仍然為0,所以,它仍然被查找出來了。

這樣,Netfilter發(fā)現(xiàn)該連接有對應的expect,哈哈,終于找到你了,于是:
  1. __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
復制代碼


設(shè)置該連接為“關(guān)連”標志位(等回到resolve_normal_ct函數(shù)中,再將此連接設(shè)置為IP_CT_RELATED)
,這樣,關(guān)連的連接就被識別出來了。并且,該連接的master指針,指向了第一條連接:
conntrack->master = exp->master;

主要的流程就這么簡單!!

小結(jié)一下:
首先,特殊的協(xié)議注冊一個helper,helper模塊根據(jù)協(xié)議的某些特性,如(udp & dport==69),“幫助”我們發(fā)現(xiàn)一條連接是“特殊協(xié)議”,于是調(diào)用help函數(shù),初始化一個“期望”連接expect,事實上,這個expect主要的作用僅僅是比較。當回來的應答包穿過Netfilter時,它被發(fā)現(xiàn)有一個expect,于是,它就被識別出來是一個“關(guān)聯(lián)”連接了!

論壇徽章:
0
2 [報告]
發(fā)表于 2006-10-16 11:56 |只看該作者
這個tftp指的不是"Trivial File Transfer Protocol"吧?

論壇徽章:
0
3 [報告]
發(fā)表于 2006-10-16 12:04 |只看該作者
原帖由 albcamus 于 2006-10-16 11:56 發(fā)表
這個tftp指的不是"Trivial File Transfer Protocol"吧?


就是它呀?它與FTP有點類似,應答包會自動打開高端口回應,而不再用69,所以,Linux就需要為它做動態(tài)協(xié)議的連接跟蹤,這篇文章就是借tftp協(xié)議的實現(xiàn)來分析整個連接跟蹤模塊對于動態(tài)協(xié)議跟蹤的實現(xiàn)!

論壇徽章:
0
4 [報告]
發(fā)表于 2006-10-16 13:00 |只看該作者
原帖由 獨孤九賤 于 2006-10-16 12:04 發(fā)表


就是它呀?它與FTP有點類似,應答包會自動打開高端口回應,而不再用69,所以,Linux就需要為它做動態(tài)協(xié)議的連接跟蹤,這篇文章就是借tftp協(xié)議的實現(xiàn)來分析整個連接跟蹤模塊對于動態(tài)協(xié)議跟蹤的實現(xiàn)!


謝謝,還有一個疑問:那為什么tftp需要在內(nèi)核層實現(xiàn)呢?

論壇徽章:
0
5 [報告]
發(fā)表于 2006-10-16 13:32 |只看該作者
原帖由 albcamus 于 2006-10-16 13:00 發(fā)表


謝謝,還有一個疑問:那為什么tftp需要在內(nèi)核層實現(xiàn)呢?


嘻嘻,不是tftp協(xié)議在內(nèi)核實現(xiàn)
是內(nèi)核中實現(xiàn)對tftp協(xié)議的跟蹤和狀態(tài)檢測……
《 Netfliter狀態(tài)跟蹤之動態(tài)協(xié)議的實現(xiàn)淺析(tftp實現(xiàn)) 》,或許這個名字本身讓人誤解,我想表達的意思是“Netfilter中狀態(tài)跟蹤模塊對動態(tài)協(xié)議的實現(xiàn)支持,用tftp協(xié)議的跟蹤實現(xiàn)的代碼來分析”……

論壇徽章:
0
6 [報告]
發(fā)表于 2006-10-16 13:45 |只看該作者

回復 5樓 獨孤九賤 的帖子

謝謝! 偶不熟悉網(wǎng)絡, 見笑了

論壇徽章:
0
7 [報告]
發(fā)表于 2006-10-16 16:53 |只看該作者
good,最近在研究這方面的東西,打算用conntrack實現(xiàn)一個ttl狀態(tài)維持的東西來避免GFW強行插入的reset包,lz這篇文章剛好是最為關(guān)鍵的conntrack代碼分析,謝了。

論壇徽章:
0
8 [報告]
發(fā)表于 2006-10-16 17:43 |只看該作者
原帖由 colddawn 于 2006-10-16 16:53 發(fā)表
good,最近在研究這方面的東西,打算用conntrack實現(xiàn)一個ttl狀態(tài)維持的東西來避免GFW強行插入的reset包,lz這篇文章剛好是最為關(guān)鍵的conntrack代碼分析,謝了。

我記得GFW是同時向客戶端與服務器發(fā)送rst的,只在客戶端避免有用麼?我曾經(jīng)簡單的在客戶端丟掉所有rst,但是服務器端還是關(guān)閉了連接。

論壇徽章:
0
9 [報告]
發(fā)表于 2006-10-16 17:52 |只看該作者
原帖由 mingyanguo 于 2006-10-16 17:43 發(fā)表

我記得GFW是同時向客戶端與服務器發(fā)送rst的,只在客戶端避免有用麼?我曾經(jīng)簡單的在客戶端丟掉所有rst,但是服務器端還是關(guān)閉了連接。

說的沒錯
我曾經(jīng)做過一個實驗,比如用 google 搜索敏感信息,抓包發(fā)現(xiàn)收到了 RST 以及 HTTP/1.0 的正文的第一個包,證明那個 RST 是某個第三者插入的,于是寫了一個 module 來 DROP 所有 RST 包

實驗的結(jié)果和 mingyanguo 說的一樣,雖然 client 的 RST 收不到了,不會馬上彈出無法連接的界面,但是由于 server 已經(jīng) disconnect 了,所以最后超時后提示錯誤

論壇徽章:
0
10 [報告]
發(fā)表于 2006-10-16 18:57 |只看該作者
原帖由 platinum 于 2006-10-16 17:52 發(fā)表

說的沒錯
我曾經(jīng)做過一個實驗,比如用 google 搜索敏感信息,抓包發(fā)現(xiàn)收到了 RST 以及 HTTP/1.0 的正文的第一個包,證明那個 RST 是某個第三者插入的,于是寫了一個 module 來 DROP 所有 RST 包

實驗的結(jié)果 ...


你們說的什么GFW,什么Reset?聽不懂,哪位能否詳細講講?
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP