| 
				
				
				
				 | 
			
			 | 
			@@ -0,0 +1,323 @@ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* notre passerelle TCP IPv4 */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <stdio.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <stdlib.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <string.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <stdint.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <unistd.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <sys/types.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <sys/stat.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <fcntl.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <sys/socket.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <arpa/inet.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <signal.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <sys/wait.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <netdb.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include <pthread.h> | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#include "pass.h" | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* les variables globales */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			int RUN=1; /* Indice qui permet de stopper en le mettant a zero */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			int Chiff=0; /* =0 rien; =1 chiff. distant =-1 chiff. local */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			in_port_t PORTL, PORTD;  /* au format du reseau !! */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			uint32_t ADDRD;		/* adressse distante au format du reseau */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			long long CLE = 0xABCD1276FA8745EC; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void interrupt(int S) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   switch(S) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   case SIGCHLD : | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			     while (waitpid(-1,NULL,WNOHANG) != -1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			     break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   case SIGINT: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   case SIGTERM: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			     fprintf(stderr,"Arret de la passerelle !\n"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			     exit(0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   default: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			     fprintf(stderr,"Recu signal %d !?!?\n",S); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   return; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* la structure sockaddr_in */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			struct sockaddr_in Sin = { AF_INET }; /* Le reste de egal à 0 !! */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* fct qui fabrique un IP v4 au format reseau | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 exemple  : makip4(127,0,0,1); */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			uint32_t makip4(int a, int b, int c, int d) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			uint32_t A; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			char *p; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    p = (char *)&A; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    *p++ = (unsigned char)a; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    *p++ = (unsigned char)b; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    *p++ = (unsigned char)c; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    *p = (unsigned char)d; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    //return htonl(A); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return A; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* fct qui traduit une adresse IP V4 en chaine de caractere xxx.xxx.xxx.xxx */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			char * adip(uint32_t A) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static char b[16]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   sprintf(b,"%d.%d.%d.%d", (int)((A>>24)& 0xFF), (int)((A>>16)& 0xFF), (int)((A>>8)& 0xFF), (int)(A & 0xFF)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   return b; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			int readNbc(int fd, char*b, int t) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			char * d; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			int n, T=t; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#ifdef TRACESP | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   printf(" readNbc %d octets !\n",t); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   d=b; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   while(T>0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      if ((n=read(fd,d,T)) == -1) return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      d+=n; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      T-=n; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			int SidLoc, SidDist; /* variables globales des 2 taches de transfert */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* gestion des cles a partir d'un fichier externe */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			char *NFCLE="/tmp/clepass"; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* ATTENTION choisir LCLE tel que = 8*n !!! */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#define LCLE 8192 /* 8 ko  => cle de 65536 bits !! */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			char BCLE[LCLE]; /* buffer contenant la cle */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* on suppose dans tout le code que la fct de chiffrement est telle que | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			fchiffre(fchiffre(buf)) = buf !! autrement dit qu'elle est involutive ! */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void fchiffre2(char * b, int l, int ori) /* travaille avec BCLE */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			long long *d, *f, *c, *fc; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   d=(long long*)b; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   f=(long long*)(b+l); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   c=(long long *)BCLE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   fc=(long long *)(BCLE+LCLE); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   /* le chiffrement avec xor */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   while (d<f) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      *d++ ^= *c++; /* equiv. *d ^= *c; d++; c++; */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      if (c==fc) c=(long long *)BCLE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   return; /* pour l'instant ne fait rien !! */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			int initCle(void) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			int fd; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   if ((fd = open(NFCLE,O_RDONLY)) == -1) return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   if (read(fd,BCLE, LCLE) != LCLE) return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   close(fd); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void fchiffre(char * b, int l, int ori) /* travaille avec CLE de 64 bits */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			long long *d, *f; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   d=(long long*)b; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   f=(long long*)(b+l); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   /* le chiffrement avec xor */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   while (d<f) *d++ ^= CLE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#ifdef TRACECH | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   if (ori==0) { /* le thread L -> D */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			     if (Chiff==1) printf("Chiffrement l=%d vers %d !\n",l,ntohs(PORTD)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			     else  printf("Dechiffrement l=%d depuis %d !\n",l,ntohs(PORTL)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   } else {      /* le fils   D -> L */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			     if (Chiff==1) printf("Dechiffrement l=%d depuis %d !\n",l,ntohs(PORTD)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			     else  printf("Chiffrement l=%d vers %d !\n",l,ntohs(PORTL)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			   return; /* pour l'instant ne fait rien !! */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			/* la fonction du thread qui lit le port local et ecrit vers le port distant */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void * fct_th(void * p) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			int n; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			uint16_t lb; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			char buf[LBUF]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* on s'occupe du transfert L -> D */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    while (1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        /* lecture cote LOCAL */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (Chiff == -1) { /* chiffrement cote local */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           if (read(SidLoc,&lb,2)!=2) n=-1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              n = (int)ntohs(lb); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              if (readNbc(SidLoc,buf,n) == -1) n=-1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              fchiffre2(buf,n,0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           n=read(SidLoc,buf,LBUF); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (n > 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           /* ecriture cote DISTANT */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           if (Chiff == 1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#ifdef TRACESP | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              printf(" writeNbc %d octets !\n",n); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              fchiffre2(buf,n,0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              lb = htons((uint16_t)n); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              write(SidDist,&lb,2); /* on envoie le nb d'octets du paquet */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           write(SidDist,buf,n); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (n==-1) break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return NULL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			int liaison(int fd) /* il faut creer la passerelle pour le client */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			int sid,n ; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			uint16_t lb; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			struct sockaddr_in Sin = { AF_INET }; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			pthread_t thid; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			char buf[LBUF]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* on est dans le cas du client qui veut se connecter au serveur */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* fabrication de l'interface reseau en IP V4 */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    SidLoc = fd; /* pour que le thread l'utilise */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if ((sid = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       perror("socket"); return 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    Sin.sin_port = PORTD; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    Sin.sin_addr.s_addr = ADDRD; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* on fait la connexion */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (connect(sid, (struct sockaddr*)&Sin, sizeof(Sin)) < 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       perror("connect"); return 2; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* on masque le signal SIGPIPE */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    signal(SIGPIPE,SIG_IGN); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* la connexion est faite ! */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    SidDist = sid; /* pour que le thread l'utilise */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* creation du thread qui va se charger du transfert L -> D */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (pthread_create(&thid,NULL,fct_th,NULL) !=0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       fprintf(stderr,"Erreur creation thread !\n"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       close(fd); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       close(sid); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       return 3; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* on s'occupe du transfert D -> L */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    while (1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (Chiff == 1) { /* chiffrement cote distant */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           if (read(sid,&lb,2)!=2) n=-1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              n = (int)ntohs(lb); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              if (readNbc(sid,buf,n) == -1) n=-1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              fchiffre2(buf,n,0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } else n=read(sid,buf,LBUF); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (n > 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           if (Chiff==-1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#ifdef TRACESP | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              printf(" writeNbc %d octets !\n",n); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              fchiffre2(buf,n,1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              lb = htons((uint16_t)n); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			              write(fd,&lb,2); /* on envoie le nb d'octets du paquet */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			           write(fd,buf,n); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (n==-1) break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    close(fd); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			void finerr(char * N, int err) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    fprintf(stderr,"%s : version %s\n",N,Version); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    fprintf(stderr,"Utilisation : %s -d|-l|-s port_local nom_ou_ip_serveur port_distant !\n",N); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    exit(err); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			int main(int N, char *P[]) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			int sid, newsid, err; /* socket id = file descriptor */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			struct sockaddr_in Srec; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			struct hostent *h; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			pid_t pid; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			long lg; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    signal(SIGCHLD,interrupt); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    signal(SIGINT,interrupt); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    signal(SIGTERM,interrupt); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (initCle()) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       fprintf(stderr,"Erreur lecture ficher cle %s !!\n", NFCLE); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       return 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* verification que l'on a bien 4 parametres et seult 4 ! */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (N != 5) finerr(P[0],1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* verification du 1er parametres */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (P[1][0] != '-') finerr(P[0],2); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (strlen(P[1]) != 2) finerr(P[0],2); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    switch(P[1][1]) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      case 'l': | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			         Chiff = -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			         break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      case 'd': | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			         Chiff = 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			         break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      case 's': | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			         Chiff = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			         break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      default : | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			         finerr(P[0],2); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    PORTL = htons(atoi(P[2]));  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    PORTD = htons(atoi(P[4]));  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if ((h=gethostbyname(P[3])) == NULL) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       fprintf(stderr,"Erreur gethostbyname no %d !\n",h_errno); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       return 2; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    bcopy((void*)(h->h_addr),(void*)(&ADDRD),h->h_length); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* fabrication de l'interface reseau en IP V4 */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if ((sid = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       perror("socket"); return 5; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* initialiser la structure sockaddr_in pour dire quel port on veut */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    Sin.sin_port = PORTL; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* Sin.sin_addr.s_addr = makip4(127,0,0,1); */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    Sin.sin_addr.s_addr = makip4(0,0,0,0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* puis faire un bind() pour s'attacher a ce port */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (bind(sid,(struct sockaddr *)&Sin,sizeof(Sin)) == -1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       perror("bind"); return 3;  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    /* on definit le nombre d'ecoutes simultannees */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    if (listen(sid, NBCLI) == -1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			       perror("listen"); return 4;  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    while(RUN) { /* on attend le clients locaux pour transmettre les donnees */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      lg = sizeof(Sin); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      if ((newsid=accept(sid,(struct sockaddr *)&Srec, (socklen_t*)&lg))<0){ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			          perror("accept"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      } else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			          /* message pour informer qui se connecte */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#ifdef TRACE_1 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			          printf("Connexion de %s !\n",adip(ntohl(Srec.sin_addr.s_addr))); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			#endif | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			          /* creation du processus dedie au client */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			          if ((pid = fork()) == -1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			             perror("fork"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			             write(newsid,"Erreur passerelle !\n",18); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			          } else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			             if (pid==0) { /* code du fils */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                err=liaison(newsid);/* creation passerelle privee pour client */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (err) printf("Erreur liaison %d !\n",err); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                return err; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			             } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			             /* suite du pere : ie passerelle principale */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			          } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			          close(newsid); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			      } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return 0; /* fin OK */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  |