This gets us to the point of seemingly being able to wrap and unwrap IPv4

Remarkably hard to test this on a single computer
This commit is contained in:
Nick Thomas
2013-08-06 18:44:13 +01:00
parent 13090d3c75
commit dcb4e5ef28
7 changed files with 189 additions and 13 deletions

View File

@@ -69,7 +69,6 @@ int wrap_ipv4_packet(struct rlocs* reg, struct recv_pkt* pkt, struct rsp_data* o
struct rloc* d_rloc;
struct in_addr tmp;
// TODO: check endianness of saddr/daddr
tmp.s_addr = pkt->hdr.ip.saddr;
if ( ( s_rloc = rloc_find_for_ipv4( reg, &tmp ) ) == NULL ) {
warn( "Couldn't find source rloc, dropping packet" );
@@ -98,7 +97,7 @@ int wrap_ipv4_packet(struct rlocs* reg, struct recv_pkt* pkt, struct rsp_data* o
size_t bytes_to_encrypt;
if ( orig_data_size > 512 ) {
bytes_to_encrypt = pkt->hdr.ip.ihl * 4;
bytes_to_encrypt = 512; // No point wasting bytes on padding
} else {
bytes_to_encrypt = orig_data_size;
}
@@ -140,7 +139,7 @@ int wrap_ipv4_packet(struct rlocs* reg, struct recv_pkt* pkt, struct rsp_data* o
wrap_hdr->tot_len = htons( wrap_hdr_size + enc_size + out->iovs[2].iov_len );
compute_ip_checksum( wrap_hdr );
info( "Finished building return packet" );
info( "Finished wrapping IPv4 packet" );
return 1;
}
@@ -155,8 +154,60 @@ int wrap_ipv6_packet(struct rlocs *reg, struct recv_pkt* pkt, struct rsp_data* o
int unwrap_ipv4_packet(struct rlocs* reg, struct recv_pkt* pkt, struct rsp_data* out)
{
warn( "STUB: unwrap_ipv4_packet" );
return 0;
out->count = 2;
assert( out->count < MAX_IOVS );
// first, check this is actually a hide-eid packet.
if ( pkt->hdr.ip.protocol != IPPROTO_HIDE_EID ) {
warn( "expected IP protocol %u, not %u", IPPROTO_HIDE_EID, pkt->hdr.ip.protocol );
return 0;
}
// We need to know destination rloc to decrypt the packet
struct rloc* rloc;
struct in_addr tmp;
// TODO: check endianness of saddr/daddr
tmp.s_addr = pkt->hdr.ip.daddr;
if ( ( rloc = rloc_find_for_ipv4( reg, &tmp ) ) == NULL ) {
warn( "Couldn't find destination rloc, dropping packet" );
// TODO: we should be able to specify we need it to have a private key
return 0;
}
uint16_t hdr_size = pkt->hdr.ip.ihl * 4;
uint16_t encrypted_size = ntohs( *((uint16_t*)pkt + ( hdr_size / 2 )) );
info( "encrypted_size: %u", encrypted_size );
// iovec 0: decrypted data. This should be an IP header.
unsigned char *encrypted_data = ((unsigned char *)pkt) + hdr_size + 2;
unsigned char *scratch = &out->scratch[0];
int decrypted_size = rloc_decrypt( rloc, encrypted_data, encrypted_size, scratch, IP_MAXPACKET );
if ( decrypted_size < 0 ) {
warn( "Failed to decrypt packet!" );
return 0;
}
info( "decrypted_size: %u", decrypted_size );
out->iovs[0].iov_base = scratch;
out->iovs[0].iov_len = decrypted_size;
// iovec 1: never-encrypted part
out->iovs[1].iov_base = (unsigned char*) pkt + hdr_size + 2;
out->iovs[1].iov_len = ntohs( pkt->hdr.ip.tot_len ) - hdr_size - encrypted_size;
if ( out->iovs[0].iov_len + out->iovs[1].iov_len > IP_MAXPACKET ) {
warn( "Unwrapped packet is too large, dropping it" );
warn( "iovs[0] is %zu, iovs[1] is %zu", out->iovs[0].iov_len, out->iovs[1].iov_len );
warn( "hdr_size = %u, encrypted_size = %u, tot_len = %u", hdr_size, encrypted_size, ntohs( pkt->hdr.ip.tot_len ) );
return 0;
}
info( "Finished unwrapping IPv4 packet" );
return 1;
}
int unwrap_ipv6_packet(struct rlocs *reg, struct recv_pkt* pkt, struct rsp_data* out)