struct padding error fix

This commit is contained in:
nis 2020-05-03 00:19:54 +02:00
parent bd8f5c452b
commit 733c700492
2 changed files with 145 additions and 36 deletions

View File

@ -10,7 +10,11 @@ void hash_data(pub_data *data, unsigned char *buf) {
// The resulting buf is hashed and put into a buffer
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
hash_trunc(hash, buf);
@ -35,9 +39,10 @@ void hash_network(list *data_list, unsigned char *buf) {
}
// Hash all of concat to obtain the network hash
if (SHA256(concat, totlen, hash) == NULL) {
print_debug(">> Doing the hash failed : function return NULL, should return a pointer.");
};
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, concat, concat_len);
SHA256_Final(hash, &sha256);
// Put truncated hash into buf
hash_trunc(hash, buf);

View File

@ -698,6 +698,51 @@ int validate_tlv(char *data, int pos, uint16_t packet_len){
return 7;
case 8:
if(tlv_len < MIN_LEN_NODE_STATE || tlv_len > MAX_LEN_NODE_STATE) return -1;
/*
// Check if it has the right hash
uint16_t *seqno = (uint16_t*) (data + pos + 10);
uint64_t *id = (uint64_t*) (data + pos + 2);
pub_data pdata = (pub_data) {
.length = tlv_len,
.id = *id,
.seqno = *seqno,
.data = (unsigned char*) malloc(tlv_len)
};
unsigned char *cur_hash = (unsigned char*) (data + pos + 12);
char *cur_message = data + pos + 28;
unsigned char hash[16];
memcpy(pdata.data, cur_message, tlv_len);
hash_data(&pdata, hash);
if(memcmp(hash, cur_hash, 16) != 0) {
print_debug(">> Malformed hash.");
printf("\x1b[31m[DEBUG]\x1b[0m >> Received : ");
for(int x = 0; x < 16; x++){
printf("%02x", hash[x]);
fflush(0);
}
printf("\n");
printf("\x1b[31m[DEBUG]\x1b[0m >> Received : ");
for(int x = 0; x < 16; x++){
printf("%02x", cur_hash[x]);
fflush(0);
}
printf("\n");
return -1;
}
*/
return 8;
case 9:
return 9;
@ -772,7 +817,7 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
int nbr_of_tlvs = 0;
int pos = 4;
unsigned char tlv_len, hash[16];
unsigned char tlv_len, hash[16], hash2[16];
char warn[32];
// The TLV we are going to send back.
@ -798,6 +843,12 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
int ifindex = 0;
// Temporary values
uint16_t *port, *seqno;
uint64_t *id;
unsigned char *cur_hash, *ip;
char *cur_message;
while(pos < total_packet_len) {
// Making sure the current TLV we are looking at is valid.
// TODO : I think we should reset all the structs here.
@ -850,13 +901,14 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
print_debug(">> Received neighbour tlv, sending back network hash.");
// We received a neighbour tlv so a tlv network hash is sent to that address
cur_tlv.neighbour = (neighbour*) (data + pos);
ip = (unsigned char*) (data + pos + 2);
port = (uint16_t*) (data + pos + 18);
// Init dest socket
memset(&new_neighbour, 0, sizeof(new_neighbour));
new_neighbour.sin6_family = AF_INET6;
memcpy(&new_neighbour.sin6_addr, &cur_tlv.neighbour->ip, 16);
new_neighbour.sin6_port = be16toh(cur_tlv.neighbour->port);
memcpy(&new_neighbour.sin6_addr, ip, 16);
new_neighbour.sin6_port = be16toh(*port);
new_neighbour.sin6_scope_id = ifindex;
// Build network hash
@ -874,7 +926,8 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
print_debug(">> Received network_hash, comparing with our own..");
// We reveived a network hash tlv so we compare the hash with our own,
// if they differ we send a network state request tlv
cur_tlv.network_hash = (network_hash*) (data + pos);
cur_hash = (unsigned char*) (data + pos + 2);
hash_network(data_list, hash);
if (DEBUG_LEVEL > 1) {
@ -886,13 +939,13 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
printf("\n");
printf("\x1b[31m[DEBUG]\x1b[0m >> Received : ");
for(int x = 0; x < 16; x++){
printf("%02x", cur_tlv.network_hash->network_hash[x]);
printf("%02x", cur_hash[x]);
fflush(0);
}
printf("\n");
}
if(memcmp(hash, cur_tlv.network_hash->network_hash, 16) != 0) {
if(memcmp(hash, cur_hash, 16) != 0) {
print_debug(">> Sending out our network hash.");
build_network_state_req(&new_tlv);
send_single_tlv(&new_tlv, sender, socket_num);
@ -931,16 +984,20 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
// we send a node state request,
//if the hashes are identical nothing has to be done
print_debug(">> Received node hash, updating message entry...");
cur_tlv.node_hash = (node_hash*) (data + pos);
pdata = get_data(be64toh(cur_tlv.node_hash->node_id));
id = (uint64_t*) (data + pos + 2);
cur_hash = (unsigned char*) (data + pos + 12);
pdata = get_data(be64toh(*id));
// If data is found for this id then we check that both hashes are the same
if(pdata != NULL) {
print_debug(">> Comparing hashes...");
// We hash the data stored in the data list
hash_data(pdata, hash);
// If both hashes are the same then nothing has to be done
if(memcmp(hash, cur_tlv.node_hash->node_hash, 16) == 0) {
if(memcmp(hash, cur_hash, 16) == 0) {
// The position is updated
tlv_len = data[pos+1];
pos += tlv_len + 2;
@ -950,9 +1007,9 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
}
print_debug(">> No hash found, or hashs are differents, sending back node state request.");
print_debug(">> No hash found, or hashs are different, sending back node state request.");
// If no pub_data was found or the hashes differ then we send a node state request
build_node_state_req(&new_tlv, be64toh(cur_tlv.node_hash->node_id));
build_node_state_req(&new_tlv, be64toh(*id));
add_tlv(&pack, &new_tlv, sender, socket_num);
// The position is updated
@ -966,8 +1023,10 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
// so a node state tlv for this node id has to be sent,
// if no pub_data exists for this id nothing is sent
print_debug(">> Received node state request. Processing...");
cur_tlv.node_state_req = (node_state_req*) (data + pos);
pdata = get_data(be64toh(cur_tlv.node_state_req->node_id));
id = (uint64_t*) (data + pos + 2);
pdata = get_data(be64toh(*id));
if(pdata != NULL) {
build_node_state(&new_tlv, pdata->id, pdata->seqno, pdata->data, pdata->length);
@ -986,46 +1045,90 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
// we add it to the data list
// or update the data stored
print_debug(">> Received node state, updating...");
cur_tlv.node_state = (node_state*) (data + pos);
tlv_len = data[pos + 1];
id = (uint64_t*) (data + pos + 2);
seqno = (uint16_t*) (data + pos + 10);
cur_hash = (unsigned char*) (data + pos + 12);
cur_message = data + pos + 28;
print_debug(">> Received message ! ");
printf("Type : %d\n", cur_tlv.node_state->type );
printf("Length : %d\n", cur_tlv.node_state->length );
printf("Node ID : %lu\n", be64toh(cur_tlv.node_state->node_id) );
printf("Seqno : %hu\n", be16toh(cur_tlv.node_state->seqno) );
printf("Type : %d\n", data[pos] );
printf("Length : %d\n", tlv_len );
printf("Node ID : %lu\n", be64toh(*id) );
printf("Seqno : %hu\n", be16toh(*seqno) );
printf("Hash :");
for(int x = 0; x < 16; x++){
printf("%02x", cur_tlv.node_state->node_hash[x]);
printf("%02x", cur_hash[x]);
fflush(0);
}
printf("\n");
for(int x = 0; x < 192; x++){
printf("%d", cur_tlv.node_state->data[x]);
for(int x = 0; x < tlv_len; x++){
printf("%c", cur_message[x]);
fflush(0);
}
printf("\n");
// Check if it has the right hash
pub_data pdata_check = (pub_data) {
.length = tlv_len,
.id = *id,
.seqno = *seqno,
.data = (unsigned char*) malloc(tlv_len)
};
memcpy(pdata_check.data, cur_message, tlv_len);
hash_data(&pdata_check, hash2);
if(memcmp(hash2, cur_hash, 16) != 0) {
print_debug(">> Malformed hash.");
printf("\x1b[31m[DEBUG]\x1b[0m >> Calculated : ");
for(int x = 0; x < 16; x++){
printf("%02x", hash2[x]);
fflush(0);
}
printf("\n");
printf("\x1b[31m[DEBUG]\x1b[0m >> Received : ");
for(int x = 0; x < 16; x++){
printf("%02x", cur_hash[x]);
fflush(0);
}
printf("\n");
pos += tlv_len + 2;
break;
}
/*
if (DEBUG_LEVEL > 0) {
if (cur_tlv.node_state->data == NULL) {
if (cur_message == NULL) {
print_error("The data in the current node is NULL !");
return -1;
}
printf("\x1b[31m[DEBUG]\x1b[0m >> “%ls\0\n", (const wchar_t*) cur_tlv.node_state->data);
printf("\x1b[31m[DEBUG]\x1b[0m >> “%ls\0\n", (const wchar_t*) cur_message);
sleep(1);
}
*/
// Compare hashes
pdata = get_data(be64toh(cur_tlv.node_state->node_id));
pdata = get_data(be64toh(*id));
// If data is found for this id then we check that both hashes are the same
if(pdata != NULL) {
print_debug(">> Comparing hashes...");
// We hash the data stored in the data list
memset(hash, 0, 16);
hash_data(pdata, hash);
// If both hashes are the same then nothing has to be done
if(memcmp(hash, cur_tlv.node_state->node_hash, 16) == 0) {
if(memcmp(hash, cur_hash, 16) == 0) {
// The position is updated
tlv_len = data[pos+1];
pos += tlv_len + 2;
break;
@ -1034,12 +1137,11 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
}
// Else, we update the data
int rc = add_data(cur_tlv.node_state->length - 26, be64toh(cur_tlv.node_state->node_id), be16toh(cur_tlv.node_state->seqno), cur_tlv.node_state->data, pdata);
int rc = add_data(tlv_len - 26, be64toh(*id), be16toh(*seqno), (unsigned char*) cur_message, pdata);
if (rc < 0) {
print_error("Error while adding node state !");
}
// The position is updated
tlv_len = data[pos+1];
pos += tlv_len + 2;
break;
@ -1048,12 +1150,14 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
// We received a warning tlv so it's message is printed
cur_tlv.warning = (warning*) (data + pos);
tlv_len = data[pos+1];
cur_message = data + pos + 2;
// Print exactly new_tlv.length characters from new_tlv.message
sprintf(warn, ">> WARNING:\n%%.%ds", cur_tlv.warning->length + 1);
printf(warn, cur_tlv.warning->message);
sprintf(warn, ">> WARNING:\n%%.%ds", tlv_len + 1);
printf(warn, cur_message);
// The position is updated
tlv_len = data[pos+1];
pos += tlv_len + 2;
break;