SERVEUR ET CLIENT OK : Nouvelle version du serveur avec un tableau

This commit is contained in:
Paul Faure 2021-02-07 13:31:21 +01:00
parent 28cca06320
commit 758d24ff55
4 changed files with 236 additions and 220 deletions

133
Client.c
View file

@ -12,13 +12,9 @@
#include <stdio.h>
/* la lib standard */
#include <stdlib.h>
/* pour le fork */
#include <unistd.h>
/* pour memcpy */
#include <string.h>
/* pour le scanf permissif */
#define SIZE_MAX 32767
#include <unistd.h>
int main (int argc, char * argv[]) {
@ -55,29 +51,116 @@ int main (int argc, char * argv[]) {
exit(1);
}
printf("Que souhaitez vous faire : [PRINT|ADD|SUB|MUL|DIV|RESET|GET]\n");
printf("Que souhaitez vous faire : \n - READ 'index'\n - WRITE 'value' 'index'\n - ADD 'index1' 'index2' 'index3'\n - SUB 'index1' 'index2' 'index3'\n - MUL 'index1' 'index2' 'index3'\n - DIV 'index1' 'index2' 'index3'\n - LOWER 'index1' 'index2'\n - EQUAL 'index1' 'index2'\n - PRINT\n - QUIT\n");
int cont = 1;
while (cont) {
// Lecture de la requette
char buff[SIZE_MAX];
scanf("%s", buff);
// Lecture de la requette
char requette[40];
fgets(requette, 40, stdin);
char req[10] = "\0";
int param1 = -1;
int param2 = -1;
int param3 = -1;
sscanf(requette, "%s %d %d %d", req, &param1, &param2, &param3);
// Envoi de la requette
send(sock, buff, strlen(buff), 0);
// Si arg en envoyer ou réponse a recevoir
if (!strcmp(buff, "ADD") || !strcmp(buff, "SUB") || !strcmp(buff, "MUL") || !strcmp(buff, "DIV")) {
printf("Veuillez saisir l'argument\n");
// Lecture de l'argument
int arg;
scanf("%d", &arg);
// Envoi de la requette
sprintf(buff, "%d", arg);
send(sock, buff, strlen(buff), 0);
} else if (!strcmp(buff, "GET")) {
char buffer[SIZE_MAX];
read(sock, buffer, SIZE_MAX);
printf("La valeur est : %s\n", buffer);
}
char buff[40] = "\0";
if (!strcmp(req, "READ")) {
if (param1 < 0) {
printf("ERROR SYNTAX\n");
} else {
sprintf(buff, "r.%d.0.0", param1);
send(sock, buff, strlen(buff), 0);
read(sock, buff, 40);
printf("Tableau[%d] = %s\n", param1, buff);
}
} else if (!strcmp(req, "WRITE")) {
if (param2 < 0) {
printf("ERROR SYNTAX\n");
} else {
sprintf(buff, "w.%d.%d.0", param1, param2);
send(sock, buff, strlen(buff), 0);
}
} else if (!strcmp(req, "ADD")) {
if (param1 < 0 || param2 < 0 || param3 < 0) {
printf("ERROR SYNTAX\n");
} else {
sprintf(buff, "a.%d.%d.%d", param1, param2, param3);
send(sock, buff, strlen(buff), 0);
}
} else if (!strcmp(req, "SUB")) {
if (param1 < 0 || param2 < 0 || param3 < 0) {
printf("ERROR SYNTAX\n");
} else {
sprintf(buff, "s.%d.%d.%d", param1, param2, param3);
send(sock, buff, strlen(buff), 0);
}
} else if (!strcmp(req, "MUL")) {
if (param1 < 0 || param2 < 0 || param3 < 0) {
printf("ERROR SYNTAX\n");
} else {
sprintf(buff, "m.%d.%d.%d", param1, param2, param3);
send(sock, buff, strlen(buff), 0);
}
} else if (!strcmp(req, "DIV")) {
if (param1 < 0 || param2 < 0 || param3 < 0) {
printf("ERROR SYNTAX\n");
} else {
sprintf(buff, "d.%d.%d.%d", param1, param2, param3);
send(sock, buff, strlen(buff), 0);
}
} else if (!strcmp(req, "LOWER")) {
if (param1 < 0 || param2 < 0) {
printf("ERROR SYNTAX\n");
} else {
sprintf(buff, "l.%d.%d.0", param1, param2);
send(sock, buff, strlen(buff), 0);
char retour[2];
read(sock, retour, 2);
char res[6];
if (!strcmp(retour, "1")) {
strcpy(res, "TRUE");
} else if (!strcmp(retour, "0")) {
strcpy(res, "FALSE");
} else {
strcpy(res, "ERROR");
}
printf("Tableau[%d] < Tableau[%d] => %s\n", param1, param2, res);
}
} else if (!strcmp(req, "EQUAL")) {
if (param1 < 0 || param2 < 0) {
printf("ERROR SYNTAX\n");
} else {
sprintf(buff, "e.%d.%d.0", param1, param2);
send(sock, buff, strlen(buff), 0);
char retour[2];
read(sock, retour, 2);
char res[6];
if (!strcmp(retour, "1")) {
strcpy(res, "TRUE");
} else if (!strcmp(retour, "0")) {
strcpy(res, "FALSE");
} else {
strcpy(res, "ERROR");
}
printf("Tableau[%d] == Tableau[%d] => %s\n", param1, param2, res);
}
} else if (!strcmp(req, "PRINT")) {
sprintf(buff, "p.0.0.0");
send(sock, buff, strlen(buff), 0);
} else if (!strcmp(req, "QUIT")) {
sprintf(buff, "q.0.0.0");
send(sock, buff, strlen(buff), 0);
cont = 0;
} else {
printf("SYNTAX ERROR\n");
}
}
close(sock);
return 0;

294
Serveur.c
View file

@ -13,57 +13,33 @@
#include <stdlib.h>
/* pour le fork */
#include <unistd.h>
/* pour la SHM */
#include <sys/shm.h>
#include <sys/sem.h>
#include <signal.h>
/* pour la manipulation des strings */
#include <string.h>
/* pour le read permissif */
#define SIZE_MAX 32767
/* Taille du tableau d'int fourni au client */
#define SIZE_TAB 128
// Pour la SHM
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
#define NB_SEP 65
#define NB_PAR_LIGNE 16
// L'adresse de la SHM en variable globale pour qu'elle soit accessible depuis les fonctions
int * addr_shm;
// fonctions de manipulation de la SHM
void print_shm() {
printf("La valeur est : %d\n", *addr_shm);
//printf("BEFORE: %p\n", __builtin_return_address(0));
void handle_sigsegv(int signum)
{
fprintf(stderr,"Signal SIGSEGV (%d) received : SEG FAULT\n", signum);
_exit(0);
}
void add(int n) {
*addr_shm += n;
}
void sub(int n) {
*addr_shm -= n;
}
void mul(int n) {
*addr_shm *= n;
}
void divi(int n) {
*addr_shm /= n;
}
void reset() {
printf("Hello ça marche\n");
*addr_shm = 0;
}
int get() {
return *addr_shm;
int min(int a, int b) {
if (a<b) {
return a;
} else {
return b;
}
}
// affichage du nombre de connexions
@ -78,116 +54,106 @@ void print_nb_connexions(int nb_connexions) {
printf("L'adresse du nombre de connexions est : %p\n", &nb_connexions);
}
// Structure pour le traitement des requettes client
struct traitement {
int action;
int arg;
};
// Fonction traitant la phrase reçu et renvoyant une structure traitement
// Fonction qui sera exploitable
struct traitement process(int sock) {
char buff[200];
// PRIMITIVE READ TRES MAL UTILISEE VOLONTAIREMENT
read(sock, buff, SIZE_MAX);
printf("Affichage de la PILE : \n addr buff : %p\n socket : %d\n", buff, sock);
int i;
for (i=0; i<220; i++) {
if (i != 0 && i % 4 == 0) {
printf(" ");
}
printf("%2.2hhx", buff[i]);
void print_ligne(int * ligne, int n) {
printf("|");
int i;
for (i=0; i<n; i++) {
printf(" %d |", ligne[i]);
}
printf("\n");
struct traitement ret;
if (!strncmp(buff, "PRINT", 5)) {
ret.action = 1;
} else if (!strncmp(buff, "ADD", 3)) {
ret.action = 2;
read(sock, buff, SIZE_MAX);
ret.arg = atoi(buff);
} else if (!strncmp(buff, "SUB", 3)) {
ret.action = 3;
read(sock, buff, SIZE_MAX);
ret.arg = atoi(buff);
} else if (!strncmp(buff, "MUL", 3)) {
ret.action = 4;
read(sock, buff, SIZE_MAX);
ret.arg = atoi(buff);
} else if (!strncmp(buff, "DIV", 3)) {
ret.action = 5;
read(sock, buff, SIZE_MAX);
ret.arg = atoi(buff);
} else if (!strncmp(buff, "RESET", 5)) {
ret.action = 6;
} else if (!strncmp(buff, "GET", 3)) {
ret.action = 7;
} else {
ret.action = 8;
}
return ret;
}
int main(int argc, char * argv[])
{
printf("L'adresse de la fonction reset est : %p\n", reset);
void print_sep() {
int i;
for (i=0; i<NB_SEP; i++) {
printf("-");
}
printf("\n");
}
void print_tab(int * tab, int n) {
print_sep();
int i;
for (i=0; i<n; i+=NB_PAR_LIGNE) {
print_ligne(&(tab[i]), min(n-i, NB_PAR_LIGNE));
print_sep();
}
}
// Fonction lancée a chaque fork
void process(int sock) {
// Tableau des datas du client
int tab[SIZE_TAB];
// initialisation (tt a 0)
int i;
for (i=0; i<SIZE_TAB; i++) {
tab[i] = 0;
}
int quit = 0;
while (quit == 0) {
// récupération de l'input du client
char buff[40] = "\0";
read(sock, buff, 40);
char what;
int param1;
int param2;
int param3;
sscanf(buff, "%c.%d.%d.%d", &what, &param1, &param2, &param3);
printf("%c.%d.%d.%d\n", what, param1, param2, param3);
if (what == 'r') {
char buff_envoi[40];
sprintf(buff_envoi, "%d", tab[param1]);
send(sock, buff_envoi, strlen(buff_envoi), 0);
} else if (what == 'w') {
tab[param2] = param1;
} else if (what == 'a') {
tab[param1] = tab[param2] + tab[param3];
} else if (what == 's') {
tab[param1] = tab[param2] - tab[param3];
} else if (what == 'm') {
tab[param1] = tab[param2] * tab[param3];
} else if (what == 'd') {
tab[param1] = tab[param2] / tab[param3];
} else if (what == 'l') {
if (tab[param1] < tab[param2]) {
send(sock, "1", 1, 0);
} else {
send(sock, "0", 1, 0);
}
} else if (what == 'e') {
if (tab[param1] == tab[param2]) {
send(sock, "1", 1, 0);
} else {
send(sock, "0", 1, 0);
}
} else if (what == 'p') {
print_tab(tab, SIZE_TAB);
} else {
quit = -1;
}
}
}
int main(int argc, char * argv[]) {
if (argc != 2) {
printf("ERREUR : Usage : ./serveur N°Port\n");
exit(2);
}
// Variable pour le test sur le retour des fonctions des librairies
int rt;
// Déclaration des clés
int key_sema = 327;
int key_mem = 328;
// Création de la SHM (dans les deux processus)
int ma_shm;
ma_shm = shmget((key_t)key_mem, sizeof(int), 0666 | IPC_CREAT);
if (ma_shm == -1) {
perror("ERREUR. Echec shmget((key_t)key_mem, sizeof(int), 0666 | IPC_CREAT) \n");
fprintf(stderr, "ERREUR. Echec shmget((key_t)key, sizeof(int), 0666 | IPC_CREAT) \n");
exit(2);
}
addr_shm = (int *)shmat(ma_shm, 0, 0);
if (addr_shm == NULL) {
perror("ERREUR. Echec shmat(ma_shm, 0, 0) \n");
fprintf(stderr, "ERREUR. Echec shmat(ma_shm, 0, 0) \n");
exit(2);
}
// Initialisation de la SHM
*addr_shm = 0;
// Création du semaphore (dans les deux processus)
int sema;
sema = semget((key_t)key_sema, 1, 0666 | IPC_CREAT);
if (sema == -1) {
perror("ERREUR. Echec semget((key_t)key_sema, 1, 0666 | IPC_CREAT) \n");
fprintf(stderr, "ERREUR. Echec semget((key_t)key, 1, 0666 | IPC_CREAT) \n");
exit(2);
}
// Initialisation du sémaphore
union semun arg;
arg.val = 1;
rt = semctl(sema, 0, SETVAL, arg);
if (rt != 0) {
perror("ERREUR. Echec semctl(sema, 0, SETVAL, arg) \n");
fprintf(stderr, "ERREUR. Echec semctl(sema, 0, SETVAL, arg) \n");
exit(2);
}
// La structure pour manipuler les semaphores
struct sembuf buf;
buf.sem_flg = 0;
buf.sem_num = 0;
// install a handler for SIGSEGV in a part of your code
if(signal(SIGSEGV,&handle_sigsegv)==SIG_ERR)
{
fprintf(stderr,"Could not install SIGSEGV handler");
return -1;
}
// On crée le socket local
int sock = socket(AF_INET, SOCK_STREAM, 0);
@ -217,7 +183,6 @@ int main(int argc, char * argv[])
// Variable de stockage de l'addresse emmeteur
struct sockaddr_in addr_em;
unsigned int longueur_addr_em = sizeof(struct sockaddr_in);
// On se met en état d'acceptation de connexion (et on crée un socket en passant)
int pid = 1;
@ -236,45 +201,8 @@ int main(int argc, char * argv[])
printf("ERREUR lors de l'acceptation de la connexion\n");
exit(1);
} else {
// Recupération du traitement
struct traitement taf = process(sock_connexion);
printf("On est revenu\n");
printf("On a sauté ?\n");
// Prise du Semaphore
buf.sem_op = -1;
rt = semop(sema, &buf, 1);
if (rt != 0) {
perror("ERREUR. EChec semop(sema, &buf, 1) \n");
fprintf(stderr, "ERREUR. Echec semop(sema, &buf, 1) \n");
exit(2);
}
// Traitement
if (taf.action == 1) {
print_shm();
} else if (taf.action == 2) {
add(taf.arg);
} else if (taf.action == 3) {
sub(taf.arg);
} else if (taf.action == 4) {
mul(taf.arg);
} else if (taf.action == 5) {
divi(taf.arg);
} else if (taf.action == 6) {
reset();
} else if (taf.action == 7) {
int val = get();
char val_string[10];
sprintf(val_string, "%d", val);
send(sock_connexion, val_string, strlen(val_string), 0);
}
// Libération du Semaphore
buf.sem_op = 1;
rt = semop(sema, &buf, 1);
if (rt != 0) {
perror("ERREUR. EChec semop(sema, &buf, 1) \n");
fprintf(stderr, "ERREUR. Echec semop(sema, &buf, 1) \n");
exit(2);
}
// Traitement de la connexion
process(sock_connexion);
}
}
}

View file

@ -5,7 +5,7 @@
#define LATENCE 10000
#define FAT_LATENCE 1000000
#define FUNCTION usleep
#define SIZE_BUFF 212
#define SIZE_BUFF 228
#define NUM_PORT 1258
int main(int argc, char * argv[]) {
@ -45,9 +45,9 @@ int main(int argc, char * argv[]) {
char buff[SIZE_BUFF + 1];
int i;
for (i=0; i<(SIZE_BUFF / 4); i++) {
buff[(i*4)] = 0x25;
buff[(i*4) + 1] = 0x9a;
buff[(i*4) + 2] = 0x6;
buff[(i*4)] = 0xef;
buff[(i*4) + 1] = 0xca;
buff[(i*4) + 2] = 0x5c;
buff[(i*4) + 3] = 0x56;
}
buff[SIZE_BUFF] = '\0';

View file

@ -1,12 +1,12 @@
default:
@echo "Usage : [ Classic | SansCanary | 32bits | 32bitsSansCanary | Attaque ]"
Classic: clean serveur client
SansCanary: clean serveurSsCanary client
32bits: clean serveur32 client32
32bitsSansCanary: clean serveur32SsCanary client32
Classic: cleanServCli serveur client
SansCanary: cleanServCli serveurSsCanary client
32bits: cleanServCli serveur32 client32
32bitsSansCanary: cleanServCli serveur32SsCanary client32
Attaque: clean attaque.c
Attaque: cleanAttaque attaque.c
@echo "######################################"
@echo "# Compilation du programme ATTAQUANT #"
@echo "######################################"
@ -70,7 +70,12 @@ serveur32SsCanary: Serveur.c
@echo ""
edit:
pluma Serveur.c Client.c &
pluma Serveur.c Client.c Attaque.c &
clean:
@rm -f client serveur attaque
cleanAttaque:
@rm -f attaque
cleanServCli:
@rm -f client serveur
clean: cleanAttaque cleanServCli