[pso] [Tema4][Linux]NU incepeti tema inainte sa cititi ASTA

Andrei Popa ca at i-neo.ro
Wed May 30 00:05:06 EEST 2007


On Sun, 2007-05-20 at 18:30 +0300, Razvan Deaconescu wrote:
> sorin gsmcreation wrote:
> > Salutare!
> > 
> > Dupa ceva timp am reusit sa descoperim (Razvan de
> > fapt) motivul comportarii ciudate a hook-ului de
> > input. 
> > Problema era ca in acest hook, cand citeam portul
> > sursa si destinatie al oricarui pachet, fie el
> > TCP/UDP, valorile acestor porturi erau corupte. 
> > 
> > Asta pentru ca nu obtineam ok pointerii catre
> > headerele tcp si udp (foloseam metoda initiala din
> > laboratorul de networking). Partea ciudata e ca in
> > hook-ul de output mergea sa obtinem headerele ca in
> > laborator; doar la input se comporta ciudat.
> > 
> > Solutia care merge este:
> > struct iphdr *iph = (*skb)->nh.iph;
> > struct tcphdr *tcph = (struct tcphdr *) ((*skb)->data
> > + iph->ihl * 4);
> > struct udphdr *udph = (struct udphdr *) ((*skb)->data
> > + iph->ihl * 4);
> 
> se pare ca pe hook-ul de in (NF_LOCAL_IN), subsistemul de networking nu 
> "dezasambleaza" antetul TCP/UDP in campurile (*skb)->h.th, respectiv 
> (*skb)->h.uh
> 
> la hook-ul de out (NF_LOCAL_OUT), dezasamblarea este realizata corect si 
> totul merge OK daca se folosesc (*skb)->h.th/(*skb)->h.uh
> 

pachetul cand vine, prima oara este trecut prin ip_input.c si se
apeleaza functiile de hooking NF_IP_LOCAL_IN si dupa asta este pasat
layer-ului TCP/UDP.
din aceasta cauza campurile pt. TCP/UDP din skb nu sunt setate bine in hooking-ul NF_IP_LOCAL_IN. 
cand un pachet pleaca, pleaca din layerele TCP/UDP unde i se seteaza campurile pt. TCP/UDP din skb
si dupa asta este trimis la ip_output.c care apeleaza functiile de hooking pt. NF_IP_LOCAL_OUT si astfel
campurile sunt setate bine.

explicatia mai tehnica:
filtrele NF_IP_LOCAL_IN si NF_IP_LOCAL_OUT sunt apelate in ip_input.c si
ip_output.c

INPUT( cand un pachet vine):

http://lxr.linux.no/source/net/ipv4/ip_input.c#L263
//hook-ul pt. NF_IP_LOCAL_IN este apelat in ip_local_deliver()
return NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL,  ip_local_deliver_finish);

//dupa care este apelata functia ip_local_deliver_finish()
http://lxr.linux.no/source/net/ipv4/ip_input.c#L199
//unde
http://lxr.linux.no/source/net/ipv4/ip_input.c#L214
struct net_protocol *ipprot;
if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) {
ret = ipprot->handler(skb); //se apeleaza defapt functia tcp_v4_rcv()

http://lxr.linux.no/source/net/ipv4/af_inet.c#L1289
//se inregistreaza functia care sa fie apelata pt. acest protocol
static struct net_protocol tcp_protocol = {
         .handler =      tcp_v4_rcv,
         .err_handler =  tcp_v4_err,
         .gso_send_check = tcp_v4_gso_send_check,
         .gso_segment =  tcp_tso_segment,
         .no_policy =    1,
};
// se vede ca .handler =      tcp_v4_rcv,
//functia tcp_v4_rcv este definita in
http://lxr.linux.no/source/net/ipv4/tcp_ipv4.c#L1611
deci pachetul este trimis layerului TCP/UDP abia dupa ce au fost aplicate functiile
de filtrare din NF_IP_LOCAL_IN si din cauza asta nu are campurile skb->h.th si
skb->h.uh setate bine (aceste campuri le seteaza TCP/UDP-ul)

OUTPUT( cand un pachet pleaca):

in functia tcp_transmit_skb() se creeaza pachetul TCP/IP pt. a fi transmis,
fiindui setata si portul sursa si portul destinatie:
http://lxr.linux.no/source/net/ipv4/tcp_output.c#L468

http://lxr.linux.no/source/net/ipv4/tcp_output.c#L544
err = icsk->icsk_af_ops->queue_xmit(skb, 0); //se apeleaza aceasta functie

http://lxr.linux.no/source/net/ipv4/tcp_ipv4.c#L1807
.queue_xmit        = ip_queue_xmit, //defapt este apelata functia ip_queue_xmit

http://lxr.linux.no/source/net/ipv4/ip_output.c#L284
este definita functia int ip_queue_xmit(struct sk_buff *skb, int ipfragok){}
care deja este in ip_output.c si care apeleaza hook-ul pt. NF_IP_LOCAL_OUT
return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output);
deci pachetul cand pleaca prima oara este creat de layer-ul TCP/UDP care ii seteaza
campurile kb->h.th si skb->h.uh si abia dupa asta este filtrat de NF_IP_LOCAL_OUT.


-- 
Andrei Popa - 341C3



More information about the pso mailing list