123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- /*
- * tools
- * Creation et manipulation de sockets
- * Thomas Nemeth -- le 15 juin 2001
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <errno.h>
- #include <signal.h>
- #include <netdb.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <string.h>
- #include <strings.h>
- #include <arpa/inet.h>
- #include "defines.h"
- #include "xmem.h"
- #include "tools.h"
-
- /*
- * Ouverture d'une socket de type flot de donnees
- *
- * creation d'une socket serveur : port != 0
- *
- */
- int ouvre_socket (int port, char *adr_ip, struct sockaddr_in *ptr_adresse) {
- int desc_soc;
- int lg_adresse = sizeof (struct sockaddr_in);
- int lg_linger = sizeof (struct linger);
- struct sockaddr_in adresse;
- struct linger ling;
-
- /*
- * Creation de la socket
- *
- */
- if ( (desc_soc = socket (AF_INET, SOCK_STREAM, 0) ) == -1) {
- #ifdef DEBUG
- fprintf (stderr, "Ne peut pas ouvrir la socket de connexion.\n");
- #endif
- perror (__FILE__ " socket");
- return -1;
- }
-
- /*
- * Affectation des options
- *
- */
- if (port != 0) {
- int opt = 1;
- if (setsockopt (desc_soc, SOL_SOCKET,
- SO_REUSEADDR, &opt, sizeof (int) ) == -1) {
- #ifdef DEBUG
- fprintf (stderr, "Impossible de positionner REUSEADDR.\n");
- #endif
- perror (__FILE__ " setsockopt -- REUSEADDR");
- return -1;
- }
- }
- ling.l_onoff = 0;
- ling.l_linger = 0;
- if (setsockopt (desc_soc, SOL_SOCKET, SO_LINGER, &ling, lg_linger) == -1) {
- #ifdef DEBUG
- fprintf (stderr, "Impossible de positionner LINGER.\n");
- #endif
- perror (__FILE__ " setsockopt -- LINGER");
- return -1;
- }
-
- /*
- * Preparation de l'adresse d'attachement
- *
- */
- memset (&adresse, 0, sizeof (adresse) );
- adresse.sin_family = AF_INET;
- if (adr_ip) {
- struct in_addr ia;
-
- if (inet_aton(adr_ip, &ia)) {
- adresse.sin_addr = ia;
- } else {
- struct hostent *h;
-
- h = gethostbyname(adr_ip);
- if (!h) {
- fprintf (stderr, "Adresse %s inconnue.\n", adr_ip);
- return -1;
- }
- memcpy (&adresse.sin_addr.s_addr, h->h_addr, h->h_length);
- }
- } else
- adresse.sin_addr.s_addr = htonl (INADDR_ANY);
- adresse.sin_port = htons (port);
-
- /*
- * Demande d'attachement de la socket
- *
- */
- if (bind (desc_soc, (struct sockaddr*) &adresse, lg_adresse) == -1) {
- #ifdef DEBUG
- fprintf (stderr,
- "Ne peut donner de nom a la socket de connexion.\n"
- "Attendez quelques minutes avant de relancer.\n");
- #endif
- perror (__FILE__ " bind");
- close (desc_soc);
- return -1;
- }
-
- /*
- * Recuperation de l'adresse effective d'attachement
- *
- */
- if (ptr_adresse != NULL)
- getsockname (desc_soc, (struct sockaddr *) ptr_adresse, &lg_adresse);
-
- return desc_soc;
- }
-
-
- int connect_server (const char *machine, int port) {
- struct hostent *serveur;
- struct sockaddr_in adresse_serveur, adresse_client;
- int socket_client;
-
- /* Recherche de la machine ou se trouve le serveur */
- if ( (serveur = gethostbyname (machine) ) == NULL) {
- #ifdef DEBUG
- fprintf (stderr, "Machine %s inconnue...\n", machine);
- #endif
- return -1;
- }
-
- /* Creation et attachement de la socket du client --
- * port quelconque => 0
- */
- if ( (socket_client = ouvre_socket
- (0, NULL, (struct sockaddr_in *) &adresse_client)) == -1) {
- #ifdef DEBUG
- fprintf (stderr, "Creation de la socket du client impossible.\n");
- #endif
- return -1;
- }
-
- /* Preparation de l'adresse du serveur */
- adresse_serveur.sin_family = AF_INET;
- adresse_serveur.sin_port = htons (port);
- memcpy (&adresse_serveur.sin_addr.s_addr,
- serveur->h_addr, serveur->h_length);
-
- /* Demande de connexion au serveur */
- if (connect (socket_client, (struct sockaddr *) &adresse_serveur,
- sizeof (adresse_serveur) ) == -1) {
- #ifdef DEBUG
- fprintf (stderr, "Impossible de se connecter au serveur.\n");
- #endif
- perror (__FILE__ " connect");
- return -1;
- }
-
- return socket_client;
- }
-
-
- int install_server (int port, char *adr_ip, struct sockaddr_in *ecoute) {
- int socket_ecoute;
-
- /* Ouverture de la socket */
- if ( (socket_ecoute = ouvre_socket (port, adr_ip, ecoute)) == -1) {
- #ifdef DEBUG
- fprintf (stderr, "Creation de la socket du serveur impossible.\n");
- #endif
- return -1;
- }
-
- /* Declaration d'ouverture du service */
- if (listen (socket_ecoute, 10) == -1) {
- #ifdef DEBUG
- fprintf (stderr, "Impossible d'enregistrer le service.\n");
- #endif
- perror (__FILE__ " listen");
- return -1;
- }
-
- return socket_ecoute;
- }
-
-
- /*
- * Fonction de reception de donnees
- *
- */
- int read_infos (int socket_data, char *infos) {
- int nb;
-
- /* SSIZE_MAX = 2147483647 */
- memset (infos, 0, MAXSTRLEN);
- nb = read (socket_data, infos, MAXSTRLEN - 1);
-
- if ( (nb == -1) || (nb == 0) ) {
- #ifdef DEBUG
- fprintf (stderr, "Erreur de connexion reception !\n");
- #endif
- if ( (errno == EPIPE) || (nb == 0) ) return FALSE; /* cont = FALSE; */
- }
-
- #ifdef DEBUG
- printf ("Recu : [%s] lg = %d/%d\n", infos, strlen (infos), nb);
- #endif
-
- return TRUE;
- }
-
-
- /*
- * Fonction d'emisson de donnees
- *
- */
- int send_infos (int socket_data, const char *infos) {
-
- #ifdef DEBUG
- printf ("Emission de : %s [%d]\n", infos, strlen (infos));
- #endif
-
- if (write (socket_data, (void *) infos, strlen (infos) + 1) == -1) {
- /* Erreur : plus de socket ! */
- #ifdef DEBUG
- fprintf (stderr, "Erreur de connexion emission !\n");
- #endif
- if (errno == EPIPE) return FALSE; /*cont = FALSE;*/
- }
- #ifdef DEBUG
- fprintf (stderr, "Emission ok !\n");
- #endif
- return TRUE;
- }
-
-
- void get_sock_infos (int sock, char **nom, char **adr, int *prl, int *prd) {
- struct sockaddr_in name;
- #ifdef OpenBSD
- int namelen;
- #else
- socklen_t namelen;
- #endif
- struct hostent *machine;
-
- /* Initialisations en cas d'echecs */
- *nom = NULL;
- *adr = NULL;
- *prd = 0;
-
- /* Infos locales (port) */
- namelen = sizeof (name);
- if (getsockname (sock, (struct sockaddr *) &name, &namelen) == 0)
- *prl = ntohs (name.sin_port);
- else {
- perror ("getsockname() ");
- *prl = 0;
- }
-
- /* Port et adresse IP distants */
- namelen = sizeof (name);
- if (getpeername (sock, (struct sockaddr *) &name, &namelen) != 0) {
- #ifdef DEBUG
- perror ("Erreur de recuperation d'information sur pair !\n"
- "getpeername() ");
- #else
- perror ("Impossible d'obtenir les infos distantes ");
- #endif
- return;
- }
-
- *adr = xstrdup (inet_ntoa (name.sin_addr));
- *prd = ntohs (name.sin_port);
-
- /* Nom de machine distante */
- machine = gethostbyaddr ((char *)&name.sin_addr,
- sizeof name.sin_addr, name.sin_family);
- if (machine == NULL) {
- #ifdef DEBUG
- perror ("Erreur de recuperation de nom de pair.\n"
- "gethostbyaddr() ");
- fprintf (stderr, "Adresse : %s (%s)\tFamille : %d (2 == AF_INET)\n",
- *adr, (char *)&name.sin_addr, name.sin_family);
- #else
- perror ("Impossible d'obtenir le nom d'hote distant ");
- #endif
- return;
- }
-
- *nom = xstrdup (machine->h_name);
- }
|