Faire un don ! | | style | statistiques | contactez-nous | plan | lettre d'information

Programmation.c : Galère de pointeurs avec les GArrays

Posté par Julien Vehent (Jabber id, page perso, ) le 10 juillet 2007
Bonjour à tous,



J'ai besoin de stocker les paquets que composent une communications dans un programme C.

Comme j'ai beaucoup de communications, j'ai commencé par faire un B-Tree dans lequel chaque valeur (associée à une clé) est un GArray qui contient les paquets de la communication.



Le soucis, c'est que ça bug... les 2 premiers paquets de chaque com. sont bien enregistrés et repris, mais pour les suivants j'ai des résultats bizarres...



voilà mon code :



/*!******************************

* *

* search the entry *

* *

* ******************************/

if (

TRUE != g_tree_lookup_extended(Storing_B_Tree, key_one->str, NULL, NULL)

&&

TRUE != g_tree_lookup_extended(Storing_B_Tree, key_two->str, NULL, NULL)

)

{

/*! if doesn't exist, create it and init the GArray

* as a value for this entry

*/

GArray *value;



/*! Creates a new GArray as a B-Tree value to store the packets of this connection

*/

value = g_array_new(FALSE, FALSE, 1500);



g_array_append_val(value, m->payload);



/*! add it to the tree, value contain the address of the pointer to the array in the memory

*/

g_tree_insert(Storing_B_Tree, key_one->str, value);



g_print("STORING FUNCTION : entry created and packet %s stored in memory\n",key_one->str);



}

else {

/*! the tuple exist in the B-Tree, so add the packet at the end of the

* existing GArray table

*/

GString *key;

key = key_one;



GArray *P_to_Array;

/*! get @ of the array in memory */

if (TRUE != g_tree_lookup_extended(Storing_B_Tree, key_one->str, NULL, (gpointer *) &P_to_Array))

{

/*! if key_one is not the good key, try with key_two */

g_tree_lookup_extended(Storing_B_Tree, key_two->str, NULL,(gpointer *) &P_to_Array);

key = key_two;

}



/*! store the value at the end of the GArray table

*/

g_array_append_val(P_to_Array, m->payload);



g_print("STORING FUNCTION : %dst packet of %s stored in memory\n",P_to_Array->len, key->str);



/*! TEST PURPOSE

*

* print all the entries from the corresponding array

*/

int i;



for (i=0; i < P_to_Array->len; i++)

{

struct iphdr *iph2;



iph2 = & g_array_index(P_to_Array, struct iphdr *, i);



g_print("IP table: %s; length : %u\n",(char *) inet_ntoa(iph2->saddr), ntohs(iph2->tot_len));

}





}







et voila ce que donne une exécution, les 2 premières IP sont bien reprises mais les suivantes ne sont pas bonnes

dans le second paquet, la "length" est également fausse...



STORING FUNCTION : 4st packet of 128.8.37.122:56107:130.92.6.40:80 stored in memory

IP table: 128.8.37.122; length : 52

IP table: 130.92.6.40; length : 16384

IP table: 219.43.0.80; length : 52160

IP table: 15.53.67.83; length : 9594





Alors j'essaie de comprendre pourquoi je ne récupère pas bien mes paquets.... Il me semble que GArray attribue un nouvel index pour chaque entrée, je ne devrais donc pas dépasser sur les autres index lorsque je récupère mon entrée...

> Lire le message (17 commentaires, moyenne: 1,6).  

Vous avez demandé le commentaire #850125.

g_array_index

Posté par Bench () le 10/07/2007 à 20:58. (lien). Évalué à 2.

regarde bien, ton utilisation de g_array_index est fausse...

si c'est un tableau de iphdr tu dois faire ça :

struct iphdr *iph2;
iph2 = & g_array_index(P_to_Array, struct iphdr, i);

si c'est un tableau de iphdr* tu dois faire ça :

struct iphdr *iph2;
iph2 = g_array_index(P_to_Array, struct iphdr*, i);

voilà...

  • [^]Re: g_array_index

    Posté par Julien Vehent (Jabber id, page perso, ) le 10/07/2007 à 23:15. (lien). Évalué à 1.

    hélas non, ca me renvoi un segfault

    --
    www.linuxwall.info
    • [^]Re: g_array_index

      Posté par Bench () le 10/07/2007 à 23:27. (lien). Évalué à 2.

      Dans quel cas, les deux? tu mets quoi dans ton GArray?
      Peux tu donner plus d'infos sur la structure de ta variable m?

      • [^]Re: g_array_index

        Posté par Julien Vehent (Jabber id, page perso, ) le 11/07/2007 à 02:27. (lien). Évalué à 1.

        j'obtiens un segfault dans le cas :

        iph2 = g_array_index(P_to_Array, struct iphdr*, i);

        quand j'utilise :

        iph2 = & g_array_index(P_to_Array, struct iphdr *, i);

        j'obtiens les résultats erratiques dont je parlais dans mon premier post


        la structure "m" est de type ipq_packet_msg_t, elle contient un paquet ramené dans un hook IPQ par netfilter
        de fait, "m->payload" contient le paquet raw, le reste de la structure c'est des metadonnées IPQ qui ne m'interesse pas

        le GArray semble être fonctionnel car lorsque j'accède à "P_to_Array->len" il me retourne bien le nombre de cases que contient le tableau, et ce dans tous les cas

        de fait, je pense que mon problème vient soit de l'ajout dans le tableau, soit dans la définition du tableau avec

        value = g_array_new(FALSE, FALSE, 1500);

        ou 1500 est censé être la taille en bytes de chaque case

        --
        www.linuxwall.info
        • [^]Re: g_array_index

          Posté par Bench () le 11/07/2007 à 14:47. (lien). Évalué à 2.

          on avance, j'ai l'impression que à mal lu mon premier commentaire, qu'est-ce que t'obtiens dans le cas :
          struct iphdr *iph2;
          iph2 = & g_array_index(P_to_Array, struct iphdr, i);

          je pense que c'est ce cas là qui devrait marcher... et je vais t'expliquer pourquoi...

          g_array_index est défini par :
          #define g_array_index(a,t,i) (((t*) (a)->data) [(i)])

          remarque ce qu'il fait... il cast a->data en t* !!!!

          Or, toi tu lui dis de faire un cast en struct iphdr **, ce qui est faux je pense. Si j'ai raison, ça ne devrait marcher que pour le premier index, pour les autres ça devrait induire un décalage des données.
          Or chez toi tu obtiens le bon résultat pour le premier index, pas pour les autres. Ce qui semble comfirmer mon hypothèse.
          Essaie donc et dis moi si ça corrige quelquechose...

          • [^]Re: g_array_index

            Posté par Julien Vehent (Jabber id, page perso, ) le 11/07/2007 à 15:45. (lien). Évalué à 1.

            je l'avais déjà essayé celle là, et ça ne résoud pas le problème


            REDIRECTION CHECK : Conn ID 128.8.37.122:13666:128.8.37.121:22 or 128.8.37.121:22:128.8.37.122:13666 is not redirected
            NETFILTER_CONNTRACK : Connection check called for 128.8.37.122:13666:128.8.37.121:22 state = activ
            PCAP_TOOL : Current packet writed to output pcap file
            STORING FUNCTION : 163st packet of 128.8.37.122:13666:128.8.37.121:22 stored in memory
            IP table: 128.8.37.122; length : 60
            IP table: 160.2.22.208; length : 22
            IP table: 0.0.0.0; length : 1460
            IP table: 1.0.0.0; length : 0
            IP table: 184.22.220.191; length : 61879
            IP table: 3.0.0.0; length : 0
            IP table: 12.0.0.0; length : 56511
            IP table: 232.114.218.183; length : 56511
            IP table: 1.0.0.0; length : 65463
            IP table: 0.0.0.0; length : 0


            Dans la doc de GLib, ils disent de ne pas mettre struct devant :

            EDayViewEvent *event;

            /* This gets a pointer to the 3rd element in the array of EDayViewEvent
            structs. */
            event = &g_array_index (events, EDayViewEvent, 3);


            mais quand je fais ca

            iph2 = & g_array_index(P_to_Array, iphdr, i);


            il me dit que iphdr est une variable non déclarée....

            --
            www.linuxwall.info