seToNc : Serial To Netcat ou comment envoyer via le réseau des informations reçues sur le port série
Salut salut!
Je vous présenterai aujourd’hui la programmation d’un petit soft sous linux en C qui permet de récupérer des données envoyées sur le port USB de la machine, de les formater et de les renvoyer sur le réseau (en clair). Commençons donc tout de suite avec une petite description algorithmique:
Le programme s’occupera de créer un processus fils qui éxecutera netcat (outil de communication réseau), le processus père lira la liaison série pour envoyer toutes les données au fils, qui lui enverra le tout sur le réseau. Je me sers des fork() pour créer un processus fils, et des pipes pour communiquer entre ces deux processus, j’utilise ensuite dup2() pour rediriger la lecture standard sur le pipe crée puis la primitive execlp() pour éxecuter une commande. Voici donc le code, séparé dans deux fichiers:
seToNc.c
/** Nom: SerieToNetcat Description: Récupère les informations envoyées sur le port série et les renvoie par netcat à l'adresse ip via le port donnés en paramêtre. **/ #include#include #include #include #include #include #include #include #include #include #include int MAX = 300; pid_t idp; int fd; void traiteSig(int); char readChar(); int main(int argc, char* argv[]) { signal(SIGINT, traiteSig); int descP[2], next = 1; char *msg0 = "Erreur lors de la lecture du port sérien"; char *msg1 = "Erreur lors du pipen"; char *msg2 = "Erreur lors du forkn"; char *msg3 = "Erreur lors de l'execn"; char buff[10]; //Test d'une bonne utilisation if (argc != 3) { printf("Usage: setonc ipAddress Portn"); exit(1); } /* Ouverture de la liaison serie */ if ( (fd=open("/dev/ttyACM0",O_RDONLY)) == -1 ) { printf("%s", msg0); exit(1); } char *ip = argv[1]; char *port = argv[2]; //Création du pipe int verif = pipe(descP); if (verif == -1) { printf("%s", msg1); exit(1); } //Création du processus fils, qui lancera netcat if ((idp = fork()) == -1 ) { printf("%s", msg2); exit(2); } //Si le proccessus fils est en run if (idp == 0) { close(descP[1]); //On ferme l'accès en lecture dup2(descP[0], 0); execlp("nc", "netcat", ip, port, NULL); printf("%s", msg3); exit(3); } else { close(descP[0]); //On ferme l'accès en écriture //On tourne en boucle pour envoyer les données reçues sur le port série while (1) { //On récupère les données sur le port série buff[0] = readChar(fd); next = write(descP[1], buff, 1); } } } void traiteSig(int signal) { int code; /* Fermeture du port serie */ close(fd); printf("nFin de la connexionn"); wait(&code); //Le père attend la fin du processus fils (passé en zombie) pr le killer exit(0); }
Voici le code du fichier readChar.c
#include#include char readChar(int fd) { char c; struct termios termios_p; /* Lecture des parametres courants */ tcgetattr(fd,&termios_p); /* On ignore les BREAK et les caracteres avec erreurs de parite */ termios_p.c_iflag = IGNBRK | IGNPAR; /* Pas de mode de sortie particulier */ termios_p.c_oflag = 0; /* Liaison a 9600 bps avec 7 bits de donnees et une parite paire */ termios_p.c_cflag = B9600 | CS7 | PARENB; /* Mode non-canonique avec echo */ termios_p.c_lflag = ECHO; /* Caracteres immediatement disponibles */ termios_p.c_cc[VMIN] = 1; termios_p.c_cc[VTIME] = 0; /* Sauvegarde des nouveaux parametres */ tcsetattr(fd,TCSANOW,&termios_p); /* Lecture */ read(fd,&c,1); return c; }
Il suffit alors de taper la commande suivante pour compiler le programme et le tour est joué:
gcc -o seToNc seToNc.c readChar.c
J’essairai par la suite de faire une deuxième version du programme, en utilisant les threads et les sockets ou bien les segments de mémoire partagés. Je ne maîtrise pas encore parfaitement ces notions alors j’y vais petit à petit! En ce qui concerne l’intérêt du programme, il me sert à récupérer des données provenant des montages Arduino que je fais.
Bon codage!
Laisser un commentaire