[pso] netfilter si promiscuous mode

Bogdan Tenea tenea.bogdan at gmail.com
Tue Jul 7 02:30:36 EEST 2009


M-am prins pana la urma ce sugera documentul mentionat anterior: pentru
capturarea pachetelor in modul promiscuous se creeaza un nou packet handler
pentru IP, i se asocieaza o functie de primire care primeste doar pachete
promiscouous (cel mai simplu o copie a ip_rcv cu conditia din precedentul
email inversata) si se inregistreaza respectivul packet handler. Am trecut
mai jos solutia completa, poate o sa mai ajute la un moment dat pe cineva
si-l fereste de cateva nopti pierdure aiurea :)

*// Dummy next call on stack function to drop al promiscuous packets
static int tam_rcv_finish(struct sk_buff *skb){
    kfree_skb(skb);
    return NET_RX_DROP;
}

// Copied from ip_rcv function in the linux kernel source
int tam_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type
*pt, struct net_device *orig_dev){
    struct iphdr *iph;
    u32 len;

    /* Only look out for promiscous packets that the main ip_rcv function
discards */
    if (skb->pkt_type != PACKET_OTHERHOST)
        goto drop;

    IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INRECEIVES);

    if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
        IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS);
        goto out;
    }

    if (!pskb_may_pull(skb, sizeof(struct iphdr)))
        goto inhdr_error;

    iph = ip_hdr(skb);

    /*
     *    RFC1122: 3.2.1.2 MUST silently discard any IP frame that fails the
checksum.
     *
     *    Is the datagram acceptable?
     *
     *    1.    Length at least the size of an ip header
     *    2.    Version of 4
     *    3.    Checksums correctly. [Speed optimisation for later, skip
loopback checksums]
     *    4.    Doesn't have a bogus length
     */

    if (iph->ihl < 5 || iph->version != 4)
        goto inhdr_error;

    if (!pskb_may_pull(skb, iph->ihl*4))
        goto inhdr_error;

    iph = ip_hdr(skb);

    if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
        goto inhdr_error;

    len = ntohs(iph->tot_len);
    if (skb->len < len) {
        IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INTRUNCATEDPKTS);
        goto drop;
    } else if (len < (iph->ihl*4))
        goto inhdr_error;

    /* Our transport medium may have padded the buffer out. Now we know it
     * is IP we can trim to the true length of the frame.
     * Note this now means skb->len holds ntohs(iph->tot_len).
     */
    if (pskb_trim_rcsum(skb, len)) {
        IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS);
        goto drop;
    }

    /* Remove any debris in the socket control block */
    memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));

    return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, dev, NULL,
             tam_rcv_finish);

inhdr_error:
    IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INHDRERRORS);
drop:
    kfree_skb(skb);
out:
    return NET_RX_DROP;
}

// Structure for registring the promiscuous packet handler
static struct packet_type tam_packet_type = {
    .type    = __constant_htons(ETH_P_IP),
    .func    = tam_rcv,
    .dev    = NULL,
};

dev_add_pack(&tam_packet_type);*

2009/6/25 Bogdan Tenea <tenea.bogdan at gmail.com>

> M-am uitat mai atent la ebtables si in lipsa unei documentatii sau a unor
> exemple de urilizare m-am lasat pagubas.
>
> Am gasit urmatorul document [1] in care se explica destul de clar ce se
> intampla la trecerea prin kernel a unui pachet si am ajuns sa modific
> function ip_rcv din net/ipv4/ip_input.c ca sa nu mai imi dea drop la
> pachetele promisc:
>
>  <https://cs.pub.ro/%7Epso/lxrng/linux/net/ipv4/ip_input.c#L386>        // if (skb <https://cs.pub.ro/%7Epso/lxrng/linux/+code=skb>->pkt_type <https://cs.pub.ro/%7Epso/lxrng/linux/+code=pkt_type> == PACKET_OTHERHOST <https://cs.pub.ro/%7Epso/lxrng/linux/+code=PACKET_OTHERHOST>)
>  <https://cs.pub.ro/%7Epso/lxrng/linux/net/ipv4/ip_input.c#L387>        //        goto drop <https://cs.pub.ro/%7Epso/lxrng/linux/+code=drop>;
>
> Ma mint ca e o solutie temporara insa parca vad ca o sa ramana asa :)
>
> [1]
> http://www.net.t-labs.tu-berlin.de/talks/2006-09-12-pronchev-slides.pdf
>
>
> 2009/6/24 Bogdan Tenea <tenea.bogdan at gmail.com>
>
>> Dupa mai multe sapaturi am gasit si eu acea specificare. Am gasit si
>> patchul dar as vrea sa fac o chestie care sa mearga pur si simplu fara sa ma
>> apuc sa recompilez kernelu.
>>
>> Am incercat sa dau strace pt iptables si pare destul de criptic. Dar, in
>> cel mai rau caz e si asta o solutie. Momentan am gasit ebtables<https://cs.pub.ro/%7Epso/lxrng/linux/net/bridge/netfilter/ebtables.c>care din cate inteleg e un fel de netfilter la nivel de ethernet (e o
>> limitare dar momentan nu e atat de neplacuta). Revin cu detalii daca il
>> reusesc sa-l conving sa si mearga :)
>>
>> 2009/6/24 Octavian Voicu <octavian.voicu at gmail.com>
>>
>> Prin netfilter in mod normal nu se poate; primul hook (cronologic) e dupa
>>> ce sunt dropped pachetele nedestinate hostului:
>>>
>>> /* IP Hooks */
>>> /* After promisc drops, checksum checks. */
>>> #define NF_IP_PRE_ROUTING    0
>>>
>>> Presupun ca ai gasit patchul<http://caia.swin.edu.au/cv/szander/netfilter.html>care adauga un hook nou pentru promiscuous mode.
>>>
>>> Alta varianta e sa folosesti raw sockets, cum functioneaza si tcpdump
>>> (care merge prin libpcap, library user space pt captura de pachete), dar
>>> implementat cu sockets la nivel de kernel (probabil ceva mai complicat).
>>>
>>> Daca dai un `strace tcpdump` poti sa vezi ce fel de socket trebuie creat
>>> si cum selectezi interfata pe care asculta. Check out si man packet<http://linux.die.net/man/7/packet>
>>> .
>>>
>>>
>>>
>>> 2009/6/24 Bogdan Tenea <tenea.bogdan at gmail.com>
>>>
>>>>  Salut
>>>>
>>>> Incerc sa fac un modul care sa analizeze niste pachete de pe retea care
>>>> nu sunt destinate hostului pe care ruleaza. Am pus interfetele in  modul
>>>> promiscous, traficul ajunge pe ele ca vad contotorul pentru interfata
>>>> mergand, traficul apre in iptraf iar daca dau tcpdump pe interfata
>>>> respectiva se vede foarte clar dar nu-mi dau seama din ce motiv pachetele
>>>> nu  ajung in hooku de netfilter. Mentionez ca l-am inserat in prerouting cu
>>>> NF_IP_PRI_FIRST si ca pentru pachetele destinate hostului respective merge.
>>>> Am cautat pe net si primele chestii gasite sunt legate de un patch de
>>>> kernel care sa faca netfilter sa accepte si acele pachete, insa caut o
>>>> solutie mai eleganta :)
>>>>
>>>> Pls help :)
>>>>
>>>> Multumesc,
>>>> Bogdan
>>>>
>>>> _______________________________________________
>>>> pso mailing list
>>>> pso at cursuri.cs.pub.ro
>>>> http://cursuri.cs.pub.ro/cgi-bin/mailman/listinfo/pso
>>>>
>>>>
>>>
>>>
>>> --
>>> Octavian Voicu
>>>
>>> _______________________________________________
>>> pso mailing list
>>> pso at cursuri.cs.pub.ro
>>> http://cursuri.cs.pub.ro/cgi-bin/mailman/listinfo/pso
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cursuri.cs.pub.ro/pipermail/pso/attachments/20090707/b05e9ebc/attachment-0001.htm>


More information about the pso mailing list