121 lines
3.4 KiB
C
121 lines
3.4 KiB
C
#ifndef _RLOCS_H_
|
|
#define _RLOCS_H_
|
|
|
|
#include "util.h"
|
|
|
|
#include <json/json_object.h>
|
|
#include <netinet/in.h>
|
|
|
|
#include <openssl/evp.h>
|
|
#include <openssl/sha.h>
|
|
|
|
// 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
|