国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
iptables ipt_do_table


  • 從圖1和圖2中我們可以看清楚linux下防火墻netfilter的運(yùn)作方式,設(shè)有5個(gè)鉤子函數(shù)
    Hook Called...
    NF_IP_PRE_ROUTING After sanity checks, before routing decisions.
    NF_IP_LOCAL_IN After routing decisions if packet is for this host.
    NF_IP_FORWARD If the packet is destined for another interface.
    NF_IP_LOCAL_OUT For packets coming from local processes on their way out.
    NF_IP_POST_ROUTING Just before outbound packets "hit the wire".
    圖1 鉤子函數(shù)

    不同的模塊將會(huì)注冊(cè)不同的鉤子函數(shù),每當(dāng)數(shù)據(jù)包處理到這個(gè)階段時(shí),就調(diào)用模塊中定義的處理函數(shù),而netfilter提供了一個(gè)整體框架,避免了原來(lái)代碼的雜亂無(wú)章。如圖,當(dāng)數(shù)據(jù)包從外部進(jìn)來(lái),首先處理的是PRE_ROUTING,然后轉(zhuǎn)到路由,路由判斷究竟是forward這個(gè)數(shù)據(jù)包還是讀入本機(jī)處理,如果是轉(zhuǎn)發(fā)的,會(huì)進(jìn)入到FORWARD鉤子,如果是讀入處理的,會(huì)到LOCAL_IN鉤子。當(dāng)數(shù)據(jù)包是從本機(jī)發(fā)出的數(shù)據(jù)包時(shí),經(jīng)過LOCAL_OUT鉤子,然后路由判斷。最后FORWARD和LOCAL_OUT都會(huì)經(jīng)過POST_ROUTING鉤子。這樣整個(gè)防火墻的結(jié)構(gòu)就很清晰了,主要由INPUT OUTPUT FORWARD三個(gè)鏈條組成。

    圖2 netfilter處理流程
    我們通過源代碼來(lái)看一下它的實(shí)現(xiàn)。我們首先看一下發(fā)送ip數(shù)據(jù)包到上層的函數(shù)ip_local_deliver(),它所在的文件是net/ipv4/ip_input.c
    261 /*
    262 * Deliver IP Packets to the higher protocol layers.
    263 */
    264 int ip_local_deliver(struct sk_buff *skb)
    265 {
    266 /*
    267 * Reassemble IP fragments.
    268 */
    269
    270 if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
    271 skb = ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER);
    272 if (!skb)
    273 return 0;
    274 }
    275
    276 return NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL,
    277 ip_local_deliver_finish);
    278 }
    我們關(guān)心其中的那個(gè)returen語(yǔ)句,調(diào)用了函數(shù)NF_HOOK,這個(gè)自然就是netfilter的hook調(diào)用。我們發(fā)現(xiàn)這其實(shí)是一個(gè)宏,那么繼續(xù)深入下去看看:
    246 #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \ 
    247 NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN)
    可見它的形參分別是協(xié)議類型,鉤子類型,skb,進(jìn)去的device,出去的device以及回調(diào)函數(shù)指針,它首先會(huì)探尋說(shuō)我們的規(guī)則表中有沒有對(duì)這類情況注冊(cè)鉤子函數(shù)進(jìn)行匹配處理,如果有的話,會(huì)調(diào)用鉤子函數(shù),如果沒有的話,則繼續(xù)執(zhí)行形參中的回調(diào)函數(shù),完成整個(gè)過程??梢妌etfilter是一個(gè)很輕量級(jí)的,和內(nèi)核網(wǎng)絡(luò)代碼能輕易剝離的防火墻。我們繼續(xù)往下看:
    182 /** 
    183 * nf_hook_thresh - call a netfilter hook

    184 *
    185 * Returns 1 if the hook has allowed the packet to pass. The function
    186 * okfn must be invoked by the caller in this case. Any other return

    187 * value indicates the packet has been consumed by the hook.

    188 */

    189
    static inline int nf_hook_thresh(int pf, unsigned int hook,
    190 struct sk_buff **pskb,
    191 struct net_device *indev,
    192 struct net_device *outdev,
    193 int (*okfn)(struct sk_buff *), int thresh,
    194 int cond)
    195 {
    196 if (!cond)
    197 return 1;
    198 #ifndef CONFIG_NETFILTER_DEBUG
    199 if (list_empty(&nf_hooks[pf][hook]))
    200 return 1;
    201 #endif
    202 return nf_hook_slow(pf, hook, pskb, indev, outdev, okfn, thresh);
    203 }
    這里出現(xiàn)了一個(gè)非常重要的數(shù)據(jù)結(jié)構(gòu)nf_hooks,我們?nèi)タ匆幌碌降资窃趺礃幼拥?br>58 struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
    一個(gè)很典型的二維數(shù)組,第一維是協(xié)議類型,第二維是一個(gè)協(xié)議最多的鉤子函數(shù)的數(shù)量。這個(gè)數(shù)組的每一項(xiàng)就是一個(gè)list頭,指向一串有鉤子函數(shù)的鏈表,當(dāng)這個(gè)數(shù)組的這一項(xiàng)為空時(shí),即沒有鉤子函數(shù)掛接時(shí),函數(shù)nf_hook_thresh返回1,也就是直接執(zhí)行okfn函數(shù),否則的話繼續(xù)調(diào)用nf_hook_slow()。
    我們來(lái)看一個(gè)nf_hooks初始化的例子,在net/ipv4/netfilter/iptable_filter.c中的初始化函數(shù)
    142 static int __init iptable_filter_init(void)
    143 {
    144 int ret;
    145
    146
    if (forward < 0 || forward > NF_MAX_VERDICT) {
    147 printk("iptables forward must be 0 or 1\n");
    148 return -EINVAL;
    149 }
    150
    151
    /* Entry 1 is the FORWARD hook */
    152 initial_table.entries[1].target.verdict = -forward - 1;
    153
    154 /* Register table */
    155 ret = ipt_register_table(&packet_filter, &initial_table.repl);
    156 if (ret < 0)
    157 return ret;
    158
    159 /* Register hooks */
    160
    ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops));
    161 if (ret < 0)
    162 goto cleanup_table;
    163
    164 return ret;
    165
    166 cleanup_table:
    167 ipt_unregister_table(&packet_filter);
    168 return ret;
    169 }
    其中的注冊(cè)table和注冊(cè)鉤子函數(shù)就很清晰了,這些都是在初始化時(shí)候完成的。我們繼續(xù)看nf_register_hooks函數(shù),它調(diào)用了nf_register_hook函數(shù)。
     62 int nf_register_hook(struct nf_hook_ops *reg)
    63 {
    64 struct list_head *i;
    65
    66
    spin_lock_bh(&nf_hook_lock);
    67 list_for_each(i, &nf_hooks[reg->pf][reg->hooknum]) {
    68 if (reg->priority < ((struct nf_hook_ops *)i)->priority)
    69 break;
    70 }
    71 list_add_rcu(?->list, i->prev);
    72 spin_unlock_bh(&nf_hook_lock);
    73
    74 synchronize_net();
    75 return 0;
    76 }
    這個(gè)函數(shù)很清楚了,它注冊(cè)一個(gè)數(shù)據(jù)結(jié)構(gòu)到nf_hook_ops的數(shù)據(jù)結(jié)構(gòu)到表nf_hooks中的相應(yīng)位置中去,在list中的位置根據(jù)reg的priority的值,應(yīng)該是數(shù)值越小,優(yōu)先級(jí)越高,就越先處理。而nf_hook_ops的內(nèi)容猜都能猜出來(lái)吧,肯定是鉤子函數(shù)咯。
    我們回到前面的調(diào)用函數(shù)nf_hook_slow那個(gè)地方,看看這個(gè)函數(shù)究竟做什么的。
    161 int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
    162 struct net_device *indev,
    163 struct net_device *outdev,
    164 int (*okfn)(struct sk_buff *),
    165 int hook_thresh)
    166 {
    167 struct list_head *elem;
    168 unsigned int verdict;
    169 int ret = 0;
    170
    171
    /* We may already have this, but read-locks nest anyway */
    172 rcu_read_lock();
    173
    174 elem = &nf_hooks[pf][hook];
    175 next_hook:
    176 verdict = nf_iterate(&nf_hooks[pf][hook], pskb, hook, indev,
    177 outdev, &elem, okfn, hook_thresh);
    178 if (verdict == NF_ACCEPT || verdict == NF_STOP) {
    179 ret = 1;
    180 goto unlock;
    181 } else if (verdict == NF_DROP) {
    182 kfree_skb(*pskb);
    183 ret = -EPERM;
    184 } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
    185 NFDEBUG("nf_hook: Verdict = QUEUE.\n");
    186 if (!nf_queue(pskb, elem, pf, hook, indev, outdev, okfn,
    187 verdict >> NF_VERDICT_BITS))
    188 goto next_hook;
    189 }
    190 unlock:
    191 rcu_read_unlock();
    192 return ret;
    193 }
    我們發(fā)現(xiàn)一個(gè)變量verdict,這個(gè)就是鉤子函數(shù)對(duì)數(shù)據(jù)包的處理結(jié)果,它有以下幾種類型,NF_STOP我也不知道是干嘛的??!
    Return Code Meaning
    NF_DROP Discard the packet.
    NF_ACCEPT Keep the packet.
    NF_STOLEN Forget about the packet.
    NF_QUEUE Queue packet for userspace.
    NF_REPEAT Call this hook function again.
    處理的方式從代碼中可見
    1.是當(dāng)接受和停止時(shí),返回1
    2.丟棄時(shí)釋放內(nèi)存空間
    3.進(jìn)隊(duì)列則為加入隊(duì)列然后繼續(xù)下一個(gè)hook
    我們可以看到其中的中心函數(shù)必定是nf_iterate,它將返回verdict給我們。
    117 unsigned int nf_iterate(struct list_head *head,
    118 struct sk_buff **skb,
    119 int hook,
    120 const struct net_device *indev,
    121 const struct net_device *outdev,
    122 struct list_head **i,
    123 int (*okfn)(struct sk_buff *),
    124 int hook_thresh)
    125 {
    126 unsigned int verdict;
    127
    128
    /*
    129 * The caller must not block between calls to this

    130 * function because of risk of continuing from deleted element.

    131
    */
    132 list_for_each_continue_rcu(*i, head) {
    133 struct nf_hook_ops *elem = (struct nf_hook_ops *)*i;
    134
    135 if (hook_thresh > elem->priority)
    136 continue;
    137
    138 /* Optimization: we don't need to hold module
    139 reference here, since function can't sleep. --RR
    */
    140
    verdict = elem->hook(hook, skb, indev, outdev, okfn);
    141 if (verdict != NF_ACCEPT) {
    142 #ifdef CONFIG_NETFILTER_DEBUG
    143 if (unlikely((verdict & NF_VERDICT_MASK)
    144 > NF_MAX_VERDICT)) {
    145 NFDEBUG("Evil return from %p(%u).\n",
    146 elem->hook, hook);
    147 continue;
    148 }
    149 #endif
    150 if (verdict != NF_REPEAT)
    151 return verdict;
    152 *i = (*i)->prev;
    153 }
    154 }
    155 return NF_ACCEPT;
    156 }

    這下我們應(yīng)該清楚了,這個(gè)迭代就是挨個(gè)運(yùn)行nf_hooks[pf][hook]所指向鏈表中的鉤子函數(shù)elem->hook。

    如果其中有一個(gè)鉤子函數(shù)沒有ACCEPT且不是repeat,就直接跳出循環(huán)了,然后返回verdict,如果ACCEPT了,則繼續(xù)處理下一個(gè)鉤子函數(shù),直到處理完。

     60 struct nf_hook_ops
    61 {
    62 struct list_head list;
    63
    64 /* User fills in from here down. */
    65
    nf_hookfn *hook;
    66 struct module *owner;
    67 int pf;
    68 int hooknum;
    69 /* Hooks are ordered in ascending priority. */
    70 int priority;
    71 };
    我們看看這個(gè)數(shù)據(jù)結(jié)構(gòu),再想想前面注冊(cè)hook時(shí)候的情景,應(yīng)該明白了。它其中定義了pf和hooknum,指定了在nf_hooks表中的元素位置,nf_hookfn則是現(xiàn)實(shí)的鉤子函數(shù),而priority則指定了它在這個(gè)鏈表中的位置,按照升序排列。那么nf_hookfn是什么時(shí)候指定的呢?這個(gè)自然是和各個(gè)協(xié)議相關(guān)的。在net/ipv4/netfilter/iptable_filter.c中,我們看到這么一個(gè)賦值語(yǔ)句。
    114 static struct nf_hook_ops ipt_ops[] = {
    115 {
    116 .hook = ipt_hook,
    117 .owner = THIS_MODULE,
    118 .pf = PF_INET,
    119 .hooknum = NF_IP_LOCAL_IN,
    120 .priority = NF_IP_PRI_FILTER,
    121 },
    122 {
    123 .hook = ipt_hook,
    124 .owner = THIS_MODULE,
    125 .pf = PF_INET,
    126 .hooknum = NF_IP_FORWARD,
    127 .priority = NF_IP_PRI_FILTER,
    128 },
    129 {
    130 .hook = ipt_local_out_hook,
    131 .owner = THIS_MODULE,
    132 .pf = PF_INET,
    133 .hooknum = NF_IP_LOCAL_OUT,
    134 .priority = NF_IP_PRI_FILTER,
    135 },
    136 };
    這是在ipv4的filter中預(yù)先注冊(cè)的,我們知道還有預(yù)先注冊(cè)的像nat和mangle,當(dāng)然我們也可以自己寫模塊,實(shí)現(xiàn)這個(gè)hook函數(shù)。像這個(gè)例子中,第一個(gè)的hook函數(shù)就是ipt_hook,屬于的協(xié)議是ipv4,屬于的鉤子類型是LOCAL_IN。
    說(shuō)實(shí)話ipt_hook以及之后調(diào)用的ipt_do_table我沒有看懂,汗,誰(shuí)看懂了交流一下吧,呵呵! 這周繼續(xù)閱讀netfilter部分的代碼和文檔,看了一下netfilter hacking howto和水木上的m文,對(duì)前一周一些沒有搞懂的問題弄明白了。
    主要的一個(gè)問題是netfilter是在內(nèi)核中,那么它和iptables這個(gè)基于user space的工具怎么交互呢?其實(shí)我們應(yīng)該這么想,netfilter和table是分開實(shí)現(xiàn)的,我們通過協(xié)議類型和掛載點(diǎn)來(lái)找到的在二維數(shù)組nf_hooks的位置上,是一個(gè)鏈表的頭指針,它所指向的這個(gè)鏈表中有對(duì)于這個(gè)特定協(xié)議和特定掛載點(diǎn)的對(duì)于各個(gè)表中規(guī)則的處理,這些表包括像filter,nat和mangle之類的表。我們?cè)谟脩艨臻g中調(diào)用iptables時(shí),我們的參數(shù)為所針對(duì)的table,針對(duì)的處理鏈chain,match的規(guī)則,和最終的處理方式target,而它們中每個(gè)都能在內(nèi)核空間找到對(duì)應(yīng)關(guān)系,像chain針對(duì)的就是掛載點(diǎn)。
    我們重新回到nf_hooks數(shù)組,我們得到一個(gè)處理鏈表,自然進(jìn)行遍歷,在每個(gè)節(jié)點(diǎn)上都調(diào)用hook函數(shù),hook函數(shù)指定為ipt_hook之類的函數(shù),具體需要參照加載的函數(shù),我們只是找出一個(gè)進(jìn)行舉例。ipt_hook調(diào)用ipt_do_table,這個(gè)函數(shù)是對(duì)table進(jìn)行操作的,函數(shù)很長(zhǎng),我們來(lái)看一下。
    215 /* Returns one of the generic firewall policies, like NF_ACCEPT. */
    216 unsigned int
    217 ipt_do_table(struct sk_buff **pskb,
    218 unsigned int hook,
    219 const struct net_device *in,
    220 const struct net_device *out,
    221 struct ipt_table *table,//這個(gè)是我們要操作的table,如filter
    222 void *userdata)
    223 {
    224 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
    225 u_int16_t offset;
    226 struct iphdr *ip;
    227 u_int16_t datalen;
    228 int hotdrop = 0;
    //hotdrop為1時(shí)就直接返回NF_DROP了,這是快速扔包的方法

    229 /* Initializing verdict to NF_DROP keeps gcc happy. */
    230 unsigned int verdict = NF_DROP;
    231 const char *indev, *outdev;
    232 void *table_base;
    233 struct ipt_entry *e, *back;
    234 struct xt_table_info *private = table->private;
    //xt_table_info中蘊(yùn)含了整套規(guī)則,以及這些規(guī)則的偏移量,使尋找變得容易

    235
    236 /* Initialization */
    237 ip = (*pskb)->nh.iph;
    238 datalen = (*pskb)->len - ip->ihl * 4;
    239 indev = in ? in->name : nulldevname;
    240 outdev = out ? out->name : nulldevname;
    241 /* We handle fragments by dealing with the first fragment as
    242 * if it was a normal packet. All other fragments are treated
    243 * normally, except that they will NEVER match rules that ask
    244 * things we don't know, ie. tcp syn flag or ports). If the
    245 * rule is also a fragment-specific rule, non-fragments won't
    246 * match it. */
    247 offset = ntohs(ip->frag_off) & IP_OFFSET;
    248
    249 read_lock_bh(&table->lock);
    250 IP_NF_ASSERT(table->valid_hooks & (1 << hook));
    251 table_base = (void *)private->entries[smp_processor_id()];
    252 e = get_entry(table_base, private->hook_entry[hook]);
    //得到這個(gè)hook點(diǎn)起始規(guī)則的偏移

    253
    254 /* For return from builtin chain */
    255 back = get_entry(table_base, private->underflow[hook]);
    //得到這個(gè)hook點(diǎn)規(guī)則末尾的偏移

    256
    257 do {
    258 IP_NF_ASSERT(e);
    259 IP_NF_ASSERT(back);
    260 if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) {
    261 struct ipt_entry_target *t;
    262
    263 if (IPT_MATCH_ITERATE(e, do_match,
    264 *pskb, in, out,
    265 offset, &hotdrop) != 0)
    //這個(gè)宏用來(lái)遍歷所有的match,會(huì)調(diào)用do_match函數(shù)
    266 goto no_match;
    //如果沒有匹配的規(guī)則,則跳轉(zhuǎn)到no_match

    267
    268 ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
    269
    270 t = ipt_get_target(e);//獲得target
    271 IP_NF_ASSERT(t->u.kernel.target);
    272 /* Standard target? */
    273 if (!t->u.kernel.target->target) {
    //當(dāng)為NULL時(shí),就是standard target,它是沒有模塊定義target函數(shù)的
    274 int v;
    275
    276 v = ((struct ipt_standard_target *)t)->verdict;
    277 if (v < 0) {
    278 /* Pop from stack? */
    279 if (v != IPT_RETURN) {
    280 verdict = (unsigned)(-v) - 1;
    281 break;
    282 }
    283 e = back;
    284 back = get_entry(table_base,
    285 back->comefrom);
    286 continue;
    287 }
    288 if (table_base + v != (void *)e + e->next_offset
    289 && !(e->ip.flags & IPT_F_GOTO)) {
    290 /* Save old back ptr in next entry */
    291 struct ipt_entry *next
    292 = (void *)e + e->next_offset;
    293 next->comefrom
    294 = (void *)back - table_base;
    295 /* set back pointer to next entry */
    296 back = next;
    297 }
    298
    299 e = get_entry(table_base, v);
    300 } else {
    301 /* Targets which reenter must return
    302 abs. verdicts */
    303 #ifdef CONFIG_NETFILTER_DEBUG
    304 ((struct ipt_entry *)table_base)->comefrom
    305 = 0xeeeeeeec;
    306 #endif
    307 verdict = t->u.kernel.target->target(pskb,
    308 in, out,
    309 hook,
    310 t->u.kernel.target,
    311 t->data,
    312 userdata);
    //調(diào)用模塊中定義的target函數(shù),返回一個(gè)verdict

    313
    314 #ifdef CONFIG_NETFILTER_DEBUG
    315 if (((struct ipt_entry *)table_base)->comefrom
    316 != 0xeeeeeeec
    317 && verdict == IPT_CONTINUE) {
    318 printk("Target %s reentered!\n",
    319 t->u.kernel.target->name);
    320 verdict = NF_DROP;
    321 }
    322 ((struct ipt_entry *)table_base)->comefrom
    323 = 0x57acc001;
    324 #endif
    325 /* Target might have changed stuff. */
    326 ip = (*pskb)->nh.iph;
    327 datalen = (*pskb)->len - ip->ihl * 4;
    328
    329 if (verdict == IPT_CONTINUE)
    330 e = (void *)e + e->next_offset;
    331 else
    332 /* Verdict */
    333 break;
    334 }
    335 } else {
    336
    337 no_match:
    338 e = (void *)e + e->next_offset;
    //如果沒有匹配,則找到下一個(gè)ipt_entry
    339 }
    340 } while (!hotdrop);
    341
    342 read_unlock_bh(&table->lock);
    343
    344 #ifdef DEBUG_ALLOW_ALL
    345 return NF_ACCEPT;
    346 #else
    347 if (hotdrop)
    348 return NF_DROP;
    349 else return verdict;
    350 #endif
    351 }
    做一些基本的注釋,其實(shí)我不喜歡一篇技術(shù)博客長(zhǎng)篇累牘貼代碼,尤其是Linux內(nèi)核源代碼,更多的是希望能夠進(jìn)行分析。但往往越是討厭的事情,自己往往又這么做了。好吧,還是來(lái)解釋一下這個(gè)函數(shù)吧。
    它是對(duì)table進(jìn)行操作,至于對(duì)于哪個(gè)table,是由調(diào)用函數(shù)決定的。調(diào)用之后,他的主要工作如下:
    1.找到table的地址,其實(shí)重要的是找到ipt_entry的地址,因?yàn)槔锩娲嬷鴐atch和target。
    2.對(duì)match進(jìn)行匹配,如果匹配成功,則獲取target。如果失敗,跳轉(zhuǎn)到no_match,找到下一個(gè)ipt_entry,進(jìn)行下一輪匹配。
    3.成功的話會(huì)有兩種情況,一是得到初始化時(shí)候的standard target,這時(shí)候target函數(shù)是初始化為NULL的。二是得到一個(gè)由用戶新加的target,跟據(jù)verdict和hotdrop,來(lái)決定是怎么返回。
    這邊有一點(diǎn)需要指出的是,match的匹配原則是如果這個(gè)數(shù)據(jù)包都匹配了,則不再進(jìn)行比較,直接可以返回了,只有在no match的情況下才繼續(xù)匹配下一條match。這個(gè)和在上文提到的nf_iterate中的處理方式不同,這個(gè)要小心區(qū)分的。在同一張表中,是只要匹配就返回verdict,而在nf_iterate 調(diào)用鉤子函數(shù)處理中,如果是ACCEPT的情況,則需要繼續(xù)處理。天哪,其實(shí)這個(gè)貌似沒有什么特別的聯(lián)系,只是我自己混淆了一開始,我想大家應(yīng)該不會(huì)像我 這樣犯這么低級(jí)的錯(cuò)誤,寫出來(lái)算是警戒一下自己。

    剛才做了個(gè)實(shí)驗(yàn),驗(yàn)證了一下。
    實(shí)驗(yàn)一:
    sudo iptables -t filter -A INPUT -j ACCEPT -p tcp
    sudo iptables -t filter -A INPUT -j DROP -p tcp -s hk-in-f104.google.com
    這時(shí)候是能訪問google的,因?yàn)閿?shù)據(jù)包進(jìn)入鉤子函數(shù)之后只匹配了第一條就返回了,第二條規(guī)則是沒有意義的。

    實(shí)驗(yàn)二:
    sudo iptables -t filter -A INPUT -j DROP -p tcp -s hk-in-f104.google.com
    sudo iptables -t filter -A INPUT -j DROP -p tcp
    這時(shí)候不能訪問任何網(wǎng)站,因?yàn)間oogle以外任意一個(gè)網(wǎng)站第一條不匹配,則進(jìn)入下一條,然后drop掉,google則第一條就不匹配,直接drop。

    這個(gè)在ip_do_table的源代碼里面就很清楚了。至于表示table的那些源代碼,真的是看了厥倒,這種匪夷所思的數(shù)據(jù)結(jié)構(gòu),這些hacker們還膽子真夠大的,真不怕內(nèi)存讀寫錯(cuò)誤啊,要是我我可不敢這么寫,他們果然是藝高人膽大,這個(gè)下次再分析吧,今天還算是差不多搞清楚了。


本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Linux netfilter源碼分析
netfilter: Linux 防火墻在內(nèi)核中的實(shí)現(xiàn)
netfilter整體架構(gòu)解析初步
Linux中Netfilter的原理介紹
netfilter中iptables表的實(shí)現(xiàn)
linux實(shí)現(xiàn)流量監(jiān)控的幾種方法
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服