ipfw防火墙和IP fragmentation

JavaGG 发布于 2009/06/15 22:44
阅读 440
收藏 0

 
最近因为要做防火墙相关的一些东西,看了一下ipfw,发现它被调用是在IP分片重组之前的,直接在交给IP层处理之前就做了过滤:
ether_input -> ether_demux -> ether_ipfw_chk -> ip_fw_chk_ptr [ipfw_chk]


处理之后如果需要往下走,才进行协议分析并调用netisr_dispatch交给协议栈处理。在ipfw_chk函数中对于分片的第一个分片直接确认它至少有一个L4的协议头,否则就失败了:
#define PULLUP_TO(len, p, T)                        \
do {                                    \
    int x = (len) + sizeof(T);                    \
    if ((m)->m_len < x) {                        \
        args->m = m = m_pullup(m, x);                \
        if (m == NULL)                        \
            goto pullup_failed;                \
    }                                \
    p = (mtod(m, char *) + (len));                    \
} while (0)
 

        if (offset == 0) {
            switch (proto) {
            case IPPROTO_TCP:
                PULLUP_TO(hlen, ulp, struct tcphdr);
                dst_port = TCP(ulp)->th_dport;
                src_port = TCP(ulp)->th_sport;
                args->f_id.flags = TCP(ulp)->th_flags;
                break;
 


可以看出如果长度不够就直接跳到最后返回IP_FW_DENY了,而在外面直接DROP掉了。

协议有没有规定IP分片对于有L4协议的一定要包含一个完整的L4协议头?好像没看到哪有明确说法。


同时也看了一下pf的代码,感觉比较难看懂,因为没啥注释;不过也算找到大概怎么调的了,它也是在IP重组之前进行检测的,不过看代码好像自己试图做分片的处理,在pf_test中有如下处理:
    /* We do IP header normalization and packet reassembly here */
    if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) {
        action = PF_DROP;
        goto done;
    }
    m = *m0;
    h = mtod(m, struct ip *);

    off = h->ip_hl << 2;
    if (off < (int)sizeof(*h)) {
        action = PF_DROP;
        REASON_SET(&reason, PFRES_SHORT);
        log = 1;
        goto done;
    }

    pd.src = (struct pf_addr *)&h->ip_src;
    pd.dst = (struct pf_addr *)&h->ip_dst;
    PF_ACPY(&pd.baddr, dir == PF_OUT ? pd.src : pd.dst, AF_INET);
    pd.ip_sum = &h->ip_sum;
    pd.proto = h->ip_p;
    pd.af = AF_INET;
    pd.tos = h->ip_tos;
    pd.tot_len = ntohs(h->ip_len);
    pd.eh = eh;

    /* handle fragments that didn't get reassembled by normalization */
    if (h->ip_off & htons(IP_MF | IP_OFFMASK)) {
        action = pf_test_fragment(&r, dir, kif, m, h,
            &pd, &a, &ruleset);
        goto done;
    }

    switch (h->ip_p) {

    case IPPROTO_TCP: {
 

 

Linux的netfilter对于local in倒是在协议栈重组之后检测的。 

加载中
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部