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:
@@ -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)
|
||||
|
Reference in New Issue
Block a user