Compilation fixes

Network filtering code has been temporarely commented out as it is broken
This commit is contained in:
Luca Deri 2020-11-10 17:58:35 +01:00
parent 90bb3eaf92
commit 6bd375efc4
4 changed files with 780 additions and 694 deletions

View File

@ -109,6 +109,51 @@ struct ether_hdr
typedef struct ether_hdr ether_hdr_t;
struct n2n_iphdr {
#if defined(__LITTLE_ENDIAN__)
u_int8_t ihl:4, version:4;
#elif defined(__BIG_ENDIAN__)
u_int8_t version:4, ihl:4;
#else
# error "Byte order must be defined"
#endif
u_int8_t tos;
u_int16_t tot_len;
u_int16_t id;
u_int16_t frag_off;
u_int8_t ttl;
u_int8_t protocol;
u_int16_t check;
u_int32_t saddr;
u_int32_t daddr;
} __attribute__ ((__packed__));
struct n2n_tcphdr
{
u_int16_t source;
u_int16_t dest;
u_int32_t seq;
u_int32_t ack_seq;
#if defined(__LITTLE_ENDIAN__)
u_int16_t res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, ece:1, cwr:1;
#elif defined(__BIG_ENDIAN__)
u_int16_t doff:4, res1:4, cwr:1, ece:1, urg:1, ack:1, psh:1, rst:1, syn:1, fin:1;
#else
# error "Byte order must be defined"
#endif
u_int16_t window;
u_int16_t check;
u_int16_t urg_ptr;
} __attribute__ ((__packed__));
struct n2n_udphdr
{
u_int16_t source;
u_int16_t dest;
u_int16_t len;
u_int16_t check;
} __attribute__ ((__packed__));
#ifdef HAVE_LIBZSTD
#include <zstd.h>
#endif
@ -310,7 +355,8 @@ typedef struct network_traffic_filter
/* A packet has been received from a peer. N2N_DROP can be returned to
* drop the packet. The packet payload can be modified. This only allows
* the packet size to be reduced */
n2n_verdict (*filter_packet_from_peer)(struct network_traffic_filter* filter, n2n_edge_t *eee, const n2n_sock_t *peer, uint8_t *payload, uint16_t payload_size);
n2n_verdict (*filter_packet_from_peer)(struct network_traffic_filter* filter, n2n_edge_t *eee,
const n2n_sock_t *peer, uint8_t *payload, uint16_t payload_size);
/* A packet has been received from the TAP interface. N2N_DROP can be
* returned to drop the packet. The packet payload can be modified.
@ -361,7 +407,9 @@ typedef struct n2n_edge_conf {
int register_ttl; /**< TTL for registration packet when UDP NAT hole punching through supernode. */
int local_port;
int mgmt_port;
#ifdef FILTER_TRAFFIC
filter_rule_t *network_traffic_filter_rules;
#endif
} n2n_edge_conf_t;

View File

@ -35,8 +35,8 @@
#include "network_traffic_filter.h"
static cap_value_t cap_values[] = {
//CAP_NET_RAW, /* Use RAW and PACKET sockets */
CAP_NET_ADMIN /* Needed to performs routes cleanup at exit */
//CAP_NET_RAW, /* Use RAW and PACKET sockets */
CAP_NET_ADMIN /* Needed to performs routes cleanup at exit */
};
int num_cap = sizeof(cap_values)/sizeof(cap_value_t);
@ -144,7 +144,11 @@ static void help() {
#ifndef __APPLE__
"[-D] "
#endif
"[-r] [-E] [-v] [-i <reg_interval>] [-L <reg_ttl>] [-t <mgmt port>] [-A[<cipher>]] [-H] [-z[<compression algo>]] [-R <rule_str>] [-h]\n\n");
"[-r] [-E] [-v] [-i <reg_interval>] [-L <reg_ttl>] [-t <mgmt port>] [-A[<cipher>]] [-H] [-z[<compression algo>]] "
#ifdef FILTER_TRAFFIC
"[-R <rule_str>] "
#endif
"[-h]\n\n");
#if defined(N2N_CAN_NAME_IFACE)
printf("-d <tap device> | tap device name\n");
@ -176,14 +180,14 @@ static void help() {
printf("-A1 | Disable payload encryption. Do not use with key (defaulting to Twofish then).\n");
printf("-A2 ... -A5 or -A | Choose a cipher for payload encryption, requires a key: -A2 = Twofish (default),\n");
printf(" | -A3 or -A (deprecated) = AES, "
"-A4 = ChaCha20, "
"-A5 = Speck-CTR.\n");
"-A4 = ChaCha20, "
"-A5 = Speck-CTR.\n");
printf("-H | Enable full header encryption. Requires supernode with fixed community.\n");
printf("-z1 ... -z2 or -z | Enable compression for outgoing data packets: -z1 or -z = lzo1x"
#ifdef N2N_HAVE_ZSTD
", -z2 = zstd"
", -z2 = zstd"
#endif
" (default=disabled).\n");
" (default=disabled).\n");
printf("-E | Accept multicast MAC addresses (default=drop).\n");
printf("-S | Do not connect P2P. Always use the supernode.\n");
#ifdef __linux__
@ -383,10 +387,10 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
case 'H': /* indicate header encryption */
{
/* we cannot be sure if this gets parsed before the community name is set.
* so, only an indicator is set, action is taken later*/
conf->header_encryption = HEADER_ENCRYPTION_ENABLED;
break;
/* we cannot be sure if this gets parsed before the community name is set.
* so, only an indicator is set, action is taken later*/
conf->header_encryption = HEADER_ENCRYPTION_ENABLED;
break;
}
case 'z':
@ -440,10 +444,10 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
{
conf->local_port = atoi(optargument);
if(conf->local_port == 0){
traceEvent(TRACE_WARNING, "Bad local port format");
break;
}
if(conf->local_port == 0){
traceEvent(TRACE_WARNING, "Bad local port format");
break;
}
break;
}
@ -519,21 +523,23 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
setTraceLevel(getTraceLevel() + 1);
break;
#ifdef FILTER_TRAFFIC
case 'R': /* network traffic filter */
{
filter_rule_t *new_rule = malloc(sizeof(filter_rule_t));
memset(new_rule, 0, sizeof(filter_rule_t));
if(process_traffic_filter_rule_str(optargument, new_rule) )
{
HASH_ADD(hh, conf->network_traffic_filter_rules, key, sizeof(filter_rule_key_t), new_rule);
}else{
filter_rule_t *new_rule = malloc(sizeof(filter_rule_t));
memset(new_rule, 0, sizeof(filter_rule_t));
if(process_traffic_filter_rule_str(optargument, new_rule) )
{
HASH_ADD(hh, conf->network_traffic_filter_rules, key, sizeof(filter_rule_key_t), new_rule);
}else{
free(new_rule);
traceEvent(TRACE_WARNING, "Invalid filter rule: %s", optargument);
return(-1);
}
break;
}
break;
}
#endif
default:
{
traceEvent(TRACE_WARNING, "Unknown option -%c: Ignored", (char)optkey);
@ -548,15 +554,15 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
static const struct option long_options[] =
{
{ "community", required_argument, NULL, 'c' },
{ "supernode-list", required_argument, NULL, 'l' },
{ "tap-device", required_argument, NULL, 'd' },
{ "euid", required_argument, NULL, 'u' },
{ "egid", required_argument, NULL, 'g' },
{ "help" , no_argument, NULL, 'h' },
{ "verbose", no_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 }
};
{ "community", required_argument, NULL, 'c' },
{ "supernode-list", required_argument, NULL, 'l' },
{ "tap-device", required_argument, NULL, 'd' },
{ "euid", required_argument, NULL, 'u' },
{ "egid", required_argument, NULL, 'g' },
{ "help" , no_argument, NULL, 'h' },
{ "verbose", no_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 }
};
/* *************************************************** */
@ -842,48 +848,48 @@ int main(int argc, char* argv[]) {
if(conf.encrypt_key && !strcmp((char*)conf.community_name, conf.encrypt_key))
traceEvent(TRACE_WARNING, "Community and encryption key must differ, otherwise security will be compromised");
if((eee = edge_init(&conf, &rc)) == NULL) {
traceEvent(TRACE_ERROR, "Failed in edge_init");
exit(1);
if((eee = edge_init(&conf, &rc)) == NULL) {
traceEvent(TRACE_ERROR, "Failed in edge_init");
exit(1);
}
memcpy(&(eee->tuntap_priv_conf), &ec, sizeof(ec));
if ((0 == strcmp("static", eee->tuntap_priv_conf.ip_mode)) ||
((eee->tuntap_priv_conf.ip_mode[0] == '\0') && (eee->tuntap_priv_conf.ip_addr[0] != '\0'))) {
traceEvent(TRACE_NORMAL, "Use manually set IP address.");
eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_STATIC;
} else if (0 == strcmp("dhcp", eee->tuntap_priv_conf.ip_mode)) {
traceEvent(TRACE_NORMAL, "Obtain IP from other edge DHCP services.");
eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_DHCP;
} else {
traceEvent(TRACE_NORMAL, "Automatically assign IP address by supernode.");
eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN;
do {
fd_set socket_mask;
struct timeval wait_time;
update_supernode_reg(eee, time(NULL));
FD_ZERO(&socket_mask);
FD_SET(eee->udp_sock, &socket_mask);
wait_time.tv_sec = SOCKET_TIMEOUT_INTERVAL_SECS;
wait_time.tv_usec = 0;
if (select(eee->udp_sock + 1, &socket_mask, NULL, NULL, &wait_time) > 0) {
if (FD_ISSET(eee->udp_sock, &socket_mask)) {
readFromIPSocket(eee, eee->udp_sock);
}
memcpy(&(eee->tuntap_priv_conf), &ec, sizeof(ec));
}
} while (eee->sn_wait);
eee->last_register_req = 0;
}
if ((0 == strcmp("static", eee->tuntap_priv_conf.ip_mode)) ||
((eee->tuntap_priv_conf.ip_mode[0] == '\0') && (eee->tuntap_priv_conf.ip_addr[0] != '\0'))) {
traceEvent(TRACE_NORMAL, "Use manually set IP address.");
eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_STATIC;
} else if (0 == strcmp("dhcp", eee->tuntap_priv_conf.ip_mode)) {
traceEvent(TRACE_NORMAL, "Obtain IP from other edge DHCP services.");
eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_DHCP;
} else {
traceEvent(TRACE_NORMAL, "Automatically assign IP address by supernode.");
eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN;
do {
fd_set socket_mask;
struct timeval wait_time;
update_supernode_reg(eee, time(NULL));
FD_ZERO(&socket_mask);
FD_SET(eee->udp_sock, &socket_mask);
wait_time.tv_sec = SOCKET_TIMEOUT_INTERVAL_SECS;
wait_time.tv_usec = 0;
if (select(eee->udp_sock + 1, &socket_mask, NULL, NULL, &wait_time) > 0) {
if (FD_ISSET(eee->udp_sock, &socket_mask)) {
readFromIPSocket(eee, eee->udp_sock);
}
}
} while (eee->sn_wait);
eee->last_register_req = 0;
}
if (tuntap_open(&tuntap, eee->tuntap_priv_conf.tuntap_dev_name, eee->tuntap_priv_conf.ip_mode,
eee->tuntap_priv_conf.ip_addr, eee->tuntap_priv_conf.netmask,
eee->tuntap_priv_conf.device_mac, eee->tuntap_priv_conf.mtu) < 0) exit(1);
traceEvent(TRACE_NORMAL, "Local tap IP: %s, Mask: %s",
eee->tuntap_priv_conf.ip_addr, eee->tuntap_priv_conf.netmask);
memcpy(&eee->device, &tuntap, sizeof(tuntap));
// hexdump((unsigned char*)&tuntap,sizeof(tuntap_dev));
if (tuntap_open(&tuntap, eee->tuntap_priv_conf.tuntap_dev_name, eee->tuntap_priv_conf.ip_mode,
eee->tuntap_priv_conf.ip_addr, eee->tuntap_priv_conf.netmask,
eee->tuntap_priv_conf.device_mac, eee->tuntap_priv_conf.mtu) < 0) exit(1);
traceEvent(TRACE_NORMAL, "Local tap IP: %s, Mask: %s",
eee->tuntap_priv_conf.ip_addr, eee->tuntap_priv_conf.netmask);
memcpy(&eee->device, &tuntap, sizeof(tuntap));
// hexdump((unsigned char*)&tuntap,sizeof(tuntap_dev));
#ifndef WIN32
if(eee->tuntap_priv_conf.daemon) {

View File

@ -271,9 +271,11 @@ n2n_edge_t* edge_init(const n2n_edge_conf_t *conf, int *rv) {
goto edge_init_error;
}
eee->network_traffic_filter = create_network_traffic_filter();
#ifdef FILTER_TRAFFIC
eee->network_traffic_filter = create_network_traffic_filter();
network_traffic_filter_add_rule(eee->network_traffic_filter, eee->conf.network_traffic_filter_rules);
#endif
//edge_init_success:
*rv = 0;
return(eee);
@ -726,8 +728,8 @@ static void send_query_peer( n2n_edge_t * eee,
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED){
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
eee->conf.header_iv_ctx,
time_stamp (), pearson_hash_16 (pktbuf, idx));
eee->conf.header_iv_ctx,
time_stamp (), pearson_hash_16 (pktbuf, idx));
}
sendto_sock( eee->udp_sock, pktbuf, idx, &(eee->supernode) );
@ -742,8 +744,8 @@ static void send_query_peer( n2n_edge_t * eee,
/* Re-encrypt the orginal message again for non-repeating IV. */
memcpy(pktbuf, tmp_pkt, idx);
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
eee->conf.header_iv_ctx,
time_stamp (), pearson_hash_16 (pktbuf, idx));
eee->conf.header_iv_ctx,
time_stamp (), pearson_hash_16 (pktbuf, idx));
}
sendto_sock( eee->udp_sock, pktbuf, idx, &(peer->sock));
}
@ -806,23 +808,23 @@ static void send_register_super(n2n_edge_t *eee) {
static int sort_supernodes(n2n_edge_t *eee, time_t now){
struct peer_info *scan, *tmp;
if(eee->curr_sn != eee->conf.supernodes){
eee->curr_sn = eee->conf.supernodes;
memcpy(&eee->supernode, &(eee->curr_sn->sock), sizeof(n2n_sock_t));
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS;
if(eee->curr_sn != eee->conf.supernodes){
eee->curr_sn = eee->conf.supernodes;
memcpy(&eee->supernode, &(eee->curr_sn->sock), sizeof(n2n_sock_t));
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS;
traceEvent(TRACE_INFO, "Registering with supernode [%s][number of supernodes %d][attempts left %u]",
supernode_ip(eee), HASH_COUNT(eee->conf.supernodes), (unsigned int)eee->sup_attempts);
traceEvent(TRACE_INFO, "Registering with supernode [%s][number of supernodes %d][attempts left %u]",
supernode_ip(eee), HASH_COUNT(eee->conf.supernodes), (unsigned int)eee->sup_attempts);
send_register_super(eee);
eee->sn_wait = 1;
}
send_register_super(eee);
eee->sn_wait = 1;
}
if(now - eee->last_sweep > SWEEP_TIME){
if(now - eee->last_sweep > SWEEP_TIME){
if(eee->sn_wait == 0){
// this routine gets periodically called
// it sorts supernodes in ascending order of their ping_time-fields
HASH_SORT(eee->conf.supernodes, ping_time_sort);
HASH_SORT(eee->conf.supernodes, ping_time_sort);
}
HASH_ITER(hh, eee->conf.supernodes, scan, tmp){
@ -1020,7 +1022,7 @@ void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) {
if(supernode2sock(&(eee->supernode), eee->curr_sn->ip_addr) == 0) {
traceEvent(TRACE_INFO, "Registering with supernode [%s][number of supernodes %d][attempts left %u]",
supernode_ip(eee), HASH_COUNT(eee->conf.supernodes), (unsigned int)eee->sup_attempts);
supernode_ip(eee), HASH_COUNT(eee->conf.supernodes), (unsigned int)eee->sup_attempts);
send_register_super(eee);
}
@ -1157,6 +1159,7 @@ static int handle_PACKET(n2n_edge_t * eee,
return(-1);
} else if((!eee->conf.allow_routing) && (!is_multicast)) {
/* Check if it is a routed packet */
if((ntohs(eh->type) == 0x0800) && (eth_size >= ETH_FRAMESIZE + IP4_MIN_SIZE)) {
uint32_t *dst = (uint32_t*)&eth_payload[ETH_FRAMESIZE + IP4_DSTOFFSET];
uint8_t *dst_mac = (uint8_t*)eth_payload;
@ -1178,7 +1181,7 @@ static int handle_PACKET(n2n_edge_t * eee,
}
if( eee->network_traffic_filter->filter_packet_from_peer( eee->network_traffic_filter, eee, orig_sender,
eth_payload, eth_size ) == N2N_DROP){
eth_payload, eth_size ) == N2N_DROP){
traceEvent(TRACE_DEBUG, "Filtered packet %u", (unsigned int)eth_size);
return(0);
}
@ -1347,9 +1350,9 @@ static void readFromMgmtSocket(n2n_edge_t *eee, int *keep_running) {
"community: %s\n",
eee->conf.community_name);
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
" id tun_tap MAC edge hint last_seen\n");
" id tun_tap MAC edge hint last_seen\n");
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"-----------------------------------------------------------------------------------------------\n");
"-----------------------------------------------------------------------------------------------\n");
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"supernode_forward:\n");
@ -1362,9 +1365,9 @@ static void readFromMgmtSocket(n2n_edge_t *eee, int *keep_running) {
" %-4u %-15s %-17s %-21s %-15s %lu\n",
++num, inet_ntoa(*(struct in_addr *) &net),
macaddr_str(mac_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)),
peer->dev_desc,
now - peer->last_seen);
sock_to_cstr(sockbuf, &(peer->sock)),
peer->dev_desc,
now - peer->last_seen);
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
@ -1382,9 +1385,9 @@ static void readFromMgmtSocket(n2n_edge_t *eee, int *keep_running) {
" %-4u %-15s %-17s %-21s %-15s %lu\n",
++num, inet_ntoa(*(struct in_addr *) &net),
macaddr_str(mac_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)),
peer->dev_desc,
now - peer->last_seen);
sock_to_cstr(sockbuf, &(peer->sock)),
peer->dev_desc,
now - peer->last_seen);
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/,
(struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in));
@ -1392,7 +1395,7 @@ static void readFromMgmtSocket(n2n_edge_t *eee, int *keep_running) {
}
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"-----------------------------------------------------------------------------------------------\n");
"-----------------------------------------------------------------------------------------------\n");
msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len),
"uptime %lu | ",
@ -1733,11 +1736,14 @@ void edge_read_from_tap(n2n_edge_t * eee) {
}
else
{
if( eee->network_traffic_filter->filter_packet_from_tap( eee->network_traffic_filter, eee, eth_pkt,
len) == N2N_DROP){
if(eee->network_traffic_filter) {
if( eee->network_traffic_filter->filter_packet_from_tap( eee->network_traffic_filter, eee, eth_pkt,
len) == N2N_DROP){
traceEvent(TRACE_DEBUG, "Filtered packet %u", (unsigned int)len);
return;
}
}
}
if(eee->cb.packet_from_tap) {
uint16_t tmp_len = len;
if(eee->cb.packet_from_tap(eee, eth_pkt, &tmp_len) == N2N_DROP) {
@ -1799,7 +1805,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
* IP transport version the packet arrived on. May need to UDP sockets. */
/* REVISIT: do not endprse use with several supernodes
memset(&sender, 0, sizeof(n2n_sock_t)); */
memset(&sender, 0, sizeof(n2n_sock_t)); */
sender.family = AF_INET; /* UDP socket was opened PF_INET v4 */
sender.port = ntohs(sender_sock.sin_port);
@ -1970,12 +1976,12 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
in_addr_t net;
char * ip_str = NULL;
n2n_REGISTER_SUPER_ACK_t ra;
uint8_t tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE];
n2n_sock_t *tmp_sock;
n2n_mac_t *tmp_mac;
int i;
int skip_add;
struct peer_info *sn;
uint8_t tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE];
n2n_sock_t *tmp_sock;
n2n_mac_t *tmp_mac;
int i;
int skip_add;
struct peer_info *sn;
memset(&ra, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
@ -2037,7 +2043,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
/* REVISIT: find a more elegant expression to increase following pointers. */
tmp_sock = (void*)tmp_sock + REG_SUPER_ACK_PAYLOAD_ENTRY_SIZE;
tmp_mac = (void*)tmp_sock + sizeof(n2n_sock_t);
}
}
eee->last_sup = now;
eee->sn_wait=0;
@ -2309,8 +2315,10 @@ void edge_term(n2n_edge_t * eee) {
edge_cleanup_routes(eee);
#ifdef FILTER_TRAFFIC
destroy_network_traffic_filter(eee->network_traffic_filter);
#endif
closeTraceFile();
free(eee);
@ -2810,16 +2818,17 @@ void edge_term_conf(n2n_edge_conf_t *conf) {
if (conf->routes) free(conf->routes);
if (conf->encrypt_key) free(conf->encrypt_key);
#ifdef FILTER_TRAFFIC
if(conf->network_traffic_filter_rules)
{
filter_rule_t *el = 0, *tmp = 0;
HASH_ITER(hh, conf->network_traffic_filter_rules, el, tmp)
{
HASH_DEL(conf->network_traffic_filter_rules, el);
free(el);
filter_rule_t *el = 0, *tmp = 0;
HASH_ITER(hh, conf->network_traffic_filter_rules, el, tmp)
{
HASH_DEL(conf->network_traffic_filter_rules, el);
free(el);
}
}
}
#endif
}
/* ************************************** */

File diff suppressed because it is too large Load Diff