create tlv
This commit is contained in:
parent
a8c32c2be2
commit
4ebed74a15
31
parser.c
Normal file
31
parser.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
// retourne le type de commande à exécuter
|
||||||
|
cmd_token parse_cmd() {
|
||||||
|
char buf[198], cmd[5], arg[193];
|
||||||
|
cmd_token token;
|
||||||
|
token.type = ERROR;
|
||||||
|
memset(token.arg, 0, 193);
|
||||||
|
|
||||||
|
if(fgets(buf, 198, stdin) == NULL)
|
||||||
|
return token;
|
||||||
|
|
||||||
|
// cmd sera le premier mot rencontré et arg la suite de mots après celui ci, si les deux variables ne sont pas remplies alors il y a une erreur
|
||||||
|
if(sscanf(buf, "%s %[^\t\n]", cmd, arg) != 2)
|
||||||
|
return token;
|
||||||
|
|
||||||
|
if(strcmp("req", cmd) == 0) {
|
||||||
|
if(strcmp("neighbour", arg) == 0)
|
||||||
|
token.type = NEIGHBOUR_REQ;
|
||||||
|
else if(strcmp("network state", arg) == 0)
|
||||||
|
token.type = NETWORK_STATE_REQ;
|
||||||
|
else if(strcmp("node state", arg) == 0)
|
||||||
|
token.type = NODE_STATE_REQ;
|
||||||
|
} else if(strcmp("send", cmd) == 0) {
|
||||||
|
token.type = SEND;
|
||||||
|
//arg[192] = 0;
|
||||||
|
strcpy(token.arg, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
39
parser.h
39
parser.h
@ -1,41 +1,14 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
enum cmd_type {
|
typedef enum cmd_type {
|
||||||
NEIGHBOUR_REQ, NETWORK_STATE_REQ, NODE_STATE_REQ, SEND, ERROR
|
NEIGHBOUR_REQ, NETWORK_STATE_REQ, NODE_STATE_REQ, SEND, ERROR
|
||||||
};
|
} cmd_type;
|
||||||
|
|
||||||
struct cmd_token {
|
typedef struct cmd_token {
|
||||||
enum cmd_type type;
|
cmd_type type;
|
||||||
char arg[193];
|
char arg[193];
|
||||||
};
|
} cmd_token;
|
||||||
|
|
||||||
// retourne le type de commande à exécuter
|
// retourne le type de commande à exécuter
|
||||||
struct cmd_token parse_cmd() {
|
cmd_token parse_cmd();
|
||||||
char buf[198], cmd[5], arg[193];
|
|
||||||
struct cmd_token token;
|
|
||||||
token.type = ERROR;
|
|
||||||
memset(token.arg, 0, 193);
|
|
||||||
|
|
||||||
if(fgets(buf, 198, stdin) == NULL)
|
|
||||||
return token;
|
|
||||||
|
|
||||||
// cmd sera le premier mot rencontré et arg la suite de mots après celui ci, si les deux variables ne sont pas remplies alors il y a une erreur
|
|
||||||
if(sscanf(buf, "%s %[^\t\n]", cmd, arg) != 2)
|
|
||||||
return token;
|
|
||||||
|
|
||||||
if(strcmp("req", cmd) == 0) {
|
|
||||||
if(strcmp("neighbour", arg) == 0)
|
|
||||||
token.type = NEIGHBOUR_REQ;
|
|
||||||
else if(strcmp("network state", arg) == 0)
|
|
||||||
token.type = NETWORK_STATE_REQ;
|
|
||||||
else if(strcmp("node state", arg) == 0)
|
|
||||||
token.type = NODE_STATE_REQ;
|
|
||||||
} else if(strcmp("send", cmd) == 0) {
|
|
||||||
token.type = SEND;
|
|
||||||
//arg[192] = 0;
|
|
||||||
strcpy(token.arg, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
|
188
tlv.c
Normal file
188
tlv.c
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
#include "tlv.h"
|
||||||
|
|
||||||
|
// creer un tlv
|
||||||
|
int build_tlv(tlv *tlv, cmd_token token) {
|
||||||
|
switch(token.type) {
|
||||||
|
case NEIGHBOUR_REQ:
|
||||||
|
// a remplir
|
||||||
|
break;
|
||||||
|
case NETWORK_STATE_REQ:
|
||||||
|
// a remplir
|
||||||
|
break;
|
||||||
|
case NODE_STATE_REQ:
|
||||||
|
// a remplir
|
||||||
|
break;
|
||||||
|
case SEND:
|
||||||
|
// a remplir
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
printf("Wrong format, use 'req {neighbour | network state | node state}' or 'send {message}'");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int build_pad1(tlv *tlv) {
|
||||||
|
pad1 *new = (pad1*) malloc(sizeof(pad1));
|
||||||
|
|
||||||
|
if(new == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
new->type = 0;
|
||||||
|
|
||||||
|
tlv->pad1 = new;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int build_padn(tlv *tlv, size_t len) {
|
||||||
|
padn *new = (padn*) malloc(sizeof(padn));
|
||||||
|
|
||||||
|
if(new == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
new->type = 1;
|
||||||
|
new->length = len;
|
||||||
|
new->mbz = (char*) calloc(sizeof(char), len);
|
||||||
|
|
||||||
|
tlv->padn = new;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int build_neighbour_req(tlv *tlv) {
|
||||||
|
neighbour_req *new = (neighbour_req*) malloc(sizeof(neighbour_req));
|
||||||
|
|
||||||
|
if(new == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
new->type = 2;
|
||||||
|
new->length = 0;
|
||||||
|
|
||||||
|
tlv->neighbour_req = new;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int build_neighbour(tlv *tlv, struct in6_addr ip, short port) {
|
||||||
|
neighbour *new = (neighbour*) malloc(sizeof(neighbour));
|
||||||
|
|
||||||
|
if(new == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
new->type = 3;
|
||||||
|
new->length = 18;
|
||||||
|
new->ip = ip;
|
||||||
|
new->port = port;
|
||||||
|
|
||||||
|
tlv->neighbour = new;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int build_network_hash(tlv *tlv, char *hash) {
|
||||||
|
network_hash *new = (network_hash*) malloc(sizeof(network_hash));
|
||||||
|
|
||||||
|
if(new == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
new->type = 4;
|
||||||
|
new->length = 16;
|
||||||
|
memcpy(new->network_hash, hash, 16);
|
||||||
|
|
||||||
|
tlv->network_hash = new;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int build_network_state_req(tlv *tlv) {
|
||||||
|
network_state_req *new = (network_state_req*) malloc(sizeof(network_state_req));
|
||||||
|
|
||||||
|
if(new == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
new->type = 5;
|
||||||
|
new->length = 0;
|
||||||
|
|
||||||
|
tlv->network_state_req = new;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int build_node_hash(tlv *tlv, long node_id, short seqno, char *hash) {
|
||||||
|
node_hash *new = (node_hash*) malloc(sizeof(node_hash));
|
||||||
|
|
||||||
|
if(new == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
new->type = 6;
|
||||||
|
new->length = 26;
|
||||||
|
new->node_id = node_id;
|
||||||
|
new->seqno = seqno;
|
||||||
|
memcpy(new->node_hash, hash, 16);
|
||||||
|
|
||||||
|
tlv->node_hash = new;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int build_node_state_req(tlv *tlv, long node_id) {
|
||||||
|
node_state_req *new = (node_state_req*) malloc(sizeof(node_state_req));
|
||||||
|
|
||||||
|
if(new == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
new->type = 7;
|
||||||
|
new->length = 8;
|
||||||
|
new->node_id = node_id;
|
||||||
|
|
||||||
|
tlv->node_state_req = new;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int build_node_state(tlv *tlv, long node_id, short seqno, char *node_hash, char *data) {
|
||||||
|
node_state *new = (node_state*) malloc(sizeof(node_state));
|
||||||
|
int len = strlen(data);
|
||||||
|
|
||||||
|
if(new == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// en mettant cet octet à 0 on est surs de traiter un champ data de taille 192 max
|
||||||
|
if(len > 192) {
|
||||||
|
data[192] = 0;
|
||||||
|
len = 192;
|
||||||
|
}
|
||||||
|
|
||||||
|
new->type = 8;
|
||||||
|
new->length = 26 + len;
|
||||||
|
new->node_id = node_id;
|
||||||
|
new->seqno = seqno;
|
||||||
|
memcpy(new->node_hash, node_hash, 16);
|
||||||
|
memcpy(new->data, data, len);
|
||||||
|
|
||||||
|
tlv->node_state = new;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int build_warning(tlv *tlv, char *message) {
|
||||||
|
warning *new = (warning*) malloc(sizeof(warning));
|
||||||
|
int len = strlen(message);
|
||||||
|
|
||||||
|
if(new == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// en mettant cet octet à 0 on est surs de traiter un champ message de taille 256 max
|
||||||
|
if(len > 256) {
|
||||||
|
message[256] = 0;
|
||||||
|
len = 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
new->type = 9;
|
||||||
|
new->length = len;
|
||||||
|
memcpy(new->message, message, len);
|
||||||
|
|
||||||
|
tlv->warning = new;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
77
tlv.h
77
tlv.h
@ -1,5 +1,6 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
|
||||||
// 8 octets min (struct pointer 4 octets), 1024 octets max
|
// 8 octets min (struct pointer 4 octets), 1024 octets max
|
||||||
@ -10,26 +11,12 @@ typedef struct packet {
|
|||||||
char *body;
|
char *body;
|
||||||
} packet;
|
} packet;
|
||||||
|
|
||||||
typedef union tlv {
|
|
||||||
pad1 *pad1;
|
|
||||||
padn *padn;
|
|
||||||
neighbour_req *neighbour_req;
|
|
||||||
neighbour *neighbour;
|
|
||||||
network_hash *network_hash;
|
|
||||||
network_state_req *network_state_req;
|
|
||||||
node_hash *node_hash;
|
|
||||||
node_state_req *node_state_req;
|
|
||||||
node_state *node_state;
|
|
||||||
warning *warning;
|
|
||||||
} tlv;
|
|
||||||
|
|
||||||
|
|
||||||
// 1 octet
|
// 1 octet
|
||||||
typedef struct pad1 {
|
typedef struct pad1 {
|
||||||
unsigned unsigned char type;
|
unsigned char type;
|
||||||
} pad1;
|
} pad1;
|
||||||
|
|
||||||
// 2 octets min, 257 octets max (unsigned char 0 -> 255)
|
// 2 octets min, 258 octets max (unsigned char 0 -> 255)
|
||||||
typedef struct padn {
|
typedef struct padn {
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
unsigned char length;
|
unsigned char length;
|
||||||
@ -42,7 +29,7 @@ typedef struct neighbour_req {
|
|||||||
unsigned char length;
|
unsigned char length;
|
||||||
} neighbour_req;
|
} neighbour_req;
|
||||||
|
|
||||||
// 132 octets
|
// 20 octets
|
||||||
typedef struct neighbour {
|
typedef struct neighbour {
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
unsigned char length;
|
unsigned char length;
|
||||||
@ -54,7 +41,7 @@ typedef struct neighbour {
|
|||||||
typedef struct network_hash {
|
typedef struct network_hash {
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
unsigned char length;
|
unsigned char length;
|
||||||
char *network_hash;
|
char network_hash[16];
|
||||||
} network_hash;
|
} network_hash;
|
||||||
|
|
||||||
// 2 octets
|
// 2 octets
|
||||||
@ -69,7 +56,7 @@ typedef struct node_hash {
|
|||||||
unsigned char length;
|
unsigned char length;
|
||||||
long node_id;
|
long node_id;
|
||||||
short seqno;
|
short seqno;
|
||||||
char *node_hash;
|
char node_hash[16];
|
||||||
} node_hash;
|
} node_hash;
|
||||||
|
|
||||||
// 10 octets
|
// 10 octets
|
||||||
@ -85,36 +72,42 @@ typedef struct node_state {
|
|||||||
unsigned char length;
|
unsigned char length;
|
||||||
long node_id;
|
long node_id;
|
||||||
short seqno;
|
short seqno;
|
||||||
char *node_hash;
|
char node_hash[16];
|
||||||
char *data;
|
char *data;
|
||||||
} node_state;
|
} node_state;
|
||||||
|
|
||||||
// 2 octets min, 257 ocets max (unsigned char 0 -> 255)
|
// 2 octets min, 258 ocets max (unsigned char 0 -> 255)
|
||||||
typedef struct warning {
|
typedef struct warning {
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
unsigned char length;
|
unsigned char length;
|
||||||
char *message;
|
char *message;
|
||||||
} warning;
|
} warning;
|
||||||
|
|
||||||
// creer un tlv
|
typedef union tlv {
|
||||||
void build_tlv(tlv *t) {
|
pad1 *pad1;
|
||||||
struct cmd_token token = parse_cmd();
|
padn *padn;
|
||||||
|
neighbour_req *neighbour_req;
|
||||||
|
neighbour *neighbour;
|
||||||
|
network_hash *network_hash;
|
||||||
|
network_state_req *network_state_req;
|
||||||
|
node_hash *node_hash;
|
||||||
|
node_state_req *node_state_req;
|
||||||
|
node_state *node_state;
|
||||||
|
warning *warning;
|
||||||
|
} tlv;
|
||||||
|
|
||||||
switch(token.type) {
|
|
||||||
case NEIGHBOUR_REQ:
|
// creer un tlv
|
||||||
// a remplir
|
int build_tlv(tlv *tlv, cmd_token token);
|
||||||
break;
|
|
||||||
case NETWORK_STATE_REQ:
|
// creer un tlv specifique
|
||||||
// a remplir
|
int build_pad1(tlv *tlv);
|
||||||
break;
|
int build_padn(tlv *tlv, size_t len);
|
||||||
case NODE_STATE_REQ:
|
int build_neighbour_req(tlv *tlv);
|
||||||
// a remplir
|
int build_neighbour(tlv *tlv, struct in6_addr ip, short seqno);
|
||||||
break;
|
int build_network_hash(tlv *tlv, char *network_hash);
|
||||||
case SEND:
|
int build_network_state_req(tlv *tlv);
|
||||||
// a remplir
|
int build_node_hash(tlv *tlv, long node_id, short seqno, char *node_hash);
|
||||||
break;
|
int build_node_state_req(tlv *tlv, long node_id);
|
||||||
case ERROR:
|
int build_node_state(tlv *tlv, long node_id, short seqno, char *node_hash, char *data);
|
||||||
printf("Wrong format, use 'req {neighbour | network state | node state}' or 'send {message}'");
|
int build_warning(tlv *tlv, char *message);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user