Le jeudi 10 juin, à 16h56 (+0200), yannick excoffon a écrit :
> [récupérer son @ IP]
> > listen(s, backlog);
> > t = accept(s, (struct sockaddr *) &his_addr, &addr_size);
> > getsockname(t, &recv_addr, &addr_size);
> > printf("Le client m'a contacté sur %s:%d\n",
> > inet_ntoa(recv_addr.sin_addr), ntohs(recv_addr.sin_port));
>
> C'etait malheureusement une des "sales" solutions que j'utilisais mais
> cela reste genant de squatter un port pour ce renseignement.
Comment ça sale ? Elle est très propre ma solution :-E !
> Quand a uname (mail de FX Kowalski) il permet de recuperer un nom de
> domaine au mieux.
Je crois que nous nous sommes mal compris. Je reprends.
À priori une machine peut avoir autant d'adresses IP que tu veux. La
question « Quelle est l'adresse IP de cette machine ? » est donc
ambigüe. Tu peux essayer d'y répondre de deux façons :
Cas général :
Il y a à priori un nombre quelconque d'adresses IP sur la machine.
La question de départ n'a donc pas de sens. On la remplace alors par
la question plus précise « Quelle est, parmi les adresses IP de
cette machine, celle par laquelle le client m'a contacté ? » Dans ce
cas, la réponse est dans le code que je t'ai envoyé. Tu ne squattes
pas un port, tu te sers de celui qui a reçu la connexion. Et ce
n'est pas une solution sale. Je dirais même plus : plus propre tu
meurs !
Cas particlier :
Tu supposes que, parmi les différentes adresses IP de ta machine, il
y en a une qui est plus « standard » que les autres. C'est souvent
le cas lorsque tu n'utilises qu'un réseau local en plus de
l'interface loopback (qui est sur l'adresse localhost). Là je ne
sais pas faire, je ne suis pas sûr qu'il existe une notion très bien
définie d'adresse IP « privilégiée ». J'ai pourtant l'impression que
la solution proposée par FX Kowalski est tout ce qu'il y a de plus
raisonnable. Évidemment, tu récupères un nom de domaine, mais
ensuite tu utilises le resolver pour en déduire l'adresse IP
(gethostbyaddr si je ne m'abuse).
Il faut maintenant que tu te poses les questions suivantes :
- As-tu besoin de connaître une adresse IP unique pour toute la durée
de vie du processus serveur ou bien il te suffit de la connaître au
coup par coup, à chaque connexion reçue ?
- veux-tu considérer le cas général d'une machine avec plusieurs
adresses IP ou bien tu peux te limiter au cas particulier d'une
seule adresse « importante » ?
Suivant comment tu réponds à ces questions, je pourrais te conseiller :
- D'utiliser la méthode de FX Kowalski, si tu te limites au cas d'une
seule adresse ;
- d'utiliser ma méthode, si tu n'as besoin de l'adresse qu'au coup par
coup ;
- d'indiquer au serveur son IP dans un fichier de configuration ou
dans une option de la ligne de commande.
La dernière méthode te permet d'avoir une adresse IP unique pour toute
la durée de vie du serveur sans sacrifier à la généralité. En effet,
dans le cas d'une machine avec plusieurs adresses, tu peux lancer un
processus serveur sur chacune d'entre-elles. Il faut juste penser à
attacher le socket sur l'adresse demandée et non sur INADDR_ANY.
> [récupérer un login et un mot de passe]
> > Si tu veux que ton programme fasse de l'authentification (demande un
> > login et un mot de passe pour laisser le client se connecter pour le
> > compte d'un utilisateur), la façon propre de le faire est de passer par
> > PAM. [...]
>
> En fait l'appli en GTK gere les transferts de donnees (donc de
> fichiers puisque tout est fichier sous Linux) entre deux machines
> sans utiliser le protocole FTP, pour plus de liberte dans les
> commandes. Donc lorsque je me connecte sur une machine distante le
>
> connect(fd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))
>
> ne suffit pas a authentifier l'utilisateur, il faut encore passer au
> serveur un login et un password lorsque l'utilisateur possede un
> compte ou anonymous lorsqu'on accede a un site ftp. C'est cette etape
> que je n'arrive pas a coder en C. (Etapes qui doivent rester
> invisibles pour l'utilisateur qui rentre ses coord dans un fichier de
> config et ne fait que cliquer ensuite).
Donc l'utilisateur a un compte sur la machine serveur (qui peut
d'ailleurs être le compte anonymous).
Au niveau du client :
Il doit d'une façon ou d'une autre récupérer le login et le mot de
passe de l'utilisateur. Il les envoie au client en les écrivant
simplement dans le socket. Un simple printf peut faire l'affaire(*).
Au niveau du serveur :
Il doit vérifier que ce login et ce mot de passe correspondent bien
à un utilisateur du système. C'est ce qu'on appelle
l'authentification. Comme je l'ai déjà dit, la façon propre de faire
est d'utiliser la bibliothèque PAM.
----------------
(*) Pour pouvoir utiliser printf et compagnie sur une socket, il faut
utiliser fdopen. Pour ne pas avoir à vider (fflush) le tampon à la
main, il faut utiliser setlinebuf et avoir un protocole orienté
ligne (chaque commande est une ligne complète, terminée par \n).
--
Edgar Bonet Orozco
Lab. Louis Néel -- CNRS Tel : +33 476-88-90-89
BP 166 Fax : +33 476-88-11-91
38042 Grenoble cedex 9 e-mail : bonet@???