Merge branch 'get-network-state' into 'master'

: Get network state

See merge request perdriau/dazibao!17
This commit is contained in:
PERDRIAU nelson 2020-05-05 14:58:25 +02:00
commit c52f87f2d9
9 changed files with 903 additions and 371 deletions

3
.gitignore vendored
View File

@ -1,3 +0,0 @@
dazibao
*.o
debug.*

View File

@ -1,7 +1,7 @@
TARGET ?= dazibao TARGET ?= dazibao
SRC_DIRS ?= ./src/* SRC_DIRS ?= ./src/*
CC := gcc CC := gcc
CFLAGS= -O2 -Wall CFLAGS= -O2 -Wall -g
SRCS := $(shell find $(SRC_DIRS) -name *.c -or -name *.s) SRCS := $(shell find $(SRC_DIRS) -name *.c -or -name *.s)
OBJS := $(addsuffix .o,$(basename $(SRCS))) OBJS := $(addsuffix .o,$(basename $(SRCS)))
DEPS := $(OBJS:.o=.d) DEPS := $(OBJS:.o=.d)

View File

@ -1,11 +1,72 @@
#include <stdio.h> #include <stdio.h>
#include <stddef.h>
#include <uchar.h>
#include <locale.h>
#include <arpa/inet.h>
#include "debug.h" #include "debug.h"
#include "node.h"
void print_debug(char * msg){ void print_debug(char * msg){
if (DEBUG_LEVEL > 0) { if (DEBUG_LEVEL > 0) {
printf("\x1b[31m[DEBUG]\x1b[0m %s \n", msg); printf("\x1b[31m[DEBUG]\x1b[0m %s \n", msg);
} }
if (DEBUG_LEVEL > 2) { if (DEBUG_LEVEL > 9) {
getchar(); getchar();
} }
} }
void print_error(char * msg){
printf("\x1b[41m\x1b[97m[ERROR] >> %s \x1b[0m\n", msg);
if (DEBUG_LEVEL > 1) {
getchar();
}
}
void print_peers(list * l){
// Print out the peers we have in the neighbour_list
int nbr_peers = 0;
if (l == NULL) {
print_error("The neighbour_list is empty !");
} else {
print_debug(">> Printing out peer list :");
while(l != NULL){
neighbour_peer * peer = (neighbour_peer *) l->data;
char * buff_str_ip[1024];
char * ip_str = (char * ) inet_ntop(AF_INET6,&peer->ip,(char * restrict) buff_str_ip, 1024);
int last_seen = time(NULL) - peer->last_seen;
printf("\x1b[31m[DEBUG]\x1b[0m >> %s @ %i | is temporary ? %s | last seen %i secs ago. |\n", ip_str, peer->port, peer->is_temporary ? "yes":"no", last_seen);
nbr_peers++;
if (l->next == NULL) {
break;
} else {
l = l->next;
}
}
printf("\x1b[31m[DEBUG]\x1b[0m >> Found %i peers.\n", nbr_peers);
print_debug(">> Finished printing peer list.");
}
}
void print_data(list * l){
if (l == NULL) {
print_error("Message list is empty !");
} else {
print_debug(">> Printing messages we know of so far :");
int nbr_msg = 0;
setlocale(LC_ALL, "en_US.utf8");
print_debug(">> Peer ID | Seqno | Length | Message ");
while(l != NULL){
pub_data * message = l->data;
printf("\x1b[31m[DEBUG]\x1b[0m >> %li | %i | %i | “%s” \n", message->id, message->seqno, message->length, message->data);
nbr_msg++;
if (l->next == NULL) {
break;
} else {
l = l->next;
}
}
printf("\x1b[31m[DEBUG]\x1b[0m >> Found %i messages.\n", nbr_msg);
}
}

View File

@ -1,8 +1,16 @@
#ifndef DEBUG_H #ifndef DEBUG_H
#define DEBUG_H #define DEBUG_H
#include "node.h"
#define DEBUG_LEVEL 2 #define DEBUG_LEVEL 2
void print_debug(char * msg); void print_debug(char * msg);
void print_error(char * msg);
void print_peers(list * l);
void print_data(list * l);
#endif #endif

View File

@ -1,7 +1,16 @@
#include "hash.h" #include "hash.h"
#include "debug.h"
// Hash a single data // Hash a single data
void hash_data(pub_data *data, unsigned char *buf) { void hash_data(pub_data *data, unsigned char *buf) {
/*
data->length = 52 - 26;
data->id = 34538;
data->seqno = 4864;
data->data = "Luke, je suis ton \"pair\" !";
printf("Hash received: 9ffe841a99776f6d1295ac75b53a58d7\n");
*/
// All three fields are concatenated into a single buffer // All three fields are concatenated into a single buffer
int totlen = data->length + 10; int totlen = data->length + 10;
unsigned char concat[totlen]; unsigned char concat[totlen];
@ -9,10 +18,22 @@ void hash_data(pub_data *data, unsigned char *buf) {
// The resulting buf is hashed and put into a buffer // The resulting buf is hashed and put into a buffer
unsigned char hash[SHA256_DIGEST_LENGTH]; unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256(concat, totlen, hash);
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, concat, totlen);
SHA256_Final(hash, &sha256);
// Put truncated hash into buf // Put truncated hash into buf
hash_trunc(hash, buf); hash_trunc(hash, buf);
/*
printf("Hash built: ");
for(int i = 0; i < 16; i++) {
printf("%02x", buf[i]);
}
printf("\n");
*/
} }
// Hash every data contained in data_list then return a network hash // Hash every data contained in data_list then return a network hash
@ -34,7 +55,10 @@ void hash_network(list *data_list, unsigned char *buf) {
} }
// Hash all of concat to obtain the network hash // Hash all of concat to obtain the network hash
SHA256(concat, totlen, hash); SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, concat, concat_len);
SHA256_Final(hash, &sha256);
// Put truncated hash into buf // Put truncated hash into buf
hash_trunc(hash, buf); hash_trunc(hash, buf);
@ -46,17 +70,49 @@ void hash_network(list *data_list, unsigned char *buf) {
// Truncate 32 octet hash to 16 octets // Truncate 32 octet hash to 16 octets
void hash_trunc(unsigned char *hash32oct, unsigned char *buf) { void hash_trunc(unsigned char *hash32oct, unsigned char *buf) {
// Copy the first 16 octets from hash32oct // Copy the first 16 octets from hash32oct
memcpy(buf, hash32oct, 16); if (memcpy(buf, hash32oct, 16) == NULL) {
print_debug(">> Truncating the hashs didn't work !");
}
} }
// Concat all fields of data and put them in buf // Concat all fields of data and put them in buf
void concat_data(pub_data *data, unsigned char *buf) { void concat_data(pub_data *data, unsigned char *buf) {
memcpy(buf, &(data->id), 8); // Turn seqno to big endian
memcpy(buf+8, &(data->seqno), 2); uint16_t seqno = htobe16(data->seqno);
memcpy(buf+10, data->data, data->length); uint64_t id = htobe64(data->id);
if (memcpy(buf, (char*) &id, 8) == NULL) {
print_debug(">> Concat the data (id) didn't work !");
}
if (memcpy(buf+8, (char*) &seqno, 2) == NULL) {
print_debug(">> concat the data (seqno) didn't work !");
}
if (memcpy(buf+10, data->data, data->length) == NULL) {
print_debug(">> Contact the data (data) didn't work !");
}
/*
uint64_t *id = (uint64_t *) buf;
uint16_t *seqno2 = (uint16_t *) (buf + 8);
char *message = (char*) (buf + 10);
char fuck[100];
printf("id: %ld\nseqno: %d\nmessage: ", *id, *seqno2);
for(int i = 0; i < data->length; i++) {
printf("%c", message[i]);
}
printf("\nORIGINAL\n");
printf("id: %ld\nseqno: %d\nmessage: ", data->id, htobe16(data->seqno));
for(int i = 0; i < data->length; i++) {
printf("%c", data->data[i]);
}
printf("\n");
*/
} }
// Concat hash2 to hash1 (hash1 is modified) // Concat hash2 to hash1 (hash1 is modified)
void concat_hash(unsigned char *hash1, unsigned char *hash2, size_t size) { void concat_hash(unsigned char *hash1, unsigned char *hash2, size_t size) {
memcpy(hash1+size, hash2, 16); if(memcpy(hash1+size, hash2, 16) == NULL){
print_debug(">> Concat the hash didn't work !");
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,13 @@
#include <time.h> #include <time.h>
#include <stdint.h> #include <stdint.h>
#include <net/if.h> #include <net/if.h>
#include <errno.h>
#include <endian.h>
#include <fcntl.h>
#include <poll.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <locale.h>
/* la table de voisins, qui est indexée par adresses de socket (des paires (IP, Port)), /* la table de voisins, qui est indexée par adresses de socket (des paires (IP, Port)),
* et dont chaque entrée contient un booléen indiquant si le pair est permanent * et dont chaque entrée contient un booléen indiquant si le pair est permanent
@ -34,8 +41,8 @@ typedef struct neighbour_peer {
typedef struct pub_data { typedef struct pub_data {
unsigned char length; unsigned char length;
int64_t id; uint64_t id;
int16_t seqno; uint16_t seqno;
char *data; char *data;
} pub_data; } pub_data;
@ -48,20 +55,22 @@ typedef struct list {
#include "tlv.h" #include "tlv.h"
#include "hash.h" #include "hash.h"
#include "parser.h" #include "parser.h"
#include "debug.h"
// On which port do we listen to // On which port do we listen to
#define LISTEN_PORT 1212 #define LISTEN_PORT 1212
// The node ID // The node ID
// #define NODE_ID 42675882021843277 // #define NODE_ID 42675882021843277
#define NODE_ID 42013376900101010 // #define NODE_ID 13809235719890846928
#define NODE_ID 1312
// The number of neighbours // The number of neighbours
// The neighbour table has 15 entries // The neighbour table has 15 entries
#define NEIGHBOUR_MAX 15 #define NEIGHBOUR_MAX 15
// The adress of the main peer // The adress of the main peer
#define ROOT_PEER_ADDR "2001:660:3301:9200::51c2:1b9b" #define ROOT_PEER_ADDR "::1"
// fonctions signatures // fonctions signatures
@ -69,17 +78,17 @@ int listen_for_packets(char * received_data_buffer, int received_data_len, struc
int check_header(char * received_data_buffer, int received_data_len, packet * packet_to_return); int check_header(char * received_data_buffer, int received_data_len, packet * packet_to_return);
int validate_tlv(char *data, int pos, int16_t packet_len); int validate_tlv(char *data, int pos, uint16_t packet_len);
int update_neighbours(); int update_neighbours();
int ask_for_peers(int socket_num); int ask_for_peers(int socket_num);
int work_with_tlvs(char * data, int16_t packet_len, struct sockaddr_in6 *sender, int socket_num); int work_with_tlvs(char * data, uint16_t packet_len, struct sockaddr_in6 *sender, int socket_num);
int add_tlv(packet *pack, tlv *tlv, struct sockaddr_in6 *dest, int socket_num); int add_tlv(packet *pack, tlv *tlv, struct sockaddr_in6 *dest, int socket_num);
int send_packet(char *packet_buff, int16_t length, struct sockaddr_in6 *dest, int socket_num); int send_packet(char *packet_buff, uint16_t length, struct sockaddr_in6 *dest, int socket_num);
int send_single_tlv(tlv *tlv, struct sockaddr_in6 *dest, int socket_num); int send_single_tlv(tlv *tlv, struct sockaddr_in6 *dest, int socket_num);
@ -89,12 +98,12 @@ int run_node(int sock_fd);
/* Takes a TLV and sends it over to everyone in the list of addresses. /* Takes a TLV and sends it over to everyone in the list of addresses.
* Returns -1 in case of error, 0 otherwise. * Returns -1 in case of error, 0 otherwise.
*/ */
int send_tlv(tlv *tlv_to_send, int16_t length, struct sockaddr_in6 * dest_list, int dest_list_size, int socket_num); int send_tlv(tlv *tlv_to_send, uint16_t length, struct sockaddr_in6 * dest_list, int dest_list_size, int socket_num);
/* Takes a list of TLV and sends them over to everyone in the list of addresses. /* Takes a list of TLV and sends them over to everyone in the list of addresses.
* Returns -1 in case of error, 0 otherwise. * Returns -1 in case of error, 0 otherwise.
*/ */
int send_tlvs(struct list * tlv_list, int16_t length, struct sockaddr_in6 * dest_list, int dest_list_size, int socket_num); int send_tlvs(struct list * tlv_list, uint16_t length, struct sockaddr_in6 * dest_list, int dest_list_size, int socket_num);
/* Check our peer list. If we have less than 5 peers, send out a /* Check our peer list. If we have less than 5 peers, send out a
TLV NEIGHBOUR_REQUEST to a random peer TLV NEIGHBOUR_REQUEST to a random peer
@ -116,13 +125,11 @@ int add_message(char * message, int message_len);
// This functions creates the structures needed for the rest of the project, // This functions creates the structures needed for the rest of the project,
// creates the socket, and returns all of it. // creates the socket, and returns all of it.
int bootstrap_node(int * sock_fd); int bootstrap_node(int * sock_fd, char * root_peer_ip, uint16_t root_peer_port);
// Helper functions // Helper functions
int len_list(list *l); int len_list(list *l);
void debug_print(char message_debug);
neighbour_peer *get_random_neighbour(); neighbour_peer *get_random_neighbour();
// Search for this peer in the neighbour table // Search for this peer in the neighbour table
@ -132,12 +139,12 @@ neighbour_peer *get_neighbour(struct in6_addr *ip, int16_t port);
int add_n_update_neighbour(struct in6_addr *ip, int16_t port); int add_n_update_neighbour(struct in6_addr *ip, int16_t port);
// get data associated with id, if it doesn't exist return NULL // get data associated with id, if it doesn't exist return NULL
pub_data *get_data(int64_t id); pub_data *get_data(uint64_t id);
// Take data as args and create a pub_data structure in the heap // Take data as args and create a pub_data structure in the heap
pub_data *copy_data(unsigned char len, int64_t id, int16_t seqno, char *data); pub_data *copy_data(unsigned char len, uint64_t id, uint16_t seqno, char *data);
// add new data to data list // add new data to data list
void add_data(unsigned char len, int64_t id, int16_t seqno, char *data); int add_data(unsigned char len, uint64_t id, uint16_t seqno, char *data, pub_data *found);
#endif #endif

View File

@ -1,36 +1,11 @@
#include "tlv.h" #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 POST:
// a remplir
break;
case ERROR:
printf("Wrong format, use 'req {neighbour | network state | node state}' or 'post {message}'");
break;
default:
perror("Unrecognized tlv type.");
return -1;
}
return -1;
}
int build_pad1(tlv *tlv) { int build_pad1(tlv *tlv) {
// Free the previously allocated memory // Free the previously allocated memory
free(tlv->pad1); free(tlv->pad1);
pad1 *new = (pad1*) malloc(sizeof(pad1)); pad1 *new = (pad1*) malloc(sizeof(pad1));
memset(new, 0, sizeof(pad1));
if(new == NULL) if(new == NULL)
return -1; return -1;
@ -47,6 +22,7 @@ int build_padn(tlv *tlv, size_t len) {
free(tlv->pad1); free(tlv->pad1);
padn *new = (padn*) malloc(sizeof(padn)); padn *new = (padn*) malloc(sizeof(padn));
memset(new, 0, sizeof(padn));
if(new == NULL) if(new == NULL)
return -1; return -1;
@ -62,11 +38,10 @@ int build_padn(tlv *tlv, size_t len) {
int build_neighbour_req(tlv *tlv) { int build_neighbour_req(tlv *tlv) {
// Free the previously allocated memory // Free the previously allocated memory
// if (tlv != NULL) { free(tlv->pad1);
// free(tlv->pad1);
// }
neighbour_req *new = (neighbour_req*) malloc(sizeof(neighbour_req)); neighbour_req *new = (neighbour_req*) malloc(sizeof(neighbour_req));
memset(new, 0, sizeof(neighbour_req));
if(new == NULL){ if(new == NULL){
return -1; return -1;
@ -82,9 +57,14 @@ int build_neighbour_req(tlv *tlv) {
int build_neighbour(tlv *tlv, struct in6_addr ip, int16_t port) { int build_neighbour(tlv *tlv, struct in6_addr ip, int16_t port) {
// Free the previously allocated memory // Free the previously allocated memory
// TODO : why do we free this part ? Doesn't it mean that, once the
// tlv has entered this function, it's not on the heap anymore,
// and thus, setting a value will not be accessible from other part of the
// code ?
free(tlv->pad1); free(tlv->pad1);
neighbour *new = (neighbour*) malloc(sizeof(neighbour)); neighbour *new = (neighbour*) malloc(sizeof(neighbour));
memset(new, 0, sizeof(neighbour));
if(new == NULL) if(new == NULL)
return -1; return -1;
@ -92,7 +72,7 @@ int build_neighbour(tlv *tlv, struct in6_addr ip, int16_t port) {
new->type = 3; new->type = 3;
new->length = 18; new->length = 18;
new->ip = ip; new->ip = ip;
new->port = htons(port); new->port = htobe16(port);
tlv->neighbour = new; tlv->neighbour = new;
@ -104,13 +84,14 @@ int build_network_hash(tlv *tlv, list *data_list) {
free(tlv->pad1); free(tlv->pad1);
network_hash *new = (network_hash*) malloc(sizeof(network_hash)); network_hash *new = (network_hash*) malloc(sizeof(network_hash));
memset(new, 0, sizeof(network_hash));
if(new == NULL) if(new == NULL)
return -1; return -1;
new->type = 4; new->type = 4;
new->length = 16; new->length = 16;
hash_network(data_list, (unsigned char*) new->network_hash); hash_network(data_list, new->network_hash);
tlv->network_hash = new; tlv->network_hash = new;
@ -122,6 +103,7 @@ int build_network_state_req(tlv *tlv) {
free(tlv->pad1); free(tlv->pad1);
network_state_req *new = (network_state_req*) malloc(sizeof(network_state_req)); network_state_req *new = (network_state_req*) malloc(sizeof(network_state_req));
memset(new,0,sizeof(network_state_req));
if(new == NULL) if(new == NULL)
return -1; return -1;
@ -134,70 +116,66 @@ int build_network_state_req(tlv *tlv) {
return 0; return 0;
} }
int build_node_hash(tlv *tlv, int64_t node_id, int16_t seqno, char *data) { int build_node_hash(tlv *tlv, uint64_t node_id, uint16_t seqno, char *data, unsigned char length) {
// Free the previously allocated memory // Free the previously allocated memory
free(tlv->pad1); free(tlv->pad1);
node_hash *new = (node_hash*) malloc(sizeof(node_hash)); node_hash *new = (node_hash*) malloc(sizeof(node_hash));
memset(new,0,sizeof(node_hash));
if(new == NULL) if(new == NULL)
return -1; return -1;
new->type = 6; new->type = 6;
new->length = 26; new->length = 26;
new->node_id = node_id; new->node_id = htobe64(node_id);
new->seqno = seqno; new->seqno = htobe16(seqno);
pub_data pdata = (pub_data) {.id = node_id, .seqno = seqno, .data = data}; pub_data pdata = (pub_data) {.length = length, .id = node_id, .seqno = seqno, .data = data};
hash_data(&pdata, (unsigned char*) new->node_hash); hash_data(&pdata, new->node_hash);
tlv->node_hash = new; tlv->node_hash = new;
return 0; return 0;
} }
int build_node_state_req(tlv *tlv, int64_t node_id) { int build_node_state_req(tlv *tlv, uint64_t node_id) {
// Free the previously allocated memory // Free the previously allocated memory
free(tlv->pad1); free(tlv->pad1);
node_state_req *new = (node_state_req*) malloc(sizeof(node_state_req)); node_state_req *new = (node_state_req*) malloc(sizeof(node_state_req));
memset(new, 0, sizeof(node_state_req));
if(new == NULL) if(new == NULL)
return -1; return -1;
new->type = 7; new->type = 7;
new->length = 8; new->length = 8;
new->node_id = node_id; new->node_id = htobe64(node_id);
tlv->node_state_req = new; tlv->node_state_req = new;
return 0; return 0;
} }
int build_node_state(tlv *tlv, int64_t node_id, int16_t seqno, char *data, size_t data_len) { int build_node_state(tlv *tlv, uint64_t node_id, uint16_t seqno, char *data, size_t data_len) {
// Free the previously allocated memory // Free the previously allocated memory
free(tlv->pad1); free(tlv->pad1);
node_state *new = (node_state*) malloc(sizeof(node_state)); node_state *new = (node_state*) malloc(sizeof(node_state));
int len = data_len + 26; memset(new, 0, sizeof(node_state));
if(new == NULL) if(new == NULL)
return -1; 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->type = 8;
new->length = 26 + len; new->length = data_len + 26;
new->node_id = node_id; new->node_id = htobe64(node_id);
new->seqno = seqno; new->seqno = htobe16(seqno);
memcpy(new->data, data, len); memcpy(new->data, data, data_len);
pub_data pdata = (pub_data) {.id = node_id, .seqno = seqno, .data = data}; pub_data pdata = (pub_data) {.length = data_len, .id = node_id, .seqno = seqno, .data = data};
hash_data(&pdata, (unsigned char*) new->node_hash); hash_data(&pdata, new->node_hash);
tlv->node_state = new; tlv->node_state = new;
@ -209,17 +187,13 @@ int build_warning(tlv *tlv, char *message, size_t message_len) {
free(tlv->pad1); free(tlv->pad1);
warning *new = (warning*) malloc(sizeof(warning)); warning *new = (warning*) malloc(sizeof(warning));
memset(new, 0, sizeof(warning));
int len = message_len; int len = message_len;
if(new == NULL) if(new == NULL)
return -1; 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->type = 9;
new->length = len; new->length = len;
memcpy(new->message, message, len); memcpy(new->message, message, len);

View File

@ -19,7 +19,7 @@
typedef struct packet { typedef struct packet {
unsigned char magic; // 95 (si autre, ignorer) unsigned char magic; // 95 (si autre, ignorer)
unsigned char version; // 1 (si autre, ignorer) unsigned char version; // 1 (si autre, ignorer)
int16_t length; // 1020 max uint16_t length; // 1020 max
char body[1020]; char body[1020];
} packet; } packet;
@ -53,7 +53,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[16]; unsigned char network_hash[16];
} network_hash; } network_hash;
// 2 octets // 2 octets
@ -66,25 +66,25 @@ typedef struct network_state_req {
typedef struct node_hash { typedef struct node_hash {
unsigned char type; unsigned char type;
unsigned char length; unsigned char length;
int64_t node_id; uint64_t node_id;
int16_t seqno; uint16_t seqno;
char node_hash[16]; unsigned char node_hash[16];
} node_hash; } node_hash;
// 10 octets // 10 octets
typedef struct node_state_req { typedef struct node_state_req {
unsigned char type; unsigned char type;
unsigned char length; unsigned char length;
int64_t node_id; uint64_t node_id;
} node_state_req; } node_state_req;
// 28 octets min, 220 octets max (data 0 -> 192) // 28 octets min, 220 octets max (data 0 -> 192)
typedef struct node_state { typedef struct node_state {
unsigned char type; unsigned char type;
unsigned char length; unsigned char length;
int64_t node_id; uint64_t node_id;
int16_t seqno; uint16_t seqno;
char node_hash[16]; unsigned char node_hash[16];
char data[192]; char data[192];
} node_state; } node_state;
@ -122,9 +122,9 @@ int build_neighbour_req(union tlv *tlv);
int build_neighbour(tlv *tlv, struct in6_addr ip, int16_t port); int build_neighbour(tlv *tlv, struct in6_addr ip, int16_t port);
int build_network_hash(tlv *tlv, list *data_list); int build_network_hash(tlv *tlv, list *data_list);
int build_network_state_req(tlv *tlv); int build_network_state_req(tlv *tlv);
int build_node_hash(tlv *tlv, int64_t node_id, int16_t seqno, char *data); int build_node_hash(tlv *tlv, uint64_t node_id, uint16_t seqno, char *data, unsigned char length);
int build_node_state_req(tlv *tlv, int64_t node_id); int build_node_state_req(tlv *tlv, uint64_t node_id);
int build_node_state(tlv *tlv, int64_t node_id, int16_t seqno, char *data, size_t data_len); int build_node_state(tlv *tlv, uint64_t node_id, uint16_t seqno, char *data, size_t data_len);
int build_warning(tlv *tlv, char *message, size_t message_len); int build_warning(tlv *tlv, char *message, size_t message_len);
#endif #endif