<div dir="ltr">2013/5/14 Vlad Dogaru <span dir="ltr"><<a href="mailto:ddvlad@herebedragons.ro" target="_blank">ddvlad@herebedragons.ro</a>></span><br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div class="im">On Tue, May 14, 2013 at 06:08:51PM +0300, Dan Filimon wrote:<br>
> În af_packet.c, există mai multe funcții care par să facă aproape același<br>
> lucru... să primească date.<br>
><br>
> Există packet_rcv și packet_recvmsg.<br>
><br>
> 1. packet_rcv e pusă în câmpul prot_hook.func ca și handler.<br>
> 2. Apoi, packet_recvmsg e funcția care e efectiv apelată la un receive.<br>
><br>
> Întrebările:<br>
><br>
> 1. Au prototipuri diferite și par să facă lucruri diferite, dar la<br>
> implementările mele, handlerul, prot_hook.func (numit stp_rcv) nu pare să<br>
> fie apelat niciodată.<br>
><br>
> Din ce-am înțeles handlerul ar trebui apelat de kernel când primește un<br>
> pachet de acel tip.<br>
> Curios e că am adăugat hook-ul pentru ambii sockeți (am printat un mesaj<br>
> după instrucțiune) dar nu se apelează niciodată handler-ul. De ce?<br>
<br>
</div>Nu știu ce înseamnă "am adăugat hook-ul pentru ambii sockeți".<br>
Structura packet_type (care are .func = stp_rcv) trebuie înregistrată o<br>
singură dată, la inserarea modulului.<br></blockquote><div><br></div><div style>Așa credeam și eu după ce-am citit inițial tema. Apoi, am văzut în codul af_packet.c [1] că se execută la fiecare packet_create() (acolo creeându-se sockeții packet).</div>

<div style>Ar trebui deci să înregistrez o singură dată I guess...</div><div style><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


<br>
După înregistrarea corectă, orice frame cu Ethertype == .type-ul pe care<br>
l-ai pus tu în packet_type (care trebuie să fie ETH_P_STP) ajunge în<br>
.func-ul tău. </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div class="im">
> 2. La recvmsg, eroarea pe care o primesc de la skb_recv_datagram() este<br>
> -512, -ERESTARTSYS.<br>
> Deci, ar trebui re-apelată... cu alți parametri poate?<br>
<br>
</div>stp_recv trebuie să parseze headerul de nivel STP (și să se uite și la<br>
MAC-uri, probabil) pentru a căuta cărui socket trebuie să îi trimită<br>
fiecare skb.  După ce găsești sock-ul, trimiți skb-ul către el folosind<br>
sock_queue_rcv_skb.<br></blockquote><div><br></div><div style>Deci, .func-ul e responsabil pentru apelul sock_queue_rcv_skb() care să pună pachetul în coada socket-ului care trebuie. Singurul apel de sock_queue_rcv_skb() în af.packet e la [2], în packet_rcv_skb, care un .func.</div>

<div style><br></div><div style>stp_recv e func-ul în ce-ai descris, right?</div><div style><br></div><div style>Pe urmă stp_recvmsg (altă funcție!) care e din proto_ops va lua mesajul din coadă și-l copiază într-un iovec și-l trimite mai sus.</div>

<div> </div></div></div><div class="gmail_extra">[1] <a href="http://lxr.linux.no/linux+v3.7.8/net/packet/af_packet.c#L232">http://lxr.linux.no/linux+v3.7.8/net/packet/af_packet.c#L232</a></div><div class="gmail_extra">[2] <a href="http://lxr.linux.no/linux+v3.7.8/net/packet/af_packet.c#L1328">http://lxr.linux.no/linux+v3.7.8/net/packet/af_packet.c#L1328</a></div>

</div>