En interrogeant le serveur ident, d'une extrémité distante d'un canal de communication, et en lui envoyant le couple des ports distant et local, on reçoit en retour une réponse sous la forme d'un triplet dont chaque élément est séparé par le caractère « : ».
Le programme peut s'écrire sous cette forme reprenant (en grande partie) le code de la partie serveur dans la fonction « main », le code d'une connexion en tant que client du serveur ident dans la fonction « ident » et enfin intégrant le code d'envoi de la question et de traitement de la réponse dans la fonction « dial ».
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <netdb.h> #include <sys/socket.h> #include <strings.h> // pour la fonction bzero #include <string.h> // pour les fonctions strlen et strtok #include <arpa/inet.h> // pour la fonction inet_addr #define SRVPORT 2000 void dial(int fd, int port_src, int port_dst) { char buf[1024],*p1,*p2,*p3,*p; int len; sprintf(buf,"%d, %d\n",port_src, port_dst); write(fd, buf, strlen(buf)); len=read(fd, &buf, sizeof(buf)-1); buf[len]=0x00; strtok(buf,":"); p1=strtok(NULL,":"); while (*p1==' ') p1++; for (p=p1;*p!=0x00; p++) if (*p==' ') *p=0x00; if (strcmp(p1,"USERID")==0) { p2=strtok(NULL,":"); p3=strtok(NULL,"\r\n"); while (*p3==' ') p3++; printf("[%s]\n",p3); } else if (strcmp(p1,"ERROR")==0) { p2=strtok(NULL,"\r\n"); if (strcmp(p2,"HIDDEN-USER")==0) printf("Utilisateur caché\n"); } } void ident(struct sockaddr_in *src) { int fd; struct sockaddr_in addr; int err; fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd<0) { printf("Erreur de creation de la socket !\n"); exit(1); } bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET; memcpy(&addr.sin_addr, &src->sin_addr, sizeof(src->sin_addr)); addr.sin_port = htons(113); err = connect(fd, (struct sockaddr *) &addr, sizeof(addr)); if (err != 0) { printf("Erreur de connexion au serveur !\n"); exit(1); } printf("Connexion établie avec le serveur ident !\n"); dial(fd, ntohs(src->sin_port), SRVPORT); } int main() { int fd_srv, fd_con; struct sockaddr_in adr_srv, adr_cli; int err; socklen_t adr_cli_len; fd_srv = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd_srv<0) { printf("Erreur de creation de la socket !\n"); exit(1); } bzero(&adr_srv, sizeof(adr_srv)); adr_srv.sin_family = AF_INET; err = inet_aton("0.0.0.0", &adr_srv.sin_addr); if (err == 0) { printf("Adresse IPv4 invalide !\n"); exit(1); } adr_srv.sin_port = htons(SRVPORT); err = bind(fd_srv, (struct sockaddr *) &adr_srv, sizeof(adr_srv)); if (err != 0) { printf("Erreur d'accès au port serveur !\n"); exit(1); } err = listen(fd_srv, 5); if (err != 0) { printf("Erreur de création de la file d'attente !\n"); exit(1); } printf("Serveur lancé !\n"); while(1) { adr_cli_len = sizeof(adr_cli); fd_con = accept(fd_srv, (struct sockaddr *) &adr_cli, &adr_cli_len); if (fd_con<0) { printf("Erreur sur l'acceptation de connexion entrante !\n"); exit(1); } printf("Connexion acceptée !\n"); ident(&adr_cli); shutdown(fd_con, SHUT_RDWR); close(fd_con); printf("Client déconnecté par le serveur !\n"); } return 0; }
Il suffit, par exemple, de :
Exemple : Pour transférer le fichier tp-ident-fr.c vers le répertoire /home/isenXX du serveur Unix 10.34.161.21 avec les droits de l'utilisateur isenXX, on utilise la commande suivante depuis une fenêtre cmd de windows ou depuis un terminal sur MAC.
scp tp-ident-fr.c isenXX@10.34.161.21:/home/isenXX