Bonjour.
Je suis en train de faire un petit programme dont le but est de localisé (IP) un hote sur le réseau. Ça marche avec un système client-serveur chaque hote voulant être localisé devant faire tourner le serveur.
Les programmes client (nommé flh) et serveur (flhd) fonctionne très bien en local. Mais dès que j'essaie de localisé un autre hote de mon réseau ça ne fonctionne pas :/ .
Donc voici les sources:
flh.c:
flhd.c:
Code c : 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 /*######################## # Client FLH (Find Local Host) simple # #########################*/ #include "flh.h" char* option_h = "-h"; char* help = "Usage: flh [OPTION]\nRecherche un hote sur le réseaux local suivant le protocole FLH.\n\nOption:\n\t-h\tAffiche cette aide.\n\nCode d'erreur:\n\t1\tErreur de création de la socjet.\n\t2\tErreur de nommage de la soccket.\n\t3\tErreur de réception de packet.\n\t4\tErreur de fork.\n\t5\tErreur de récupération du nom d'hote.\n\t6\tErreur d'envoie de message.\n"; int main(int argc, char* argv[]){ int h = 0; if(argc > 1){ if(strcmp(argv[1], option_h) == 0) h = 1; } else{ h = 1; } if(h){ printf("%s", help); exit(0); } else{ struct sockaddr_in addr; if(searchHost(argv[1], &addr)){ printf("%s\n", inet_ntoa(addr.sin_addr)); } else{ printf("0.0.0.0\n"); } } }
et flh.h:
Code c : 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 /*#################### # Démon FLH (Find Local Host) # #####################*/ #include "flh.h" char* option_n = "-n"; char* option_h = "-h"; char* help = "Usage: flhd [OPTION]\nLance le démon FLH.\nNe passer qu'une option à la fois.\n\nOption:\n\t-h\tAffiche cette aide.\n\t-n\tNe fork pas.\n\nCode d'erreur:\n\t1\tErreur de création de la socjet.\n\t2\tErreur de nommage de la soccket.\n\t3\tErreur de réception de packet.\n\t4\tErreur de fork.\n\t5\tErreur de récupération du nom d'hote.\n\t6\tErreur d'envoie de message.\n"; int main(int argc, char* argv[]){ int n = 0; if(argc > 1){ if(strcmp(argv[1], option_n) == 0) n = 1; else if(strcmp(argv[1], option_h) == 0){ printf("%s", help); exit(0); } } if(!n){ pid_t pid = fork(); if(pid == -1){ perror("fork()"); exit(ERR_FORK); } else if(pid > 0){ printf("PID fork: %d\n", pid); exit(0); } } char hostname[FLH_MAX_HOSTLEN]; if(gethostname(hostname, FLH_MAX_HOSTLEN) == -1){ perror("gethostname()"); exit(ERR_HOSTNAME); } int sock; struct sockaddr_in s_addr;//Server infos /* ### */ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket()"); exit(ERR_SOCK); } s_addr.sin_family = AF_INET; s_addr.sin_addr.s_addr = INADDR_ANY; s_addr.sin_port = htons(FLH_SERVER_PORT); memset(&(s_addr.sin_zero), '\0', 8); if (bind(sock, (struct sockaddr *)&s_addr, sizeof(struct sockaddr)) == -1) { perror("bind()"); exit(ERR_BIND); } socklen_t addr_len = sizeof(struct sockaddr); struct sockaddr_in c_addr;//Client infos char* ip = NULL; char buffer[FLH_MAX_MSGLEN]; int nob = 0; printf("flhd running on %s...\n", hostname); while(1){ if ((nob = recvfrom(sock, buffer, FLH_MAX_MSGLEN-1 , 0, (struct sockaddr *)&c_addr, &addr_len)) == -1) { perror("recvfrom()"); exit(ERR_RECV); } else if(strncmp(buffer, WHERE_ARE, WHERE_ARE_LEN) == 0 || nob < FLH_MAX_MSGLEN+2){ ip = inet_ntoa(c_addr.sin_addr); char tmp[FLH_MAX_MSGLEN+1]; int offset = WHERE_ARE_LEN+1; strncpy(tmp, buffer+offset, nob-offset); tmp[nob-offset] = '\0'; printf("%s is searching %s", ip, tmp); sprintf(tmp, "%s",IM_HERE); if(sendMessage(FLH_CLIENT_PORT, c_addr.sin_addr.s_addr, tmp)) printf(", response sent\n"); else printf(", error sendin response\n"); } else{ char tmp[FLH_MAX_MSGLEN+1]; strncpy(tmp, buffer, nob); tmp[nob] = '\0'; printf("Receive unknow message: %s\n", tmp); } } close(sock);//Pour la forme return 0; }
Code c : 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 /*############################ # Fonction utile pour FLH (Find Local Host) # ############################# # Définition du protocole FLH # (Find Local Host) # # Le démon écoute en UDP le port 8862 # (sur l'adresse de broadcast) et attend la # réception d'un packet contenant: # "WHERE ARE YOU X" # où X est l'hote dont on cherche l'IP. # Une fois ce message reçut, il répond # à l'expéditeur avec le message (UDP): # "IM HERE" # il envoie se message sur le port 8864 que # le client doit écouté à ce moment là. # # Un client doit donc envoyer le message # attendu par le serveur (en broadcast) en y # insérant le nom de l'hote qu'il recherche. # Puis il écoute en UDP le port 8864 et attend # une réponse. # # Le serveur ne répond qu'une seul fois. # Donc si le client ne reçoit pas de message, # il doit refaire une demande. ############################*/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h> //### #define ERR_SOCK 1 #define ERR_BIND 2 #define ERR_RECV 3 #define ERR_FORK 4 #define ERR_HOSTNAME 5 #define ERR_SENDTO 6 #define FLH_SERVER_PORT 8862 #define FLH_CLIENT_PORT 8864 #define FLH_MAX_MSGLEN 256 #define FLH_MAX_HOSTLEN 200 const char* WHERE_ARE = "WHERE ARE YOU"; const int WHERE_ARE_LEN = 13; const char* IM_HERE = "I AM HERE"; const int IM_HERE_LEN = 9; // /!\ Peu bloqué indéfiniment si aucun message reçu /!\ //Reçoit un message UDP char* receiveMessage(int port, int usec, struct sockaddr_in* addr){ int sock; struct sockaddr_in s_addr; if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket()"); return NULL; } s_addr.sin_family = AF_INET; s_addr.sin_addr.s_addr = INADDR_ANY; s_addr.sin_port = htons(port); memset(&(s_addr.sin_zero), '\0', 8); if (bind(sock, (struct sockaddr *)&s_addr, sizeof(struct sockaddr)) == -1) { perror("bind()"); return NULL; } socklen_t addr_len = sizeof(struct sockaddr); struct sockaddr_in c_addr; char* ip = NULL; char buffer[FLH_MAX_MSGLEN]; int nob = 0; if ((nob = recvfrom(sock, buffer, FLH_MAX_MSGLEN-1 , 0, (struct sockaddr *)&c_addr, &addr_len)) == -1) { perror("recvfrom()"); return NULL; } close(sock); *addr = c_addr; char* tmp = malloc(nob+sizeof(char)); strncpy(tmp, buffer, nob); tmp[nob+1] = '\0'; return tmp; } //Envoie un message en UDP int sendMessage(int port, in_addr_t addr, char* message){ int sock; struct sockaddr_in s_addr; if ((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){ perror("socket()"); return 0; } memset((char *) &s_addr, 0, sizeof(s_addr)); s_addr.sin_family = AF_INET; s_addr.sin_port = htons(port); s_addr.sin_addr.s_addr = addr; int nob = strlen(message); if(nob > FLH_MAX_MSGLEN){ return 0; } if (sendto(sock, message, nob, 0, (struct sockaddr *)&s_addr, sizeof(s_addr)) == -1){ return 0; } else{ return 1; } close(sock); } struct sockaddr_in* G_addr; int G_found= 0; //Thread de recherche void* searchThread(void *data){ char* tmp = receiveMessage(FLH_CLIENT_PORT, 2000000, G_addr); if(tmp != NULL && strcmp(tmp, IM_HERE) == 0){ G_found = 1; } return NULL; } //Cherhche un hote, 3 tentatives max, 6 secondes max int searchHost(char* hostname, struct sockaddr_in* addr){ G_addr = addr; char buffer[FLH_MAX_MSGLEN]; int nob = sprintf(buffer, "%s %s", WHERE_ARE, hostname); pthread_t st; pthread_create(&st, NULL, searchThread, NULL); sendMessage(FLH_SERVER_PORT, INADDR_ANY, buffer); sleep(1); if(G_found){ *addr = *G_addr; return 1; } sendMessage(FLH_SERVER_PORT, INADDR_ANY, buffer); sleep(2); if(G_found){ *addr = *G_addr; return 1; } sendMessage(FLH_SERVER_PORT, INADDR_ANY, buffer); sleep(3); pthread_kill(st, 0); if(G_found){ *addr = *G_addr; return 1; } else{ return 0; } }
Pour le fonctionnement, tout est expliqué au début du fichier flh.h.
Le problème est que je n'arrive pas à envoyé les packets sur l'adresse de broadcast.
Pour envoyé un message j'utilise sendMessage:
sendMessage(FLH_SERVER_PORT, INADDR_ANY, buffer);
Mais que je mette INADDR_ANY, INADDR_BROADCAST ou inet_addr("192.168.1.255") je ne voit rien transité sur mon interface réseau (je sniff mon trafic avec Wireshark).
Si j'utilise une adresse précise cela fonctionne.
Une idée du problème ?
J'ai join une archive contenant les sources et un makefile.
Merci à vous!
PS:faite pas attention au warning, ça passe!
Partager