Browse Source

Compilation fixes

Network filtering code has been temporarely commented out as it is broken
pull/497/head
Luca Deri 4 years ago
parent
commit
6bd375efc4
  1. 50
      include/n2n.h
  2. 8
      src/edge.c
  3. 11
      src/edge_utils.c
  4. 71
      src/network_traffic_filter.c

50
include/n2n.h

@ -109,6 +109,51 @@ struct ether_hdr
typedef struct ether_hdr ether_hdr_t; 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 #ifdef HAVE_LIBZSTD
#include <zstd.h> #include <zstd.h>
#endif #endif
@ -310,7 +355,8 @@ typedef struct network_traffic_filter
/* A packet has been received from a peer. N2N_DROP can be returned to /* 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 * drop the packet. The packet payload can be modified. This only allows
* the packet size to be reduced */ * 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 /* A packet has been received from the TAP interface. N2N_DROP can be
* returned to drop the packet. The packet payload can be modified. * 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 register_ttl; /**< TTL for registration packet when UDP NAT hole punching through supernode. */
int local_port; int local_port;
int mgmt_port; int mgmt_port;
#ifdef FILTER_TRAFFIC
filter_rule_t *network_traffic_filter_rules; filter_rule_t *network_traffic_filter_rules;
#endif
} n2n_edge_conf_t; } n2n_edge_conf_t;

8
src/edge.c

@ -144,7 +144,11 @@ static void help() {
#ifndef __APPLE__ #ifndef __APPLE__
"[-D] " "[-D] "
#endif #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) #if defined(N2N_CAN_NAME_IFACE)
printf("-d <tap device> | tap device name\n"); printf("-d <tap device> | tap device name\n");
@ -519,6 +523,7 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
setTraceLevel(getTraceLevel() + 1); setTraceLevel(getTraceLevel() + 1);
break; break;
#ifdef FILTER_TRAFFIC
case 'R': /* network traffic filter */ case 'R': /* network traffic filter */
{ {
filter_rule_t *new_rule = malloc(sizeof(filter_rule_t)); filter_rule_t *new_rule = malloc(sizeof(filter_rule_t));
@ -533,6 +538,7 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
} }
break; break;
} }
#endif
default: default:
{ {

11
src/edge_utils.c

@ -271,8 +271,10 @@ n2n_edge_t* edge_init(const n2n_edge_conf_t *conf, int *rv) {
goto edge_init_error; goto edge_init_error;
} }
#ifdef FILTER_TRAFFIC
eee->network_traffic_filter = create_network_traffic_filter(); eee->network_traffic_filter = create_network_traffic_filter();
network_traffic_filter_add_rule(eee->network_traffic_filter, eee->conf.network_traffic_filter_rules); network_traffic_filter_add_rule(eee->network_traffic_filter, eee->conf.network_traffic_filter_rules);
#endif
//edge_init_success: //edge_init_success:
*rv = 0; *rv = 0;
@ -1157,6 +1159,7 @@ static int handle_PACKET(n2n_edge_t * eee,
return(-1); return(-1);
} else if((!eee->conf.allow_routing) && (!is_multicast)) { } else if((!eee->conf.allow_routing) && (!is_multicast)) {
/* Check if it is a routed packet */ /* Check if it is a routed packet */
if((ntohs(eh->type) == 0x0800) && (eth_size >= ETH_FRAMESIZE + IP4_MIN_SIZE)) { if((ntohs(eh->type) == 0x0800) && (eth_size >= ETH_FRAMESIZE + IP4_MIN_SIZE)) {
uint32_t *dst = (uint32_t*)&eth_payload[ETH_FRAMESIZE + IP4_DSTOFFSET]; uint32_t *dst = (uint32_t*)&eth_payload[ETH_FRAMESIZE + IP4_DSTOFFSET];
uint8_t *dst_mac = (uint8_t*)eth_payload; uint8_t *dst_mac = (uint8_t*)eth_payload;
@ -1733,11 +1736,14 @@ void edge_read_from_tap(n2n_edge_t * eee) {
} }
else else
{ {
if(eee->network_traffic_filter) {
if( eee->network_traffic_filter->filter_packet_from_tap( eee->network_traffic_filter, eee, eth_pkt, if( eee->network_traffic_filter->filter_packet_from_tap( eee->network_traffic_filter, eee, eth_pkt,
len) == N2N_DROP){ len) == N2N_DROP){
traceEvent(TRACE_DEBUG, "Filtered packet %u", (unsigned int)len); traceEvent(TRACE_DEBUG, "Filtered packet %u", (unsigned int)len);
return; return;
} }
}
if(eee->cb.packet_from_tap) { if(eee->cb.packet_from_tap) {
uint16_t tmp_len = len; uint16_t tmp_len = len;
if(eee->cb.packet_from_tap(eee, eth_pkt, &tmp_len) == N2N_DROP) { if(eee->cb.packet_from_tap(eee, eth_pkt, &tmp_len) == N2N_DROP) {
@ -2309,7 +2315,9 @@ void edge_term(n2n_edge_t * eee) {
edge_cleanup_routes(eee); edge_cleanup_routes(eee);
#ifdef FILTER_TRAFFIC
destroy_network_traffic_filter(eee->network_traffic_filter); destroy_network_traffic_filter(eee->network_traffic_filter);
#endif
closeTraceFile(); closeTraceFile();
@ -2810,6 +2818,7 @@ void edge_term_conf(n2n_edge_conf_t *conf) {
if (conf->routes) free(conf->routes); if (conf->routes) free(conf->routes);
if (conf->encrypt_key) free(conf->encrypt_key); if (conf->encrypt_key) free(conf->encrypt_key);
#ifdef FILTER_TRAFFIC
if(conf->network_traffic_filter_rules) if(conf->network_traffic_filter_rules)
{ {
filter_rule_t *el = 0, *tmp = 0; filter_rule_t *el = 0, *tmp = 0;
@ -2819,7 +2828,7 @@ void edge_term_conf(n2n_edge_conf_t *conf) {
free(el); free(el);
} }
} }
#endif
} }
/* ************************************** */ /* ************************************** */

71
src/network_traffic_filter.c

@ -16,6 +16,7 @@
* *
*/ */
#ifdef FILTER_TRAFFIC
#include "network_traffic_filter.h" #include "network_traffic_filter.h"
#include "uthash.h" #include "uthash.h"
@ -89,14 +90,17 @@ const char* get_filter_packet_info_log_string(packet_address_proto_info_t* info)
} }
void collect_packet_info(packet_address_proto_info_t* out_info, unsigned char *buffer, int size) { void collect_packet_info(packet_address_proto_info_t* out_info, unsigned char *buffer, int size) {
struct ethhdr *hdr_ether = (struct ethhdr*)buffer; ether_hdr_t *hdr_ether = (ether_hdr_t*)buffer;
uint16_t ether_type = ntohs(hdr_ether->type);
memset(out_info, 0, sizeof(packet_address_proto_info_t)); memset(out_info, 0, sizeof(packet_address_proto_info_t));
uint16_t ether_type = ntohs(hdr_ether->h_proto);
switch (ether_type) { switch (ether_type) {
case 0x0800: case 0x0800:
{ {
buffer += ETH_HLEN; size -= ETH_HLEN; if(size <= 0) return; buffer += sizeof(ether_hdr_t); size -= sizeof(ether_hdr_t); if(size <= 0) return;
struct iphdr *hdr_ip = (struct iphdr*)buffer; struct n2n_iphdr *hdr_ip = (struct n2n_iphdr*)buffer;
switch (hdr_ip->version) switch (hdr_ip->version)
{ {
case 4: case 4:
@ -114,18 +118,18 @@ void collect_packet_info(packet_address_proto_info_t* out_info, unsigned char *b
{ {
out_info->proto = FPP_TCP; out_info->proto = FPP_TCP;
buffer += hdr_ip->ihl * 4; size -= hdr_ip->ihl * 4; if(size <= 0) return; buffer += hdr_ip->ihl * 4; size -= hdr_ip->ihl * 4; if(size <= 0) return;
struct tcphdr *hdr_tcp = (struct tcphdr*)buffer; struct n2n_tcphdr *hdr_tcp = (struct n2n_tcphdr*)buffer;
out_info->src_port = ntohs(hdr_tcp->th_sport); out_info->src_port = ntohs(hdr_tcp->source);
out_info->dst_port = ntohs(hdr_tcp->th_dport); out_info->dst_port = ntohs(hdr_tcp->dest);
break; break;
} }
case 0x11: case 0x11:
{ {
out_info->proto = FPP_UDP; out_info->proto = FPP_UDP;
buffer += hdr_ip->ihl * 4; size -= hdr_ip->ihl * 4; if(size <= 0) return; buffer += hdr_ip->ihl * 4; size -= hdr_ip->ihl * 4; if(size <= 0) return;
struct udphdr *udp_hdr = (struct tcphdr*)buffer; struct n2n_udphdr *udp_hdr = (struct n2n_udphdr*)buffer;
out_info->src_port = ntohs(udp_hdr->uh_sport); out_info->src_port = ntohs(udp_hdr->source);
out_info->dst_port = ntohs(udp_hdr->uh_dport); out_info->dst_port = ntohs(udp_hdr->dest);
break; break;
} }
default: default:
@ -161,13 +165,20 @@ const char* get_filter_rule_info_log_string(filter_rule_t* rule)
char* print_start = buf; char* print_start = buf;
char src_net[64] = {0}; char dst_net[64] = {0}; char src_net[64] = {0}; char dst_net[64] = {0};
struct in_addr src, dst; struct in_addr src, dst;
src.s_addr = rule->key.src_net_cidr; src.s_addr = rule->key.src_net_cidr;
dst.s_addr = rule->key.dst_net_cidr; dst.s_addr = rule->key.dst_net_cidr;
strcpy(src_net, inet_ntoa(src)); strcpy(dst_net, inet_ntoa(dst)); strcpy(src_net, inet_ntoa(src)); strcpy(dst_net, inet_ntoa(dst));
print_start += sprintf(print_start, "%s/%d:[%d,%d],%s/%d:[%d,%d]", print_start += sprintf(print_start, "%s/%d:[%d,%d],%s/%d:[%d,%d]",
src_net, rule->key.src_net_bit_len, rule->key.src_port_range.start_port, rule->key.src_port_range.end_port, src_net, rule->key.src_net_bit_len,
dst_net, rule->key.dst_net_bit_len, rule->key.dst_port_range.start_port, rule->key.dst_port_range.end_port, rule->key.src_port_range.start_port, rule->key.src_port_range.end_port,
rule->bool_accept_tcp ? '+' : '-', rule->bool_accept_udp ? '+' : '-', rule->bool_accept_icmp ? '+' : '-'); dst_net, rule->key.dst_net_bit_len,
rule->key.dst_port_range.start_port, rule->key.dst_port_range.end_port
#if 0
,
rule->bool_accept_tcp ? '+' : '-', rule->bool_accept_udp ? '+' : '-', rule->bool_accept_icmp ? '+' : '-'
#endif
);
if(rule->key.bool_tcp_configured) if(rule->key.bool_tcp_configured)
print_start += sprintf(print_start, ",TCP%c", rule->bool_accept_tcp ? '+' : '-'); print_start += sprintf(print_start, ",TCP%c", rule->bool_accept_tcp ? '+' : '-');
if(rule->key.bool_udp_configured) if(rule->key.bool_udp_configured)
@ -229,9 +240,9 @@ uint8_t march_rule_and_cache_key(filter_rule_key_t *rule_key, packet_address_pro
uint8_t march_dst_score = march_cidr_and_address(rule_key->dst_net_cidr, rule_key->dst_net_bit_len, pkt_addr_info->dst_ip); uint8_t march_dst_score = march_cidr_and_address(rule_key->dst_net_cidr, rule_key->dst_net_bit_len, pkt_addr_info->dst_ip);
if( march_src_score > 0 && march_dst_score > 0 ) if( march_src_score > 0 && march_dst_score > 0 )
return march_src_score + march_dst_score; return march_src_score + march_dst_score;
}else{
return 0;
} }
return(0);
} }
filter_rule_t* get_filter_rule(filter_rule_t **rules, packet_address_proto_info_t *pkt_addr_info) filter_rule_t* get_filter_rule(filter_rule_t **rules, packet_address_proto_info_t *pkt_addr_info)
@ -253,9 +264,11 @@ filter_rule_t* get_filter_rule(filter_rule_t **rules, packet_address_proto_info_
typedef struct network_traffic_filter_impl typedef struct network_traffic_filter_impl
{ {
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);
n2n_verdict (*filter_packet_from_tap)(struct network_traffic_filter* filter, n2n_edge_t *eee, uint8_t *payload, uint16_t payload_size); n2n_verdict (*filter_packet_from_tap)(struct network_traffic_filter* filter, n2n_edge_t *eee,
uint8_t *payload, uint16_t payload_size);
filter_rule_t *rules; filter_rule_t *rules;
@ -325,6 +338,7 @@ n2n_verdict filter_packet_from_peer(network_traffic_filter_impl_t *filter, n2n_e
{ {
filter_rule_pair_cache_t *cur_pkt_rule = 0; filter_rule_pair_cache_t *cur_pkt_rule = 0;
packet_address_proto_info_t pkt_info; packet_address_proto_info_t pkt_info;
collect_packet_info(&pkt_info, payload, payload_size); collect_packet_info(&pkt_info, payload, payload_size);
cur_pkt_rule = get_or_create_filter_rule_cache(filter, &pkt_info); cur_pkt_rule = get_or_create_filter_rule_cache(filter, &pkt_info);
if( cur_pkt_rule && !cur_pkt_rule->bool_allow_traffic) if( cur_pkt_rule && !cur_pkt_rule->bool_allow_traffic)
@ -340,6 +354,7 @@ n2n_verdict filter_packet_from_tap(network_traffic_filter_impl_t *filter, n2n_ed
{ {
filter_rule_pair_cache_t *cur_pkt_rule = 0; filter_rule_pair_cache_t *cur_pkt_rule = 0;
packet_address_proto_info_t pkt_info; packet_address_proto_info_t pkt_info;
collect_packet_info(&pkt_info, payload, payload_size); collect_packet_info(&pkt_info, payload, payload_size);
cur_pkt_rule = get_or_create_filter_rule_cache(filter, &pkt_info); cur_pkt_rule = get_or_create_filter_rule_cache(filter, &pkt_info);
if( cur_pkt_rule && !cur_pkt_rule->bool_allow_traffic) if( cur_pkt_rule && !cur_pkt_rule->bool_allow_traffic)
@ -352,6 +367,7 @@ n2n_verdict filter_packet_from_tap(network_traffic_filter_impl_t *filter, n2n_ed
network_traffic_filter_t *create_network_traffic_filter() { network_traffic_filter_t *create_network_traffic_filter() {
network_traffic_filter_impl_t *filter = malloc(sizeof(network_traffic_filter_impl_t)); network_traffic_filter_impl_t *filter = malloc(sizeof(network_traffic_filter_impl_t));
memset(filter, 0, sizeof(network_traffic_filter_impl_t)); memset(filter, 0, sizeof(network_traffic_filter_impl_t));
filter->filter_packet_from_peer = filter_packet_from_peer; filter->filter_packet_from_peer = filter_packet_from_peer;
filter->filter_packet_from_tap = filter_packet_from_tap; filter->filter_packet_from_tap = filter_packet_from_tap;
@ -360,30 +376,27 @@ network_traffic_filter_t *create_network_traffic_filter() {
void destroy_network_traffic_filter(network_traffic_filter_t *filter) { void destroy_network_traffic_filter(network_traffic_filter_t *filter) {
network_traffic_filter_impl_t *_filter = filter; network_traffic_filter_impl_t *_filter = filter;
{
filter_rule_t *el = 0, *tmp = 0; filter_rule_t *el = 0, *tmp = 0;
filter_rule_pair_cache_t *el = 0, *tmp = 0;
HASH_ITER(hh, _filter->rules, el, tmp) HASH_ITER(hh, _filter->rules, el, tmp)
{ {
HASH_DEL(_filter->rules, el); HASH_DEL(_filter->rules, el);
free(el); free(el);
} }
}
{
filter_rule_pair_cache_t *el = 0, *tmp = 0;
HASH_ITER(hh, _filter->connections_rule_cache, el, tmp) HASH_ITER(hh, _filter->connections_rule_cache, el, tmp)
{ {
HASH_DEL(_filter->connections_rule_cache, el); HASH_DEL(_filter->connections_rule_cache, el);
free(el); free(el);
} }
}
free(filter); free(filter);
} }
void network_traffic_filter_add_rule(network_traffic_filter_t* filter, filter_rule_t* rules) { void network_traffic_filter_add_rule(network_traffic_filter_t* filter, filter_rule_t* rules) {
filter_rule_t *item=NULL, *tmp=NULL; filter_rule_t *item=NULL, *tmp=NULL;
HASH_ITER(hh, rules, item, tmp) { HASH_ITER(hh, rules, item, tmp) {
network_traffic_filter_impl_t *_filter = filter; network_traffic_filter_impl_t *_filter = filter;
filter_rule_t *new_rule = malloc(sizeof(filter_rule_t)); filter_rule_t *new_rule = malloc(sizeof(filter_rule_t));
@ -396,12 +409,15 @@ void network_traffic_filter_add_rule(network_traffic_filter_t* filter, filter_ru
in_addr_t get_int32_addr_from_ip_string(const char* begin, const char* next_pos_of_last_char) in_addr_t get_int32_addr_from_ip_string(const char* begin, const char* next_pos_of_last_char)
{ {
char buf[16] = {0}; char buf[16] = {0};
struct in_addr addr;
if( next_pos_of_last_char - begin > 15 ) { if( next_pos_of_last_char - begin > 15 ) {
traceEvent(TRACE_WARNING, "Internal Error"); traceEvent(TRACE_WARNING, "Internal Error");
return -1; return -1;
} }
memcpy(buf, begin, next_pos_of_last_char - begin); memcpy(buf, begin, next_pos_of_last_char - begin);
struct in_addr addr;
if(1 == inet_aton(buf, &addr) ) if(1 == inet_aton(buf, &addr) )
return addr.s_addr; return addr.s_addr;
else else
@ -411,6 +427,7 @@ in_addr_t get_int32_addr_from_ip_string(const char* begin, const char* next_pos_
int get_int32_from_number_string(const char* begin, const char* next_pos_of_last_char) int get_int32_from_number_string(const char* begin, const char* next_pos_of_last_char)
{ {
char buf[6] = {0}; char buf[6] = {0};
if( next_pos_of_last_char - begin > 5 ) // max is 65535, 5 char if( next_pos_of_last_char - begin > 5 ) // max is 65535, 5 char
{ {
traceEvent(TRACE_WARNING, "Internal Error"); traceEvent(TRACE_WARNING, "Internal Error");
@ -423,6 +440,7 @@ int get_int32_from_number_string(const char* begin, const char* next_pos_of_last
void process_traffic_filter_proto(const char* begin, const char* next_pos_of_last_char, filter_rule_t *rule_struct) void process_traffic_filter_proto(const char* begin, const char* next_pos_of_last_char, filter_rule_t *rule_struct)
{ {
char buf[6] = {0}; char buf[6] = {0};
if( next_pos_of_last_char - begin > 5 ) // max length str is "ICMP+", 5 char if( next_pos_of_last_char - begin > 5 ) // max length str is "ICMP+", 5 char
{ {
traceEvent(TRACE_WARNING, "Internal Error"); traceEvent(TRACE_WARNING, "Internal Error");
@ -503,6 +521,7 @@ uint8_t process_traffic_filter_rule_str(const char *rule_str, filter_rule_t *rul
} }
break; break;
} }
case FPS_SRC_NET_BIT_LEN: case FPS_SRC_NET_BIT_LEN:
{ {
if( *cur_pos >= '0' && *cur_pos <= '9') if( *cur_pos >= '0' && *cur_pos <= '9')
@ -528,6 +547,7 @@ uint8_t process_traffic_filter_rule_str(const char *rule_str, filter_rule_t *rul
} }
break; break;
} }
case FPS_SRC_PORT_SINGLE: case FPS_SRC_PORT_SINGLE:
{ {
if( *cur_pos >= '0' && *cur_pos <= '9') if( *cur_pos >= '0' && *cur_pos <= '9')
@ -544,6 +564,7 @@ uint8_t process_traffic_filter_rule_str(const char *rule_str, filter_rule_t *rul
} }
break; break;
} }
case FPS_SRC_PORT_RANGE: case FPS_SRC_PORT_RANGE:
{ {
if(*cur_pos == '[') if(*cur_pos == '[')
@ -741,3 +762,5 @@ uint8_t process_traffic_filter_rule_str(const char *rule_str, filter_rule_t *rul
return 1; return 1;
} }
#endif

Loading…
Cancel
Save