IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

winpcap : problème de performance


Sujet :

Réseau C

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 834
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 834
    Points : 990
    Points
    990
    Par défaut winpcap : problème de performance
    bonjour,

    J'utilise winpcap pour envoyer un flux multicast. Pour le moment c'est un simple programme en mode console :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
     
    u_short calcul_du_checksum(u_char *data, u_short len)
    {
    	unsigned long checksum = 0;
    	u_short *DataPtr;
    	u_short valData;
    	u_short valTmp, valTmp2;
     
        DataPtr = (u_short*)&data[0];
    	while(len > 0)
    	{
            valData = *DataPtr++;
            if(len == 1){
                valData &= 0x00FF;
                len--;
            } else {
                len -= 2;
            }
    		checksum += valData;
    	}
     
     
    	checksum = (checksum & 0xFFFF) + ((checksum >> 16) & 0xFFFF);
        valTmp = ((checksum >> 16) & 0xFFFF);
        valTmp2 = (checksum & 0xFFFF);
        valTmp2 += valTmp;
        checksum &= 0xFFFF0000;
        checksum |= valTmp2;
     
        valTmp2 = (checksum & 0xFFFF);
    	return ~valTmp2;
    }
    // */
     
     
     
    // *************************************************************
    int main()
    {
        #define PACKET_SIZE (1500)
     
    	pcap_if_t *alldevs;
    	pcap_if_t *d;
    	int inum;
    	int i=0;
    	pcap_t *adhandle;
    	char errbuf[PCAP_ERRBUF_SIZE];
    	u_int netmask;
    	//char packet_filter[] = "ip and udp";
    	//struct bpf_program fcode;
        u_char buf[PACKET_SIZE];
        unsigned short crc;
        int cpt = 0;
     
     
    	/* Retrieve the device list */
    	if(pcap_findalldevs(&alldevs, errbuf) == -1)
    	{
    		fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
    		exit(1);
    	}
     
    	/* Print the list */
    	for(d=alldevs; d; d=d->next)
    	{
    		printf("%d. %s", ++i, d->name);
    		if (d->description)
    			printf(" (%s)\n", d->description);
    		else
    			printf(" (No description available)\n");
    	}
     
    	if(i==0)
    	{
    		printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
    		return -1;
    	}
     
    	printf("Enter the interface number (1-%d):",i);
    	scanf("%d", &inum);
     
    	/* Check if the user specified a valid adapter */
    	if(inum < 1 || inum > i)
    	{
    		printf("\nAdapter number out of range.\n");
     
    		/* Free the device list */
    		pcap_freealldevs(alldevs);
    		return -1;
    	}
     
    	/* Jump to the selected adapter */
    	for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
     
    	/* Open the adapter */
    	if ((adhandle= pcap_open_live(d->name,	// name of the device
    							 65536,			// portion of the packet to capture.
    											// 65536 grants that the whole packet will be captured on all the MACs.
    							 1,				// promiscuous mode (nonzero means promiscuous)
    							 1000,			// read timeout
    							 errbuf			// error buffer
    							 )) == NULL)
    	{
    		fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
    		/* Free the device list */
    		pcap_freealldevs(alldevs);
    		return -1;
    	}
     
     
    	/* Check the link layer. We support only Ethernet for simplicity. */
    	if(pcap_datalink(adhandle) != DLT_EN10MB)
    	{
    		fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
    		/* Free the device list */
    		pcap_freealldevs(alldevs);
    		return -1;
    	}
     
    	//if(d->addresses != NULL){
    	//	/* Retrieve the mask of the first address of the interface */
    	//	netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
    	//} else {
    	//	/* If the interface is without addresses we suppose to be in a C class network */
    	//	netmask=0xffffff;
        //}
     
     
     
        // ***********************
    	// MAC destination : 01:00:5e:01:01:01
    	buf[0]=0x01;
    	buf[1]=0x00;
    	buf[2]=0x5e;
    	buf[3]=0x01;
    	buf[4]=0x01;
    	buf[5]=0x01;
     
    	// MAC source : 00:24:E8:00:3B:A0
    	buf[6]=0x00;
    	buf[7]=0x24;
    	buf[8]=0x00;
    	buf[9]=0xE8;
    	buf[10]=0x3B;
    	buf[11]=0xA0;
     
        // trame type IP
    	buf[12]=0x08;
    	buf[13]=0x00;
     
     
        // ***********************
    	buf[14]=0x45; // version IP V4 / len = 20 bytes
    	buf[15]=0x88; // ???
     
    	// total len => 1436
    	buf[16]=0x05;
    	buf[17]=0x9C;
     
        // identification => incrémenté de 2 a chaque paquet envoyé
    	//buf[18]=0x00;
    	//buf[19]=0x00;
        buf[18]=(cpt >> 8) & 0x1F;
        buf[19]=cpt & 0xFF;
        cpt+=2;
     
     
        // flag = 0x02 / Fragment offset = 0;
    	buf[20]=0x40;
    	buf[21]=0x00;
     
    	buf[22]=0x0a; // TTL = 10
    	buf[23]=0x11; // PROTOCL = UDP
     
        // IP Checksum
    	buf[24]=0x00;
    	buf[25]=0x00;
    	//buf[24]=0xb7;
    	//buf[25]=0x83;
     
     
    	// IP Source : 10.0.200.3
    	buf[26]=10;
    	buf[27]=0;
    	buf[28]=200;
    	buf[29]=3;
     
    	// IP Destination : 224.1.1.1
    	buf[30]=224;
    	buf[31]=1;
    	buf[32]=1;
    	buf[33]=1;
     
        // affectation du checksum du Header IP
        crc = calcul_du_checksum(&buf[14], 20);
        buf[24]= crc & 0xFF;
        buf[25]= (crc >> 8) & 0xFF;
     
     
     
        // ***********************
        // source port = 6840
    	buf[34]=0x1a;
    	buf[35]=0xb8;
     
        // destination port = 6780
    	buf[36]=0x1a;
    	buf[37]=0x7c;
     
        // len = 1416
    	buf[38]=0x05;
    	buf[39]=0x88;
     
        // UDP Checksum
    	//buf[40]=0x5f;
    	//buf[41]=0xc1;
    	buf[40]=0x00;
    	buf[41]=0x00;
     
        // affectation du checksum du Header UDP
        crc = calcul_du_checksum(&buf[34], 8);
        buf[40]= crc & 0xFF;
        buf[41]= (crc >> 8) & 0xFF;
     
     
        // ***********************
    	// remplissage des data UDP
    	for(i=42;i<PACKET_SIZE;i++){
    		buf[i]= (u_char)i;
    	}
     
     
        // ************************
        // => mettre des bytes de bourrage si le paquet est trop petit (la norme impose une taille min)
     
     
     
        while(1){
        //for(i=0; i<1000; i++){
            // Send down the packet
            if (pcap_sendpacket(adhandle,	// Adapter
                buf,				// buffer with the packet
                PACKET_SIZE				// size
                ) != 0)
            {
                fprintf(stderr,"\nError sending the packet: %s\n", pcap_geterr(adhandle));
                return 3;
            }
        }
     
     
    	pcap_close(adhandle);
     
     
     
    	return 0;
    }
    J'ai deux problèmes :
    - Je n'arrive a envoyer qu'un flux de 46Mbits (pas 46Mbytes !!!) sur un lien 100Mb : est-ce normal alors que mon PC est un Intel Core Duo E8400 (3.00GHz) ? Il n'y a pas une histoire de priorité des applications qui tournent sur mon pc à gérer ?
    - J'ai installé le logiciel NetMeter pour visualiser le débit émis par mon PC : bizarrement le débit d'upload reste à 0 alors que j'envoie des paquets => ça vient de quoi ? ... j'ai fais à peu près le même programme en java et là je visualise bien mon flux (avec le programme java j'arrive à émettre un flux de 48Mbits).

    Merci d'avance,

  2. #2
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 254
    Points : 538
    Points
    538
    Par défaut
    Tu sais t'es pas obligé de recréer un thread à chaque fois. post à la suite des autres.

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 834
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 834
    Points : 990
    Points
    990
    Par défaut
    je n'ai pas utiliser de library liés au thread pour mon application : c'est juste un programme qui tourne en mode console avec un while(1) pour que les paquets soient le plus rapidement envoyés.
    => je n'ai pas bien compris par ce que tu voulais dire par "tu n'est pas obligé de recréer un thread à chaque fois" : ai-je raté quelque chose dans l'utilisation de la lib ?
    => je ne vois pas comment faire pour qu'il n'y ai pas de thread car pour moi tout programme qui tourne sur un OS utilise forcement un thread : ai-je tord ?

  4. #4
    Expert confirmé Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Points : 5 379
    Points
    5 379
    Par défaut
    Quand 6-MarViN parle de thread, il ne parle pas de programmation et de forum.

    Donc il faut entendre thread par "discussion sur le forum".

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 834
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 834
    Points : 990
    Points
    990
    Par défaut
    Citation Envoyé par fregolo52 Voir le message
    Quand 6-MarViN parle de thread, il ne parle pas de programmation et de forum.

    Donc il faut entendre thread par "discussion sur le forum".
    Au mon dieu, où avais-je la tête ?

    C'est peut-être le même sujet (la lib pcap) mais chaque thread parle d'un problème différent => si j'avais tout mis dans le même thread, je pense que ça serait vite devenu le bordel.
    N'ai-je pas raison ?

    Personne ne voit de quoi peut venir le problème ?
    => si je fais un while(1) pour envoyer mes paquets de 1500 octets, ils sont envoyés toutes les 240µs (alors que normalement, le port Ethernet est censé aller 2X plus vite pour du 100Mb : j'ai une carte gigabit qui est connectée à un switch 100Mb donc je ne pense pas que le problème viennent du hardware de la carte réseau) et la charge CPU est à 1% dans le gestionnaire des taches de windows.


    Je viens de mettre des timer dans ma boucle while(1) => c'est la fonction pcap_sendpacket() qui met du temps à s’exécuter => elle met 240µs à s’exécuter.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 834
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 834
    Points : 990
    Points
    990
    Par défaut
    Je viens de me rendre contre que je me suis trompé, je suis connecté en Gigabit sur le switch (non pas en 100Mb) => ce qui veut dire que mon port Ethernet est chargé à à peine 5%

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 834
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 834
    Points : 990
    Points
    990
    Par défaut
    C'est bon, j'ai enfin trouvé le problème : je ne sias pas pourquoi mon switch gigabit limite mon flux a 46Mb : avec un autre switch, j'ai bien mon flux de 100Mb (=> maintenant, j'arrive a contrôler précisément ma bande passante )
    => je n'ai pas testé avec un lien Gigabit jusqu’à combien je pouvais monter

  8. #8
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    ...je ne sias pas pourquoi mon switch gigabit limite mon flux a 46Mb ...
    C'est un switch gigabit à 10€ acheté à Carrefour ou bien un wrai switch gigabit d'un vrai constructeur de switch (à un prix largement supérieur à 10€) ?

    Parce que bien souvent, un petit switch gigabit est capable de cadencer le port à 1GB mais le bus de fond (interne au switch) est largement sous dimensionné par rapport à un flux constant gigabit.

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 834
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 834
    Points : 990
    Points
    990
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    C'est un switch gigabit à 10€ acheté à Carrefour ou bien un wrai switch gigabit d'un vrai constructeur de switch (à un prix largement supérieur à 10€) ?

    Parce que bien souvent, un petit switch gigabit est capable de cadencer le port à 1GB mais le bus de fond (interne au switch) est largement sous dimensionné par rapport à un flux constant gigabit.
    Non ce n'est pas un switch a 10€ mais a 15€ (marque D-Link)
    Je veux bien que le switch soit sous dimensionné mais de la à n'utiliser que 5% de la bande passante ça me semble un peu gros : je pense plutot que ça doit être une protection contre les broadcast/multicast storm mais à confirmer (je verrais un peu plus tard si j'ai le temps de faire des tests plus approfondis)
    => le switch sur lequel je passe les 100Mb est un switch low cost 100Mb

    Les problèmes dont tu parles étaient sur un switch layer 3 (routeur/passerelle) non ? car ça m'étonne qu'avec switch Layer 2 il y ai des problèmes car les flux ne passent pas par un CPU externe mais c'est directement traité par le composant "switch"

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de performance avec LEFT OUTER JOIN
    Par jgfa9 dans le forum Requêtes
    Réponses: 6
    Dernier message: 17/07/2005, 13h17
  2. [jeu]problème de performance d'un algo
    Par le Daoud dans le forum Algorithmes et structures de données
    Réponses: 12
    Dernier message: 30/05/2005, 16h07
  3. [C#] Probléme de performance avec IsDbNull
    Par jab dans le forum Windows Forms
    Réponses: 8
    Dernier message: 04/04/2005, 11h39
  4. [oracle 9i][Workbench]Problème de performance
    Par nuke_y dans le forum Oracle
    Réponses: 6
    Dernier message: 03/02/2005, 17h38
  5. [ POSTGRESQL ] Problème de performance
    Par Djouls64 dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 26/05/2003, 16h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo