|
@ -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 |
|
|