Programmation réseau |
#include <netinet/in.h> unsigned long int htonl(unsigned long int hostlong); unsigned short int htons(unsigned short int hostshort); unsigned long int ntohl(unsigned long int netlong); unsigned short int ntohs(unsigned short int netshort);
Famille | Protocole |
PF_UNIX, PF_LOCAL | Tubes nommés |
PF_INET | Protocoles TCP et UDP |
PF_INET6 | Protocoles IPv6 |
PF_APPLETALK | Protocole AppleTalk |
PF_IPX | Protocole Novell |
PF_X25, PF_CCITT | Protocole X25 |
PF_BLUETOOTH | Protocole Bluetooth |
Fichiers d’inclusion <sys/types.h>
et <sys/socket.h>
struct sockaddr { uint16_t int sa_family; uint8_t sa_data[14]; };
Fichier d’inclusion <sys/un.h>
struct sockaddr_un { uint16_t sun_family; uint8_t sun_path[UNIX_PATH_MAX]; };
Fichier d’inclusion <netinet/in.h>
struct in_addr { uint32_t s_addr; }; struct sockaddr_in { uint16_t sin_family; uint16_t sin_port; struct in_addr sin_addr; uint8_t sin_zero[8]; };
Fichier d’inclusion <netinet/in.h>
struct in6_addr { union { uint8_t u6_addr8[16]; uint16_t u6_addr16[8]; uint32_t u6_addr32[4]; } in6_u; #define s6_addr in6_u.u6_addr8 #define s6_addr16 in6_u.u6_addr16 #define s6_addr32 in6_u.u6_addr32 }; struct sockaddr_in6 { uint16_t sin6_family; uint16_t sin6_port; uint32_t sin6_flowinfo; struct in6_addr sin6_addr; uint32_t sin6_scope_id;};
Fichier d’inclusion <bluetooth/rfcomm.h>
typedef struct { uint8_t b[6]; } bdaddr_t; struct sockaddr_rc { uint16_t rc_family; bdaddr_t rc_bdaddr; uint8_t rc_channel; };
#include <sys/types.h> #include <sys/socket.h> int socket(int famille,int mode,int protocol);
#include <sys/types.h> #include <sys/socket.h> int bind(int sockfd,struct sockaddr *address,socklen_t length);
#include <sys/types.h> #include <sys/socket.h> int setsockopt(int sockfd,int level,int option, char *arguments,int number);
#include <sys/types.h> #include <sys/socket.h> int listen(int sockfd,int size);
#include <sys/types.h> #include <sys/socket.h> int accept(int sockfd,struct sockaddr *address,socklen_t *length);
#include <sys/types.h> #include <sys/socket.h> int connect(int sockfd,struct sockaddr *address,socklen_t length);
int initialisationServeur(short int *port,int connexions){ { int s; struct sockaddr_in adresse; socklen_t taille=sizeof adresse; int statut; /* Creation d'une socket */ s=socket(PF_INET,SOCK_STREAM,0); if(s<0){ perror("initialisationServeur.socket"); exit(-1); } /* Specification de l'adresse de la socket */ adresse.sin_family=AF_INET; adresse.sin_addr.s_addr=INADDR_ANY; adresse.sin_port=htons(*port); statut=bind(s,(struct sockaddr *)&adresse,sizeof(adresse)); if(statut<0) return -1; /* On recupere le numero du port utilise */ statut=getsockname(s,(struct sockaddr *)&adresse,&taille); if(statut<0){ perror("initialisationServeur.getsockname"); exit(-1); } *port=ntohs(adresse.sin_port); /* Taille de la queue d'attente */ statut=listen(s,connexions); if(statut<0) return -1; return s; }
int initialisationServeur(short int *port,int connexions){ int s; struct sockaddr_in6 adresse; socklen_t taille=sizeof adresse; int statut; /* Creation d'une socket */ s=socket(PF_INET6,SOCK_STREAM,0); if(s<0){ perror("initialisationServeur.socket"); exit(-1); } /* Specification de l'adresse de la socket */ adresse.sin6_family=AF_INET6; adresse.sin6_addr=in6addr_any; adresse.sin6_port=htons(*port); adresse.sin6_flowinfo=0; adresse.sin6_scope_id=0; statut=bind(s,(struct sockaddr *)&adresse,taille); if(statut<0) return -1; /* Recuperation du numero du port utilise */ statut=getsockname(s,(struct sockaddr *)&adresse,&taille); if(statut<0){ perror("initialisationServeur.getsockname"); exit(-1); } *port=ntohs(adresse.sin6_port); /* Taille de la queue d'attente */ statut=listen(s,connexions); if(statut<0) return -1; return s; }
int initialisationServeur(char *service,int connexions){ struct addrinfo precisions,*resultat,*origine; int statut; int s; /* Construction de la structure adresse */ memset(&precisions,0,sizeof precisions); precisions.ai_family=AF_UNSPEC; precisions.ai_socktype=SOCK_STREAM; precisions.ai_flags=AI_PASSIVE; statut=getaddrinfo(NULL,service,&precisions,&origine); if(statut<0){ perror("initialisationServeur.getaddrinfo"); exit(EXIT_FAILURE); } struct addrinfo *p; for(p=origine,resultat=origine;p!=NULL;p=p->ai_next) if(p->ai_family==AF_INET6){ resultat=p; break; } /* Creation d'une socket */ s=socket(resultat->ai_family,resultat->ai_socktype,resultat->ai_protocol); if(s<0){ perror("initialisationServeur.socket"); exit(EXIT_FAILURE); } /* Options utiles */ int vrai=1; if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&vrai,sizeof(vrai))<0){ perror("initialisationServeur.setsockopt (REUSEADDR)"); exit(EXIT_FAILURE); } if(setsockopt(s,IPPROTO_TCP,TCP_NODELAY,&vrai,sizeof(vrai))<0){ perror("initialisationServeur.setsockopt (NODELAY)"); exit(EXIT_FAILURE); } /* Specification de l'adresse de la socket */ statut=bind(s,resultat->ai_addr,resultat->ai_addrlen); if(statut<0){ freeaddrinfo(origine); shutdown(s,SHUT_RDWR); return -1; } /* Liberation de la structure d'informations */ freeaddrinfo(origine); /* Taille de la queue d'attente */ statut=listen(s,connexions); if(statut<0){ shutdown(s,SHUT_RDWR); return -2; } return s; }
int boucleServeur(int ecoute,int (*traitement)(int)){ int dialogue; while(1){ /* Attente d'une connexion */ if((dialogue=accept(ecoute,NULL,NULL))<0) return -1; /* Passage de la socket de dialogue a la fonction de traitement */ if(traitement(dialogue)<0){ shutdown(ecoute,SHUT_RDWR); return 0;} } }
int gestionClient(int s){ /* Obtient une structure de fichier */ FILE *dialogue=fdopen(s,"a+"); if(dialogue==NULL){ perror("gestionClient.fdopen"); exit(EXIT_FAILURE); } /* Echo */ char ligne[MAX_LIGNE]; while(fgets(ligne,MAX_LIGNE,dialogue)!=NULL) fprintf(dialogue,"> %s",ligne); /* Termine la connexion */ fclose(dialogue); return 0; } int main(int argc,char *argv[]) { int s; /* Lecture des arguments de la commande */ analyseArguments(argc,argv); /* Initialisation du serveur */ s=initialisationServeur(service,MAX_CONNEXIONS); if(s<0){ fprintf(stderr,"Port non utilisable\n"); exit(EXIT_FAILURE); } /* Lancement de la boucle d'ecoute */ boucleServeur(s,gestionClient); }
int connexionServeur(char *hote,int port) { int s; struct sockaddr_in adresse; socklen_t taille=sizeof adresse; int statut; /* Creation d'une socket */ s=socket(PF_INET,SOCK_STREAM,0); if(s<0){ perror("connexionServeur.socket"); exit(-1); } /* Connection de la socket a l'hote */ adresse.sin_family=AF_INET; if(nomVersAdresse(hote,(void *)&adresse)<0) return -1; adresse.sin_port=htons(port); if(connect(s,(struct sockaddr *)&adresse,taille)<0) return -1; else return s; }
int connexionServeur(char *hote,int port) { int s; struct sockaddr_in6 adresse; socklen_t taille=sizeof adresse; int statut; /* Creation d'une socket */ s=socket(PF_INET6,SOCK_STREAM,0); if(s<0){ perror("connexionServeur.socket"); exit(-1); } /* Connection de la socket a l'hote */ adresse.sin6_family=AF_INET6; if(nomVersAdresse(hote,(void *)&adresse)<0) return -1; adresse.sin6_port=htons(port); adresse.sin6_flowinfo=0; adresse.sin6_scope_id=0; if(connect(s,(struct sockaddr *)&adresse,taille)<0) return -1; else return s; }
int connexionServeur(char *hote,char *service){ struct addrinfo precisions,*resultat,*origine; int statut; int s; /* Creation de l'adresse de socket */ memset(&precisions,0,sizeof precisions); precisions.ai_family=AF_UNSPEC; precisions.ai_socktype=SOCK_STREAM; statut=getaddrinfo(hote,service,&precisions,&origine); if(statut<0){ perror("connexionServeur.getaddrinfo"); exit(EXIT_FAILURE); } struct addrinfo *p; for(p=origine,resultat=origine;p!=NULL;p=p->ai_next) if(p->ai_family==AF_INET6){ resultat=p; break; } /* Creation d'une socket */ s=socket(resultat->ai_family,resultat->ai_socktype,resultat->ai_protocol); if(s<0){ perror("connexionServeur.socket"); exit(EXIT_FAILURE); } /* Connection de la socket a l'hote */ if(connect(s,resultat->ai_addr,resultat->ai_addrlen)<0) { freeaddrinfo(origine); shutdown(s,SHUT_RDWR); return -1; } /* Liberation de la structure d'informations */ freeaddrinfo(origine); return s; }
int main(int argc,char *argv[]) { int s; /* Lecture des arguments de la commande */ analyseArguments(argc,argv); /* Connection au serveur */ s=connexionServeur(machine,port); if(s<0){ fprintf(stderr,"Erreur de connexion au serveur\n"); exit(EXIT_FAILURE); } /* Boucle de communication avec le serveur */ struct pollfd descripteurs[2]; descripteurs[0].fd=s; descripteurs[0].events=POLLIN; descripteurs[1].fd=0; descripteurs[1].events=POLLIN; while(1){ char tampon[MAX_TAMPON]; int nb=poll(descripteurs,2,-1); if(nb<0){ perror("main.poll"); exit(EXIT_FAILURE); } if((descripteurs[0].revents&POLLIN)!=0){ int taille=read(s,tampon,MAX_TAMPON); if(taille<=0) break; write(1,tampon,taille); } if((descripteurs[1].revents&POLLIN)!=0){ int taille=read(0,tampon,MAX_TAMPON); if(taille<=0) break; write(s,tampon,taille); } } /* On termine la connexion */ shutdown(s,SHUT_RDWR); return 0; }
#include <sys/types.h> #include <sys/socket.h> int sendto(int sockfd,char *message,int size,int flag, struct sockaddr *address,socklen_t length);
#include <sys/types.h> #include <sys/socket.h> int recvfrom(int sockfd,char *message,int size,int flag, struct sockaddr *address,socklen_t *length);
#include <sys/types.h> #include <sys/socket.h> int send(int sockfd,char *message,int size,int flag); int recv(int s,char *message,int size,int flag);
static void sig_urg(int signo){ int n; char c; if((n=recv(servfd,&c,1,MSG_OOB))<0){ perror("recv error"); exit(-1); } ... } int main(void){ ... signal(SIGURG,sig_urg); ... }
int main(int argc,char *argv[]) { int s; /* Descripteur de la SOCKET */ struct sockaddr_in6 adresseServeur; /* Structure adresse du serveur */ socklen_t taille=sizeof adresseServeur; int statut; /* Lecture des arguments de la commande */ analyseArguments(argc,argv); /* Creation de la SOCKET d'ecoute du serveur */ s=socket(PF_INET6,SOCK_DGRAM,0); if(s<0) {perror("socket"); exit(-1);} /* Preparation de la structure adresse du serveur */ adresseServeur.sin6_family=AF_INET6; adresseServeur.sin6_addr=in6addr_any; adresseServeur.sin6_port=htons(SERVEUR_PORT); adresseServeur.sin6_flowinfo=0; adresseServeur.sin6_scope_id=0; /* Installation du serveur a la bonne adresse */ statut=bind(s,(struct sockaddr *)&adresseServeur,taille); if(statut<0) {perror("bind"); exit(-1);} /* Attente de la connexion d'un client puis dialogue avec ce client */ while(1){ struct sockaddr_in6 adresseClient; /* Structure adresse du client */ socklen_t taille=sizeof adresseClient; /* Taille de cette adresse */ char tampon1[MAX_TAMPON]; char tampon2[MAX_TAMPON]; int nboctets; nboctets=recvfrom(s,tampon1,MAX_TAMPON-1,0, (struct sockaddr *)&adresseClient, &taille); tampon1[nboctets]='\0'; sprintf(tampon2,"%s%s",PREFIXE,tampon1); sendto(s,tampon2,strlen(tampon2),0, (struct sockaddr *)&adresseClient,taille); } }
int initialisationSocketUDP(char *service){ struct addrinfo precisions,*resultat,*origine; int statut; int s; /* Construction de la structure adresse */ memset(&precisions,0,sizeof precisions); precisions.ai_family=AF_UNSPEC; precisions.ai_socktype=SOCK_DGRAM; precisions.ai_flags=AI_PASSIVE; statut=getaddrinfo(NULL,service,&precisions,&origine); if(statut<0){ perror("initialisationSocketUDP.getaddrinfo"); exit(EXIT_FAILURE); } struct addrinfo *p; for(p=origine,resultat=origine;p!=NULL;p=p->ai_next) if(p->ai_family==AF_INET6){ resultat=p; break; } /* Creation d'une socket */ s=socket(resultat->ai_family,resultat->ai_socktype,resultat->ai_protocol); if(s<0){ perror("initialisationSocketUDP.socket"); exit(EXIT_FAILURE); } /* Options utiles */ int vrai=1; if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&vrai,sizeof(vrai))<0){ perror("initialisationServeurUDPgenerique.setsockopt (REUSEADDR)"); exit(EXIT_FAILURE); } /* Specification de l'adresse de la socket */ statut=bind(s,resultat->ai_addr,resultat->ai_addrlen); if(statut<0){ freeaddrinfo(origine); shutdown(s,SHUT_RDWR); perror("initialisationServeurUDP.bind"); return -1; } /* Liberation de la structure d'informations */ freeaddrinfo(origine); return s; } int boucleServeurUDP(int s,int (*traitement)(unsigned char *,int,struct sockaddr *,int)){ while(1){ struct sockaddr_storage adresse; socklen_t taille=sizeof(adresse); unsigned char message[MAX_UDP_MESSAGE]; int nboctets=recvfrom(s,message,MAX_UDP_MESSAGE,0,(struct sockaddr *)&adresse,&taille); if(nboctets<0) return -1; if(traitement(message,nboctets,(struct sockaddr *)&adresse,taille)<0) break; } return 0; } int main(void){ int s=initialisationSocketUDP("4242"); if(s<0){ fprintf(stderr,"Port non utilisable\n"); exit(EXIT_FAILURE); } boucleServeurUDP(s,votreFonctionUDP); shutdown(s,SHUT_RDWR); return 0; }
int main(int argc,char *argv[]) { int s; /* Descripteur de SOCKET */ struct sockaddr_in6 adresse; /* Adresse de la SOCKET du serveur */ int statut; /* Stocke le statut des commandes */ /* Analyse des arguments */ analyseArguments(argc,argv); /* Creation de la SOCKET du client */ s=socket(PF_INET6,SOCK_DGRAM,0); if(s<0){perror("socket"); exit(-1);} /* Preparation de la structure adresse du serveur */ adresse.sin6_family=AF_INET6; if(nomVersAdresse(machine,(void *)&adresse)<0){ fprintf(stderr,"Impossible de trouver l'adresse IP du serveur !\n"); exit(-1); } adresse.sin6_port=htons(port); adresse.sin6_flowinfo=0; adresse.sin6_scope_id=0; /* Dialogue avec le serveur */ { char tampon[MAX_TAMPON]; int taille; fgets(tampon,MAX_TAMPON,stdin); sendto(s,tampon,strlen(tampon),0,(struct sockaddr *)&adresse,sizeof adresse); taille=recvfrom(s,tampon,MAX_TAMPON,0,NULL,NULL); fputs(tampon,stdout); } /* Fermeture de la SOCKET de dialogue */ close(s); exit(0); }
void messageUDP(char *hote,char *service,unsigned char *message,int taille){ struct addrinfo precisions,*resultat,*origine; int statut; int s; /* Creation de l'adresse de socket */ memset(&precisions,0,sizeof precisions); precisions.ai_family=AF_UNSPEC; precisions.ai_socktype=SOCK_DGRAM; statut=getaddrinfo(hote,service,&precisions,&origine); if(statut<0){ perror("messageUDPgenerique.getaddrinfo"); exit(EXIT_FAILURE); } struct addrinfo *p; for(p=origine,resultat=origine;p!=NULL;p=p->ai_next) if(p->ai_family==AF_INET6){ resultat=p; break; } /* Creation d'une socket */ s=socket(resultat->ai_family,resultat->ai_socktype,resultat->ai_protocol); if(s<0){ perror("messageUDPgenerique.socket"); exit(EXIT_FAILURE); } /* Option sur la socket */ int vrai=1; if(setsockopt(s,SOL_SOCKET,SO_BROADCAST,&vrai,sizeof(vrai))<0){ perror("initialisationServeurUDPgenerique.setsockopt (BROADCAST)"); exit(EXIT_FAILURE); } /* Envoi du message */ int nboctets=sendto(s,message,taille,0,resultat->ai_addr,resultat->ai_addrlen); if(nboctets<0){ perror("messageUDPgenerique.sento"); exit(EXIT_FAILURE); } /* Liberation de la structure d'informations */ freeaddrinfo(origine); /* Fermeture de la socket d'envoi */ shutdown(s,SHUT_RDWR); } int main(int argc,char *argv[]){ if(argc!=3){ fprintf(stderr,"Syntaxe : %s <serveur> <message>\n",argv[0]); exit(EXIT_FAILURE); } char *hote=argv[1]; char *message=argv[2]; char *service="4000"; messageUDP(hote,service,(unsigned char *)message,strlen(message)); return 0; }
#include <netdb.h> struct hostent *gethostbyname2(char *name,int type);
struct hostent { char *h_name; /* nom officiel */ char **h_aliases; /* liste des surnoms */ int h_addrtype; /* type de l'adressage */ int h_length; /* taille des adresses */ char **h_addr_list; /* liste des adresses */ }; #define h_addr h_addr_list[0]
#include <netdb.h> struct hostent *gethostbyaddr(char *address,socklen_t length,int type);
#include <arpa/inet.h> int inet_pton(int type,const char *string,void *address);
#include <sys/types.h> #include <sys/socket.h> #include <netdb.h> int getaddrinfo(char *name,char *service, struct addrinfo *hints, struct addrinfo **res); void freeaddrinfo(struct addrinfo *res);
struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; };
#include <sys/socket.h> #include <netdb.h> int getnameinfo(struct sockaddr *address,socklen_t length, char *name,size_t maxname,char *service,size_t maxservice, int flags);
#include <sys/socket.h> int getpeername(int sockfd,struct sockaddr *address,socklen_t length);
smtp 25/tcp mail time 37/tcp timserver domain 53/udp nameserver nntp 119/tcp readnews printer 515/tcp spooler talk 517/udp
#include <netdb.h> struct servent *getservbyname(char *name,char *protocol);
struct servent { char *s_name; /* nom officiel */ char **s_aliases; /* liste de surnoms */ int s_port; /* numero de port */ char *s_proto; /* protocole */ };
ip 0 IP icmp 1 ICMP tcp 6 TCP udp 17 UDP
#include <netdb.h> struct protoent *getprotobyname(char *name);
struct protoent { char *p_name; /* nom officiel */ char **p_aliases; /* liste des surnoms */ int p_proto; /* numero de protocole */ };
int nomVersAdresse(char *hote,struct sockaddr_storage *padresse) { /* On regarde deja s'il s'agit d'une adresse IP */ struct sockaddr_in *ipv4_sock=(struct sockaddr_in *)padresse; unsigned char *ipv4=(unsigned char *)&ipv4_sock->sin_addr; if(padresse->ss_family!=AF_INET6){ int size=inet_pton(AF_INET,hote,ipv4); if(size>0){ padresse->ss_family=AF_INET; return 0; } } struct sockaddr_in6 *ipv6_sock=(struct sockaddr_in6 *)padresse; unsigned char *ipv6=(unsigned char *)&ipv6_sock->sin6_addr; if(padresse->ss_family!=AF_INET){ int size=inet_pton(AF_INET6,hote,ipv6); if(size>0){ padresse->ss_family=AF_INET6; return 0; } } /* Sinon on cherche l'adresse via le DNS */ if(padresse->ss_family!=AF_INET){ struct hostent *h=gethostbyname2(hote,AF_INET6); if(h!=NULL){ memcpy(ipv6,h->h_addr_list[0],h->h_length); padresse->ss_family=AF_INET6; return 0; } } if(padresse->ss_family!=AF_INET6){ struct hostent *h=gethostbyname2(hote,AF_INET); if(h!=NULL){ memcpy(ipv4,h->h_addr_list[0],h->h_length); padresse->ss_family=AF_INET; return 0; } } return -1; }
int nomVersAdresse(char *hote,struct sockaddr_storage *padresse) { struct addrinfo *resultat,*origine; statut=getaddrinfo(hote,NULL,NULL,&origine); if(statut==EAI_NONAME) return -1; if(statut<0){ perror("nomVersAdresse.getaddrinfo"); exit(EXIT_FAILURE); } struct addrinfo *p; for(p=origine,resultat=origine;p!=NULL;p=p->ai_next) if(p->ai_family==AF_INET6){ resultat=p; break; } memcpy(padresse,resultat->ai_addr,resultat->ai_addrlen); return 0; }
int socketVersNom(int s,char *nom) { struct sockaddr_storage adresse; struct sockaddr *padresse=(struct sockaddr *)&adresse; socklen_t taille=sizeof adresse; int statut; struct hostent *machine; /* Recupere l'adresse de la socket distante */ statut=getpeername(s,padresse,&taille); if(statut<0){ perror("socketVersNom.getpeername"); exit(-1); } /* Recupere le nom de la machine */ void *ip; int taille_ip; int taille_nom; if(padresse->sa_family==AF_INET){ struct sockaddr_in *ipv4=(struct sockaddr_in *)padresse; ip=(void *)&ipv4->sin_addr; taille_ip=sizeof(ipv4->sin_addr); taille_nom=INET_ADDRSTRLEN; } if(padresse->sa_family==AF_INET6){ struct sockaddr_in6 *ipv6=(struct sockaddr_in6 *)padresse; ip=(void *)&ipv6->sin6_addr; taille_ip=sizeof(ipv6->sin6_addr); taille_nom=INET6_ADDRSTRLEN; } machine=gethostbyaddr(ip,taille_ip,padresse->sa_family); if(machine==NULL){ inet_ntop(padresse->sa_family,ip,nom,taille_nom); return -1; } else{ strcpy(nom,machine->h_name); return 0; } }
void socketVersClient(int s,char **hote,char **service){ struct sockaddr_storage adresse; socklen_t taille=sizeof adresse; int statut; /* Recupere l'adresse de la socket distante */ statut=getpeername(s,(struct sockaddr *)&adresse,&taille); if(statut<0){ perror("socketVersNom.getpeername"); exit(EXIT_FAILURE); } /* Recupere le nom de la machine */ *hote=malloc(MAX_TAMPON); if(*hote==NULL){ perror("socketVersClient.malloc"); exit(EXIT_FAILURE); } *service=malloc(MAX_TAMPON); if(*service==NULL){ perror("socketVersClient.malloc"); exit(EXIT_FAILURE); } getnameinfo((struct sockaddr *)&adresse,sizeof adresse,*hote,MAX_TAMPON,*service,MAX_TAMPON,0); }
int cherchePortTCP(char *nom) { struct servent *pinfo; pinfo=getservbyname(nom,"tcp"); return ntohs(pinfo->s_port); }
#include <unistd.h> int daemon (int nochdir, int noclose);
service | voir /etc/services |
mode | soit dgram, soit stream |
protocole | voir /etc/protocols |
traitement | soit nowait, soit wait |
user | généralement root |
exécutable | chemin complet du serveur |
arguments | arguments de l’exécutable |
ftp stream tcp nowait root /usr/sbin/wu.ftpd wu.ftpd telnet stream tcp nowait root /usr/sbin/in.telnetd in.telnetd talk dgram udp wait root /usr/sbin/in.ntalkd in.ntalkd pop3 stream tcp nowait root /usr/sbin/in.pop3d in.pop3d
int main(int argc,char **argv) { char *url; /* Nom du fichier demande */ /* Ouverture de la session SYSLOG */ openlog(NOM_SERVEUR,LOG_PID,LOG_DAEMON); syslog(LOG_INFO,"Traitement d'une requete"); /* Envoi eventuel du fichier demande */ url=requeteValide(stdin); if(url!=NULL){ char *type=typeDeFichier(url); printf("%s\nContent-Type: %s\n\n",REP_SUCCES,type); envoiFichier(url,stdout); syslog(LOG_INFO,"Succes, fichier %s envoye",url); } else{ printf("%s\n",REP_ERREUR); syslog(LOG_INFO,"Echec, requete invalide ",url); } /* Fermeture de la session SYSLOG */ syslog(LOG_INFO,"Fin du traitement de la requete"); closelog(); exit(0); }
int main(int argc,char **argv) { char tampon[MAX_TAMPON]; /* Stocke le message de la sonde */ int longueur; /* Longueur du message */ char reponse[MAX_TAMPON]; /* Stocke la reponse a la sonde */ struct sockaddr_in adresse; /* Adresse de socket de l'emetteur */ int taille=sizeof(adresse); /* Taille de cette adresse */ /* Ouverture de la session SYSLOG */ openlog(NOM_SERVEUR,LOG_PID,LOG_DAEMON); syslog(LOG_INFO,"Traitement d'un paquet-sonde"); /* On retourne les donnees avec un prefixe */ longueur=recvfrom(0,tampon,MAX_TAMPON-1,0,&adresse,&taille); tampon[longueur]='\0'; { char *texte=inet_ntoa(adresse.sin_addr); syslog(LOG_INFO,"Sonde en provenance de %s",texte); } sprintf(reponse,"%s%s",ECHO_PREFIXE,tampon); sendto(0,reponse,strlen(reponse),0,&adresse,taille); /* Fermeture de la session SYSLOG */ syslog(LOG_INFO,"Fin du traitement"); closelog(); exit(0); }
$ strace nc -l -p 4000 ... socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 bind(3, {sin_family=AF_INET, sin_port=htons(4000), sin_addr=inet_addr("0.0.0.0")}}, 16) = 0 listen(3, 1) = 0 rt_sigaction(SIGALRM, {SIG_IGN}, {SIG_DFL}, 8) = 0 alarm(0) = 0 accept(3,
# strace -f /usr/sbin/ftpd -s -p 2121 # strace ftp localhost 2121
# strace -f nc -u -l -p 4000 ... socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 bind(3, {sin_family=AF_INET, sin_port=htons(4000), sin_addr=inet_addr("0.0.0.0")}}, 16) = 0 rt_sigaction(SIGALRM, {SIG_IGN}, {SIG_DFL}, 8) = 0 alarm(0) = 0 recvfrom(3, ... ... {sin_family=AF_INET, sin_port=htons(4000), sin_addr=inet_addr("127.0.0.1")}}, [16]) = 0 select(16, [0 3], NULL, NULL, NULL) = 1 (in [3]) read(3, "\n", 8192) = 1 write(1, "\n", 1) = 1 ... # strace nc -u localhost 4000 socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 rt_sigaction(SIGALRM, {SIG_IGN}, {SIG_DFL}, 8) = 0 alarm(0) = 0 connect(3, {sin_family=AF_INET, sin_port=htons(4000), sin_addr=inet_addr("127.0.0.1")}}, 16) = 0 rt_sigaction(SIGALRM, {SIG_IGN}, {SIG_IGN}, 8) = 0 alarm(0) = 0 select(16, [0 3], NULL, NULL, NULL) = 1 (in [0]) read(0, "\n", 8192) = 1 write(3, "\n", 1) = 1 ...
# # <service_name> <sock_type> <proto> <flags> <user> <server_path> <args> # #:INTERNAL: Internal services # echo stream tcp nowait root internal echo dgram udp wait root internal chargen stream tcp nowait root internal chargen dgram udp wait root internal discard stream tcp nowait root internal discard dgram udp wait root internal daytime stream tcp nowait root internal daytime dgram udp wait root internal time stream tcp nowait root internal time dgram udp wait root internal #:STANDARD: These are standard services. # telnet stream tcp nowait telnetd.telnetd /usr/sbin/tcpd /usr/sbin/in.telnetd ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/wu-ftpd -l telnet stream tcp nowait telnetd.telnetd /usr/sbin/tcpd /usr/sbin/in.telnetd #:BSD: Shell, login, exec and talk are BSD protocols. # shell stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.rshd login stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.rlogind exec stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.rexecd talk dgram udp wait root.tty /usr/sbin/tcpd /usr/sbin/kotalkd ntalk dgram udp wait root.tty /usr/sbin/tcpd /usr/sbin/ktalkd
#!/bin/sh # # Exemple de serveur HTTP en shell # # # Quelques constantes # NC=/usr/bin/nc PORT=8080 TTY_PREFIXE=/dev/tty PTY_PREFIXE=/dev/pty TTY_NUMERO=q3 REPERTOIRE=${HOME}/Scripts/Web # # Boucle principale # (ecoute sur le port, traitement de la requete, envoi du fichier) # while true ; do # # On ecoute sur le cote maitre du terminal virtuel # ${NC} -l -p ${PORT} 4<>${PTY_PREFIXE}${TTY_NUMERO} >&4 2>&4 <&4 & PID=$! # # On lance un sous-shell sur le cote esclave # ( stty -echo igncr # # Lecture de la requete HTTP # read requete # # Lecture des entetes (mises a la poubelle) # while read line ; do if [ -z "${line}" ] ; then break ; fi done # # Analyse de la requete # set -- ${requete} commande=$1 ; file=$2 ; protocole=$3 # # Reponse a la requete # if [ "${commande}" != "GET" -o ! -f "${REPERTOIRE}/${file}" ] ; then echo "${protocole} 400 erreur" echo echo "Erreur !!" else echo "${protocole} 200 OK" echo "Content-type: text/html" echo cat "${REPERTOIRE}/${file}" fi ) 4<>${TTY_PREFIXE}${TTY_NUMERO} >&4 2>&4 <&4 # # On stoppe l'ecoute # kill ${PID} sleep 2 done
<html> <head> <title>Serveur web de demonstration</title> </head> Voici deux p't liens : <dl> <dt> <a href="/fichier1">Premier fichier</a> <dt> <a href="/fichier2">Second fichier</a> </dl> <p align=right> Serveur Script </p> </body> </html>
#!/bin/bash WEB_DIR=`dirname $0`/www/ NOT_FOUND=error.html read cmd page proto echo $cmd $page $proto >> /tmp/log while read line ; do echo $line >> /tmp/log if [ "$line" = " " ] ; then break ; fi done if [ "$cmd" = GET ] ; then path=${WEB_DIR}$page code=200 if [ ! -f "$path" ] ; then path=${WEB_DIR}/${NOT_FOUND} code=404 fi case `basename $path` in *.png) type="image/png";; *.html) type="text/html";; esac size=`cat $path | wc -c` echo "HTTP/1.0 $code" echo "Server: ShellWeb" echo "Content-type: $type" echo "Content-length: $size" echo cat $path fi
/**** Minimal web server ****/ /** Include files **/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> /** Some constants **/ #define WEB_DIR "./www" #define PAGE_NOTFOUND "error.html" #define MAX_BUFFER 1024 #define CODE_OK 200 #define CODE_NOTFOUND 404 /** Main procedure **/ int main(void){ char buffer[MAX_BUFFER]; char cmd[MAX_BUFFER]; char page[MAX_BUFFER]; char proto[MAX_BUFFER]; char path[MAX_BUFFER]; char type[MAX_BUFFER]; if(fgets(buffer,MAX_BUFFER,stdin)==NULL) exit(-1); if(sscanf(buffer,"%s %s %s",cmd,page,proto)!=3) exit(-1); while(fgets(buffer,MAX_BUFFER,stdin)!=NULL){ if(strcmp(buffer,"\r\n")==0) break; } if(strcasecmp(cmd,"GET")==0){ int code=CODE_OK; struct stat fstat; sprintf(path,"%s%s",WEB_DIR,page); if(stat(path,&fstat)!=0 || !S_ISREG(fstat.st_mode)){ sprintf(path,"%s/%s",WEB_DIR,PAGE_NOTFOUND); code=CODE_NOTFOUND; } strcpy(type,"text/html"); char *end=page+strlen(page); if(strcmp(end-4,".png")==0) strcpy(type,"image/png"); if(strcmp(end-4,".jpg")==0) strcpy(type,"image/jpg"); if(strcmp(end-4,".gif")==0) strcpy(type,"image/gif"); fprintf(stdout,"HTTP/1.0 %d\r\n",code); fprintf(stdout,"Server: CWeb\r\n"); fprintf(stdout,"Content-type: %s\r\n",type); fprintf(stdout,"Content-length: %d\r\n",fstat.st_size); fprintf(stdout,"\r\n"); fflush(stdout); int fd=open(path,O_RDONLY); if(fd>=0){ int bytes; while((bytes=read(fd,buffer,MAX_BUFFER))>0) write(1,buffer,bytes); close(fd); } } }
while true ; do nc -l -p 80 -c ./web ; done
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <HTML> <HEAD> <TITLE>Serveur d'enseignement de Polytech'Lille</TITLE> </HEAD> <BODY> <TABLE BORDER=0 WIDTH=100% HEIGHT=100%> <TR><TD VALIGN=center> <CENTER> <IMG ALT="" SRC="elephant.png"> </CENTER> </TD></TR> </TABLE> </BODY> </HTML>
# # Generation d'un client et d'un serveur RPC de demonstration # (simple addition et soustraction d'entiers). # # Quelques constantes liees au projet CLIENT_OBJS=calc_client.o calc_clnt.o calc_xdr.o SERVER_OBJS=calc_server.o calc_svc.o calc_xdr.o # Message pour la marche a suivre all: @echo -e "\ Tapez d'abord make generate pour obtenir le fichier d'inclusion .h et\n\ les fichiers C. Modifiez les programmes calc_client.c et calc_server.c\n\ puis lancez la compilation par make compile." # Generation des fichiers C par rpcgen generate: calc.x rpcgen -a -C $^ # Copie des fichiers modifies a la main sur leurs modeles copy: cp calc_client_modified.c calc_client.c cp calc_server_modified.c calc_server.c # Compilation des programmes C compile: client server client: ${CLIENT_OBJS} calc.h gcc -o client ${CLIENT_OBJS} server: ${SERVER_OBJS} calc.h gcc -o server ${SERVER_OBJS} # Regle de nettoyage clean: rm -f client server *.o calc.h calc_svc.c calc_clnt.c calc_xdr.c rm -f calc_client.c calc_server.c
/********************************************************************/ /** Fichier de definition de RPC d'addition et de soustraction **/ /********************************************************************/ /** Quelques constantes **/ #define PROGRAM_NUMBER 19992000 #define VERSION_NUMBER 1 /** Structures des parametres des procedures **/ struct operandes { int x; int y; }; /** Definition des RPC **/ program CALC_PROG { version CALC_VERSION { int ADD(operandes) = 1; int SUB(operandes) = 2; } = VERSION_NUMBER; } = PROGRAM_NUMBER;
/* * This is sample code generated by rpcgen. * These are only templates and you can use them * as a guideline for developing your own functions. */ #include "calc.h" int * add_1_svc(operandes *argp, struct svc_req *rqstp) { static int result; /* AJOUT DE CODE : implantation de l'addition */ result=argp->x+argp->y; /* FIN D'AJOUT DE CODE */ return(&result); } int * sub_1_svc(operandes *argp, struct svc_req *rqstp) { static int result; /* AJOUT DE CODE : implantation de la soustraction */ result=argp->x-argp->y; /* FIN D'AJOUT DE CODE */ return(&result); }
/* * This is sample code generated by rpcgen. * These are only templates and you can use them * as a guideline for developing your own functions. */ #include "calc.h" void /** MODIFICATION DE CODE : ajout des operandes en parametre **/ calc_prog_1( char* host, int x, int y ) /** FIN DE MODIFICATION DE CODE **/ { CLIENT *clnt; int *result_1; operandes add_1_arg; int *result_2; operandes sub_1_arg; clnt = clnt_create(host, CALC_PROG, CALC_VERSION, "udp"); if (clnt == NULL) { clnt_pcreateerror(host); exit(1); } /** AJOUT DE CODE : initialisation du parametre de la RPC **/ add_1_arg.x = x ; add_1_arg.y = y ; /** FIN D'AJOUT DE CODE **/ result_1 = add_1(&add_1_arg, clnt); if (result_1 == NULL) { clnt_perror(clnt, "call failed:"); } /** AJOUT DE CODE : affichage du resultat de la RPC **/ printf("%d + %d = %d\n",add_1_arg.x,add_1_arg.y,*result_1); /** FIN D'AJOUT DE CODE **/ /** AJOUT DE CODE : initialisation du parametre de la RPC **/ sub_1_arg.x = x ; sub_1_arg.y = y ; /** FIN D'AJOUT DE CODE **/ result_2 = sub_1(&sub_1_arg, clnt); if (result_2 == NULL) { clnt_perror(clnt, "call failed:"); } /** AJOUT DE CODE : affichage du resultat de la RPC **/ printf("%d - %d = %d\n",sub_1_arg.x,sub_1_arg.y,*result_2); /** FIN D'AJOUT DE CODE **/ clnt_destroy( clnt ); } main( int argc, char* argv[] ) { char *host; /** AJOUT DE CODE : variables pour les operandes **/ int x,y; /** FIN D'AJOUT DE CODE **/ /** MODIFICATION DE CODE : nouvelle syntaxe **/ if(argc < 4) { printf("usage: %s server_host op1 op2\n", argv[0]); /** FIN DE MODIFICATION DE CODE **/ exit(1); } host = argv[1]; /** MODIFICATION DE CODE : recuperation et utilisation des operandes **/ x = atoi(argv[2]); y = atoi(argv[3]); calc_prog_1( host, x, y ); /** FIN DE MODIFICATION DE CODE **/ }
Ce document a été traduit de LATEX par HEVEA