#ifndef _RLOCS_H_ #define _RLOCS_H_ #include "util.h" #include #include #include #include // For now. We can dynamically allocate later. #define MAX_RLOCS 64 #define MAX_EID_MAPPINGS 256 // Just a guess, but 20-byte IP header, 16-byte IV, 16-byte tag, 16 bytes for symmetric block padding #define DEFAULT_PATH_MTU 1500 - ( 20 + 16 + 16 + 16 ) struct peer_context { int in_use; char secret[SHA256_DIGEST_LENGTH]; EVP_CIPHER_CTX ctx; unsigned int path_mtu; struct rlocs *reg; struct rloc *x; struct rloc *y; }; typedef struct peer_context PeerCtx; struct rloc { int in_use; short family; union { struct in_addr ip4; struct in6_addr ip6; } addr; EVP_PKEY *key; // We use this to index our rloc for shared keys int context_id; char presentation[128]; }; struct ip4_eid_map_entry { struct in_addr network; struct in_addr broadcast; unsigned int mask; struct rloc *rloc; }; struct ip6_eid_map_entry { struct in6_addr network; struct in6_addr broadcast; unsigned int mask; struct rloc *rloc; }; struct rlocs { json_object *config; size_t num_entries; struct rloc entries[MAX_RLOCS]; size_t num_ip4_map_entries; struct ip4_eid_map_entry ip4_mappings[MAX_EID_MAPPINGS]; size_t num_ip6_map_entries; struct ip6_eid_map_entry ip6_mappings[MAX_EID_MAPPINGS]; /* Don't do this, kids. * 2D array - [wrapping_rloc->id][unwrapping_rloc->id] * Obviously, half of the contexts would be identical. So some rules: * - if you're wrapping a packet, you are x. they are y * - if you're unwrapping a packet, you are y. they are x. * Half of the allocated memory goes unused, but we can worry about dynamic * allocation at the same time as MAX_RLOCS and MAX_EID_MAPPINGS */ struct peer_context peer_contexts[MAX_RLOCS][MAX_RLOCS]; }; void rlocs_init(void); struct rlocs *rlocs_new( char *filename ); // find a struct rlocs corresponding to a particular IPv4 eid struct rloc *rloc_find_for_ipv4( struct rlocs *reg, struct in_addr *eid ); // find a struct rlocs corresponding to a particular IPv6 eid struct rloc *rloc_find_for_ipv6( struct rlocs *reg, struct in6_addr *eid ); // find a struct rloc corresponding to a particular IPv4 or IPv6 RLOC struct rloc *rloc_find_by_address( struct rlocs *reg, struct in_addr *ipv4, struct in6_addr *ipv6 ); int rlocs_find_two_ipv4( struct rlocs *reg, struct rloc **s_rloc_ptr, struct in_addr *s_rloc_addr, struct rloc **d_rloc_ptr, struct in_addr *d_rloc_addr ); struct peer_context *rlocs_get_peer_ctx( struct rlocs *reg, struct rloc *x, struct rloc *y ); int rlocs_add_private_key( struct rlocs *reg, struct rloc *rloc, char *filename ); void rlocs_debug_output( struct rlocs *reg ); /* Returns -1 on error, or number of bytes written */ ssize_t rlocs_encrypt( struct peer_context *pctx, unsigned char *data, size_t data_len, unsigned char *dest, size_t dest_len ); ssize_t rlocs_decrypt( struct peer_context *pctx, unsigned char *data, size_t data_len, unsigned char *dest, size_t dest_len ); unsigned short rlocs_get_path_mtu( struct rlocs *reg, struct rloc *x, struct rloc *y ); void rlocs_set_path_mtu( struct rlocs *reg, struct rloc *x, struct rloc *y, unsigned short new_mtu ); void rlocs_free( struct rlocs *registry ); #endif