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 // 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);
@ -35,9 +39,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
if (SHA256(concat, totlen, hash) == NULL) { SHA256_CTX sha256;
print_debug(">> Doing the hash failed : function return NULL, should return a pointer."); 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);

View File

@ -698,6 +698,51 @@ int validate_tlv(char *data, int pos, uint16_t packet_len){
return 7; return 7;
case 8: case 8:
if(tlv_len < MIN_LEN_NODE_STATE || tlv_len > MAX_LEN_NODE_STATE) return -1; 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; return 8;
case 9: case 9:
return 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 nbr_of_tlvs = 0;
int pos = 4; int pos = 4;
unsigned char tlv_len, hash[16]; unsigned char tlv_len, hash[16], hash2[16];
char warn[32]; char warn[32];
// The TLV we are going to send back. // 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; 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) { while(pos < total_packet_len) {
// Making sure the current TLV we are looking at is valid. // Making sure the current TLV we are looking at is valid.
// TODO : I think we should reset all the structs here. // 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."); print_debug(">> Received neighbour tlv, sending back network hash.");
// We received a neighbour tlv so a tlv network hash is sent to that address // 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 // Init dest socket
memset(&new_neighbour, 0, sizeof(new_neighbour)); memset(&new_neighbour, 0, sizeof(new_neighbour));
new_neighbour.sin6_family = AF_INET6; new_neighbour.sin6_family = AF_INET6;
memcpy(&new_neighbour.sin6_addr, &cur_tlv.neighbour->ip, 16); memcpy(&new_neighbour.sin6_addr, ip, 16);
new_neighbour.sin6_port = be16toh(cur_tlv.neighbour->port); new_neighbour.sin6_port = be16toh(*port);
new_neighbour.sin6_scope_id = ifindex; new_neighbour.sin6_scope_id = ifindex;
// Build network hash // 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.."); print_debug(">> Received network_hash, comparing with our own..");
// We reveived a network hash tlv so we compare the hash 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 // 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); hash_network(data_list, hash);
if (DEBUG_LEVEL > 1) { 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("\n");
printf("\x1b[31m[DEBUG]\x1b[0m >> Received : "); printf("\x1b[31m[DEBUG]\x1b[0m >> Received : ");
for(int x = 0; x < 16; x++){ for(int x = 0; x < 16; x++){
printf("%02x", cur_tlv.network_hash->network_hash[x]); printf("%02x", cur_hash[x]);
fflush(0); fflush(0);
} }
printf("\n"); 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."); print_debug(">> Sending out our network hash.");
build_network_state_req(&new_tlv); build_network_state_req(&new_tlv);
send_single_tlv(&new_tlv, sender, socket_num); 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, // we send a node state request,
//if the hashes are identical nothing has to be done //if the hashes are identical nothing has to be done
print_debug(">> Received node hash, updating message entry..."); 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 data is found for this id then we check that both hashes are the same
if(pdata != NULL) { if(pdata != NULL) {
print_debug(">> Comparing hashes...");
// We hash the data stored in the data list // We hash the data stored in the data list
hash_data(pdata, hash); hash_data(pdata, hash);
// If both hashes are the same then nothing has to be done // 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 // The position is updated
tlv_len = data[pos+1]; tlv_len = data[pos+1];
pos += tlv_len + 2; 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 // 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); add_tlv(&pack, &new_tlv, sender, socket_num);
// The position is updated // 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, // so a node state tlv for this node id has to be sent,
// if no pub_data exists for this id nothing is sent // if no pub_data exists for this id nothing is sent
print_debug(">> Received node state request. Processing..."); 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) { if(pdata != NULL) {
build_node_state(&new_tlv, pdata->id, pdata->seqno, pdata->data, pdata->length); 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 // we add it to the data list
// or update the data stored // or update the data stored
print_debug(">> Received node state, updating..."); 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 ! "); print_debug(">> Received message ! ");
printf("Type : %d\n", cur_tlv.node_state->type ); printf("Type : %d\n", data[pos] );
printf("Length : %d\n", cur_tlv.node_state->length ); printf("Length : %d\n", tlv_len );
printf("Node ID : %lu\n", be64toh(cur_tlv.node_state->node_id) ); printf("Node ID : %lu\n", be64toh(*id) );
printf("Seqno : %hu\n", be16toh(cur_tlv.node_state->seqno) ); printf("Seqno : %hu\n", be16toh(*seqno) );
printf("Hash :"); printf("Hash :");
for(int x = 0; x < 16; x++){ for(int x = 0; x < 16; x++){
printf("%02x", cur_tlv.node_state->node_hash[x]); printf("%02x", cur_hash[x]);
fflush(0); fflush(0);
} }
printf("\n"); printf("\n");
for(int x = 0; x < 192; x++){ for(int x = 0; x < tlv_len; x++){
printf("%d", cur_tlv.node_state->data[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); 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 (DEBUG_LEVEL > 0) {
if (cur_tlv.node_state->data == NULL) { if (cur_message == NULL) {
print_error("The data in the current node is NULL !"); print_error("The data in the current node is NULL !");
return -1; 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); sleep(1);
} }
*/
// Compare hashes // 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 data is found for this id then we check that both hashes are the same
if(pdata != NULL) { if(pdata != NULL) {
print_debug(">> Comparing hashes...");
// We hash the data stored in the data list // We hash the data stored in the data list
memset(hash, 0, 16); memset(hash, 0, 16);
hash_data(pdata, hash); hash_data(pdata, hash);
// If both hashes are the same then nothing has to be done // 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 // The position is updated
tlv_len = data[pos+1];
pos += tlv_len + 2; pos += tlv_len + 2;
break; break;
@ -1034,12 +1137,11 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 *
} }
// Else, we update the data // 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) { if (rc < 0) {
print_error("Error while adding node state !"); print_error("Error while adding node state !");
} }
// The position is updated // The position is updated
tlv_len = data[pos+1];
pos += tlv_len + 2; pos += tlv_len + 2;
break; 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 // We received a warning tlv so it's message is printed
cur_tlv.warning = (warning*) (data + pos); 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 // Print exactly new_tlv.length characters from new_tlv.message
sprintf(warn, ">> WARNING:\n%%.%ds", cur_tlv.warning->length + 1); sprintf(warn, ">> WARNING:\n%%.%ds", tlv_len + 1);
printf(warn, cur_tlv.warning->message); printf(warn, cur_message);
// The position is updated // The position is updated
tlv_len = data[pos+1];
pos += tlv_len + 2; pos += tlv_len + 2;
break; break;