Salut à tous.
J'écris aujourd'hui car j'ai un problème à propos du fonctionnement d'un code que j'ai écris.
Ce code est celui d'un sniffer. Je dispose pour le mettre en oeuvre, d'un routeur WIFI(linksys) d'adresse 192.168.1.1, de deux cartes réseaux (installées sur la même machine) d'adresse respective 192.168.1.3 et 192.168.1.4.
En fait, ce un sniffer prend en paramètre l'adresse de la carte réseaux à associer à la raw socket d'écoute, et devrait intercepter tous les paquets circulant sur ce petit réseaux (onstitué de ma machine qui a 2 cartes réseaux et du routeur wifi), que ceux-ci lui soit destinés ou pas.

Le problème est que, lorsque je lance le sniffer sur l'interface 192.168.1.4 et que je fais un ping genre
le sniffer n'intercepte rien. Mais lorsque je lance le sniffer sur l'interface 192.168.1.3 il intercepte uniquement les paquets qui reviennent (les réponses du routeur) alors que je veux voir tous les paquets(envoie par ping et réponse par routeur). C'est un peu omme si, la socket raw ne reçoit que les paquets destinées à l'adresse à laquelle elle est attachée(bind).

En fait, voici mon code

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
 
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <errno.h>
#include "icmpinterfaces.h"
#include "tcpinterfaces.h"
#include "ipinterfaces.h"
 
#define MAXPACKETSIZE (1024 + sizeof(IP_HDR))
 
int main(int argc, char *argv[])
{
  // Variables tampons
  char* recvbuf = NULL; // Tampon de reception
  PIP_HDR ipuf = NULL; // Pointeur sur l'en-tête IP
 
  // Variable socket
  SOCKET sock;
  WSADATA initsocketapi; // Pour l'initialisation de la socket
  int hdrincl = 1; // Pour configurer la socket en mode IP utilisateur
  unsigned long ioctlmask = 1; // Pour débloquer la socket
 
  // Pour gerer les adresses
  struct hostent* h_local; // Pour contenir l'adresse locale
  char hostname[1024]; // Pour contenir les noms d'utilisateur
  struct sockaddr_in in_local; // Structure sockaddr locale
  unsigned long local;
 
  // Conernant la réception
  fd_set fdsr; // Ensemle surveillé
  struct timeval tv_timeout; // Délai de sureillance
  int surv, recvres;
 
 
  // Controle de la ligne de commande
  if(argc < 1)
   {
     printf("Usage: ShinSniffer [LocalAdress]");
     exit(-1);
   }
 
  // Initialisation de l'API socket
  if(WSAStartup(MAKEWORD(2, 2), &initsocketapi) != 0)
   {
     printf("Socket API initialisation Failure: [Code: %d]\n", WSAGetLastError());
     exit(-1);
   }
 
  // Initialisation de tampon
  recvbuf = (char*)malloc(MAXPACKETSIZE * sizeof(char));  
 
  // Calcul de l'adresse locale
  if(argc > 1)
   {
     local = inet_addr(argv[1]);
   }
  else
   {
     int hostnameres = gethostname(hostname, 1024);
     if(hostnameres == SOCKET_ERROR)
      {
        printf("Host name obtention failure: [Code:%d]\n", WSAGetLastError());
        exit(-1);
      }
     h_local = gethostbyname(hostname);
     local = *(unsigned long*)h_local->h_addr_list[0];
   }
 
  // Mise en plae des paramètres de sockaddr
  memset(&in_local, 0, sizeof(struct sockaddr_in));
  in_local.sin_family = AF_INET;
  in_local.sin_port = 0;
  *(unsigned long*)&in_local.sin_addr = local;    
 
  // réation de la socket (type: RAW, protool filtré: IP)
  sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
  if(sock == INVALID_SOCKET)
   {
     printf("Socket creation failure: [Code: %d\n]", WSAGetLastError());
     exit(-1);
   }
 
  // Association de la socket à la sockaddr
  if(bind(sock, (struct sockaddr*)&in_local, sizeof(in_local)) == SOCKET_ERROR)
   {
     printf("Binding socket to adress failure: [Code: %d]\n", WSAGetLastError());
     closesocket(sock);
     exit(-1);
    }
 
  // Modification du parametre HDRINCL
  if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&hdrincl, sizeof(hdrincl)) == SOCKET_ERROR)
   {
     printf("Option IP Header include failure: [Code: %d]\n", WSAGetLastError());
     closesocket(sock);
     exit(-1);
   }
 
  // Déblocage de la socket
  if(ioctlsocket(sock, FIONBIO, &ioctlmask) == SOCKET_ERROR)
   {
     printf("Unblocking socket failure: [Code: %d]\n", WSAGetLastError());
     closesocket(sock);
     exit(-1);
   }
 
  // Mise de la socket en mode promisuous
  DWORD dwBytesRet;
  unsigned int option;
  #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
  WSAIoctl(sock, SIO_RCVALL, &option, sizeof(option), NULL, 0, &dwBytesRet, NULL, NULL);
 
  // Mise à l'éoute des paquets
  printf("++++++++++++++++ Shin Sniffer Running (On %s) +++++++++++++++++\n", inet_ntoa(*(struct in_addr*)&local));
  while(1)
   {
     // Paramétrage des structure d'attente
     FD_ZERO(&fdsr);
     FD_SET(sock, &fdsr);
     tv_timeout.tv_sec = 5;
     tv_timeout.tv_usec = 0; 
 
     // Surveillance
     surv = select(sock + 1, &fdsr, NULL, NULL, &tv_timeout);
     if(surv > 0 )
      {
        if (FD_ISSET(sock, &fdsr))
         {
           recvres = recv(sock, recvbuf, MAXPACKETSIZE, 0);
           //recvres = recvfrom(sock, recvbuf, MAXPACKETSIZE, 0, 0, 0);
           DecodeIP(recvbuf);
         }
      }
   } 
  return 0;
}
Je me suis aussi rendu compte dans ce code que la fonction WSAIoctl() que j'utilise pour passer la socket en mode promiscuous me revoie -1: Je l'utilise ainsi
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
// Mise de la socket en mode promisuous
  DWORD dwBytesRet;
  unsigned int option;
  #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
  WSAIoctl(sock, SIO_RCVALL, &option, sizeof(option), NULL, 0, &dwBytesRet, NULL, NULL);
Je ne comprends pas très bien le fonctionnement de cette fonction (la construction des constantes) en en plus Je ne sais pas pourquoi ce code ne marche pas.