Traffic Restrictions, Pass Build on CircleCI and local Windows 10 VS2019 (#499)

* Add new file 'network_traffic_filter.c/.h"

* Add feature to drop or accept specific packet transmit over edge network interface by rules.

* fix CMakeLists.txt typo

* Update Rule String Format

* replace -F (filter) with -R (rule) for traffic restrictions.

* Update edge help (-h)  message. Update documents.

* Pass Build on CircleCI and local Windows 10 VS2019

* Fix cmake build failed because of sn_selection

* fix operate void* cause vs2016 build failed

* Fix typo to pass build on windows.

* add inttypes.h for n2n_typedefs.h to pass windows build

* modify headers to pass build on windows.
This commit is contained in:
joshuafc 2020-11-17 04:27:42 +08:00 committed by GitHub
parent 22756f40f9
commit b3f564e58c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 343 additions and 276 deletions

45
.ci/build-project.ps1 Normal file
View File

@ -0,0 +1,45 @@
# Build project.
#
# The script assumes that it will be called from inside the project directory.
#
# Usage: .ci\build-project.ps1 [vcpkg-directory [build-directory-name]]
# - vcpkg-directory: Optional full path to Vcpkg directory. Default: $HOME\vcpkg
# - build-directory-name: Optional name of build directory. Default: build.
# Can only be set of vcpkg-directory is set as well.
#
# Example 1: .ci\build-project.ps1
# Example 2: .ci\build-project.ps1 $HOME\vcpkg-clang
# Example 3: .ci\build-project.ps1 $HOME\vcpkg-clang build-clang
$ErrorActionPreference="Stop"
$VCPKG_DIR=$args[0]
$BUILD_DIR=$args[1]
if ($null -eq $VCPKG_DIR) { $VCPKG_DIR="$HOME\vcpkg" }
if ($null -eq $BUILD_DIR) { $BUILD_DIR="build" }
# only pass toolchain file to CMake if Vcpkg is installed
if (Test-Path "$VCPKG_DIR" -PathType Container) {
$TOOLCHAIN="$VCPKG_DIR\scripts\buildsystems\vcpkg.cmake"
} else {
$TOOLCHAIN="False"
}
Write-Host "---- build-project.ps1 ----"
Write-Host "VCPKG_DIR: $VCPKG_DIR"
Write-Host "BUILD_DIR: $BUILD_DIR"
Write-Host "CMAKE_TOOLCHAIN_FILE: $TOOLCHAIN"
Write-Host "---------------------------"
if (-not (Get-Command cmake -ErrorAction SilentlyContinue)) {
New-Alias -Name cmake -Value "$Env:ProgramFiles\CMake\bin\cmake.exe"
}
New-Item -Name $BUILD_DIR -ItemType Directory
Push-Location $BUILD_DIR
$ErrorActionPreference = "Stop";
cmake -DCMAKE_BUILD_TYPE=Release -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" ..
cmake --build . --config Release
if ($LASTEXITCODE) { Throw "BUILD FAILED!" }
Pop-Location

38
.ci/install-vcpkg.ps1 Normal file
View File

@ -0,0 +1,38 @@
# Build Vcpkg and install dependency packages.
#
# Usage: .ci\install-vcpkg.ps1 <project directory> [vcpkg directory name]
# - project directory: Path to the project sources where the .vcpkg file is located.
# - vcpkg directory name: optional name of directory where Vcpkg will be clone'd into
#
# Example 1: .ci\install-vcpkg.ps1 $Env:GITHUB_WORKSPACE
# Example 2: .ci\install-vcpkg.ps1 $Env:APPVEYOR_BUILD_FOLDER vcpkg-msvc
$ErrorActionPreference="Stop"
if ($args.Count -lt 1) { Exit 1 }
$PROJECT_DIR=$args[0]
$VCPKG_DIR=$args[1]
if ($null -eq $VCPKG_DIR) { $VCPKG_DIR="vcpkg" }
# do nothing if .vcpkg file doesn't exist
if (-not (Test-Path "$PROJECT_DIR\.vcpkg" -PathType Leaf)) { Write-Host ".vcpkg file does not exist, skipping Vcpkg installation."; Exit 0 }
Write-Host "---- install-vcpkg.ps1 ----"
Write-Host "PROJECT_DIR: $PROJECT_DIR"
Write-Host "VCPKG_DIR: $VCPKG_DIR"
Write-Host "---------------------------"
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
New-Alias -Name git -Value "$Env:ProgramFiles\Git\bin\git.exe"
}
Push-Location "$HOME"
git clone --quiet --depth 1 https://github.com/Microsoft/vcpkg.git $VCPKG_DIR
Set-Location $VCPKG_DIR
.\bootstrap-vcpkg.bat -disableMetrics
$packages = Get-Content "$PROJECT_DIR\.vcpkg"
.\vcpkg.exe install --triplet x64-windows $packages
Pop-Location

39
.circleci/config.yml Normal file
View File

@ -0,0 +1,39 @@
version: 2.1
orbs:
win: circleci/windows@2.4.0
jobs:
linux-gcc:
machine:
image: ubuntu-1604:201903-01
steps:
- checkout
- run:
name: Install Software
command: |
sudo apt-get update
sudo apt-get install -y cmake build-essential
mkdir build
cd build
cmake ..
make
windows-msvc:
executor: win/default
steps:
- checkout
- run:
name: Download CMake
command: |
$ProgressPreference = "SilentlyContinue"
Invoke-WebRequest -URI https://github.com/Kitware/CMake/releases/download/v3.16.4/cmake-3.16.4-win64-x64.zip -OutFile $Env:HOMEPATH\cmake-3.16.4-win64-x64.zip
Expand-Archive $Env:HOMEPATH\cmake-3.16.4-win64-x64.zip -DestinationPath "$Env:ProgramFiles"
Rename-Item "$Env:ProgramFiles\cmake-3.16.4-win64-x64" -NewName CMake
- run: .ci\install-vcpkg.ps1 "$Env:CIRCLE_WORKING_DIRECTORY"
- run: .ci\build-project.ps1
workflows:
version: 2
run-all:
jobs:
- linux-gcc
- windows-msvc

View File

@ -115,7 +115,8 @@ add_library(n2n STATIC
src/tuntap_linux.c src/tuntap_linux.c
src/tuntap_osx.c src/tuntap_osx.c
src/n2n_regex.c src/n2n_regex.c
src/network_traffic_filter.c) src/network_traffic_filter.c
src/sn_selection.c)
if(N2N_OPTION_AES) if(N2N_OPTION_AES)

View File

@ -98,59 +98,6 @@
#include <syslog.h> #include <syslog.h>
#include <sys/wait.h> #include <sys/wait.h>
#define ETH_ADDR_LEN 6
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <machine/endian.h>
#endif
#ifdef __OpenBSD__
#include <endian.h>
#define __BYTE_ORDER BYTE_ORDER
#if BYTE_ORDER == LITTLE_ENDIAN
#ifndef __LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__
#endif /* __LITTLE_ENDIAN__ */
#else
#define __BIG_ENDIAN__
#endif/* BYTE_ORDER */
#endif/* __OPENBSD__ */
#if __BYTE_ORDER == __LITTLE_ENDIAN
#ifndef __LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__
#endif
#else
#ifndef __BIG_ENDIAN__
#define __BIG_ENDIAN__
#endif
#endif
#ifdef WIN32
#ifndef __LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__ 1
#endif
#endif
#if !(defined(__LITTLE_ENDIAN__) || defined(__BIG_ENDIAN__))
#if defined(__mips__)
#undef __LITTLE_ENDIAN__
#undef __LITTLE_ENDIAN
#define __BIG_ENDIAN__
#endif
/* Everything else */
#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__))
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__
#else
#define __BIG_ENDIAN__
#endif
#endif
#endif
#ifdef HAVE_LIBZSTD #ifdef HAVE_LIBZSTD
#include <zstd.h> #include <zstd.h>
#endif #endif
@ -199,22 +146,7 @@
#include "speck.h" #include "speck.h"
#include "n2n_regex.h" #include "n2n_regex.h"
#include "sn_selection.h" #include "sn_selection.h"
#include "network_traffic_filter.h"
//rule_str format: src_ip/len:[b_port,e_port],dst_ip/len:[s_port,e_port],TCP+/-,UDP+/-,ICMP+/-
//
//ip/len indicate a cidr block, len can be ignore, means single ip (not cidr block) will be use in filter rule.
//
//'+','-' after proto type indicate allow or disallow that proto transmit packet. if any of above three proto missed, it will be disallow.
//
//[s_port,e_port] can be instead by single port number, if not specify, 0-65535 ports will be used. ports range include start_port and end_port.
//
//examples:
//192.168.1.5/32:[0,65535],192.168.0.0/24:[8081,65535],TCP-,UDP-,ICMP+
//192.168.1.5:[0,65535],192.168.0.0/24:8000,ICMP+
//192.168.1.5,192.168.0.7 // packets by all proto of all ports from 192.158.1.5 to any ports of 192.168.0.7 will be disallow(dropped).
//
// for impl, see: network_traffic_filter.c
uint8_t process_traffic_filter_rule_str(const char* rule_str, filter_rule_t* rule_struct);
/* ************************************** */ /* ************************************** */

View File

@ -19,61 +19,7 @@
#ifndef _N2N_TYPEDEFS_H_ #ifndef _N2N_TYPEDEFS_H_
#define _N2N_TYPEDEFS_H_ #define _N2N_TYPEDEFS_H_
struct ether_hdr
{
uint8_t dhost[ETH_ADDR_LEN];
uint8_t shost[ETH_ADDR_LEN];
uint16_t type; /* higher layer protocol encapsulated */
} __attribute__ ((__packed__));
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__));
typedef uint8_t n2n_community_t[N2N_COMMUNITY_SIZE]; typedef uint8_t n2n_community_t[N2N_COMMUNITY_SIZE];
typedef uint8_t n2n_mac_t[N2N_MAC_SIZE]; typedef uint8_t n2n_mac_t[N2N_MAC_SIZE];
@ -81,6 +27,186 @@ typedef uint8_t n2n_cookie_t[N2N_COOKIE_SIZE];
typedef uint8_t n2n_desc_t[N2N_DESC_SIZE]; typedef uint8_t n2n_desc_t[N2N_DESC_SIZE];
typedef char n2n_sock_str_t[N2N_SOCKBUF_SIZE]; /* tracing string buffer */ typedef char n2n_sock_str_t[N2N_SOCKBUF_SIZE]; /* tracing string buffer */
#ifdef _MSC_VER
#include "getopt.h"
/* Other Win environments are expected to support stdint.h */
/* stdint.h typedefs (C99) (not present in Visual Studio) */
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
/* sys/types.h typedefs (not present in Visual Studio) */
typedef unsigned int u_int32_t;
typedef unsigned short u_int16_t;
typedef unsigned char u_int8_t;
typedef int ssize_t;
typedef unsigned long in_addr_t;
#include "n2n_win32.h"
#endif /* #ifdef _MSC_VER */
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <machine/endian.h>
#endif
#ifdef __OpenBSD__
#include <endian.h>
#define __BYTE_ORDER BYTE_ORDER
#if BYTE_ORDER == LITTLE_ENDIAN
#ifndef __LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__
#endif /* __LITTLE_ENDIAN__ */
#else
#define __BIG_ENDIAN__
#endif/* BYTE_ORDER */
#endif/* __OPENBSD__ */
#if __BYTE_ORDER == __LITTLE_ENDIAN
#ifndef __LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__
#endif
#else
#ifndef __BIG_ENDIAN__
#define __BIG_ENDIAN__
#endif
#endif
#ifdef WIN32
#ifndef __LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__ 1
#endif
#endif
#if !(defined(__LITTLE_ENDIAN__) || defined(__BIG_ENDIAN__))
#if defined(__mips__)
#undef __LITTLE_ENDIAN__
#undef __LITTLE_ENDIAN
#define __BIG_ENDIAN__
#endif
/* Everything else */
#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__))
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define __LITTLE_ENDIAN__
#else
#define __BIG_ENDIAN__
#endif
#endif
#endif
/* *************************************** */
#ifdef __GNUC__
#define PACK_STRUCT __attribute__((__packed__))
#else
#define PACK_STRUCT
#endif
#ifdef _MSC_VER
#pragma pack(push,1)
#endif
#define ETH_ADDR_LEN 6
struct ether_hdr
{
uint8_t dhost[ETH_ADDR_LEN];
uint8_t shost[ETH_ADDR_LEN];
uint16_t type; /* higher layer protocol encapsulated */
} PACK_STRUCT;
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;
} PACK_STRUCT;
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;
} PACK_STRUCT;
struct n2n_udphdr
{
u_int16_t source;
u_int16_t dest;
u_int16_t len;
u_int16_t check;
} PACK_STRUCT;
#ifdef _MSC_VER
#pragma pack(pop)
#endif
typedef struct port_range{
uint16_t start_port; // range contain 'start_port' self
uint16_t end_port; // range contain 'end_port' self
} port_range_t;
typedef struct filter_rule_key
{
in_addr_t src_net_cidr;
uint8_t src_net_bit_len;
port_range_t src_port_range;
in_addr_t dst_net_cidr;
uint8_t dst_net_bit_len;
port_range_t dst_port_range;
uint8_t bool_tcp_configured;
uint8_t bool_udp_configured;
uint8_t bool_icmp_configured;
} filter_rule_key_t;
typedef struct filter_rule
{
filter_rule_key_t key;
uint8_t bool_accept_icmp;
uint8_t bool_accept_udp;
uint8_t bool_accept_tcp;
UT_hash_handle hh; /* makes this structure hashable */
} filter_rule_t;
#ifndef WIN32 #ifndef WIN32
typedef struct tuntap_dev { typedef struct tuntap_dev {
int fd; int fd;
@ -306,6 +432,17 @@ typedef enum {
/* *************************************************** */ /* *************************************************** */
typedef struct network_traffic_filter
{
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);
} network_traffic_filter_t;
/* *************************************************** */
/* Callbacks allow external programs to attach functions in response to /* Callbacks allow external programs to attach functions in response to
* N2N events. */ * N2N events. */
typedef struct n2n_edge_callbacks { typedef struct n2n_edge_callbacks {
@ -329,60 +466,6 @@ typedef struct n2n_edge_callbacks {
void (*main_loop_period)(n2n_edge_t *eee, time_t now); void (*main_loop_period)(n2n_edge_t *eee, time_t now);
} n2n_edge_callbacks_t; } n2n_edge_callbacks_t;
/* ***************************************************** */
// network traffic filter
typedef struct port_range{
uint16_t start_port; // range contain 'start_port' self
uint16_t end_port; // range contain 'end_port' self
} port_range_t;
typedef struct filter_rule_key
{
in_addr_t src_net_cidr;
uint8_t src_net_bit_len;
port_range_t src_port_range;
in_addr_t dst_net_cidr;
uint8_t dst_net_bit_len;
port_range_t dst_port_range;
uint8_t bool_tcp_configured;
uint8_t bool_udp_configured;
uint8_t bool_icmp_configured;
} filter_rule_key_t;
typedef struct filter_rule
{
filter_rule_key_t key;
uint8_t bool_accept_icmp;
uint8_t bool_accept_udp;
uint8_t bool_accept_tcp;
UT_hash_handle hh; /* makes this structure hashable */
} filter_rule_t;
#ifdef FILTER_TRAFFIC
/*
* network traffic filter interface
*/
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);
/* A packet has been received from the TAP interface. 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_tap)(struct network_traffic_filter* filter, n2n_edge_t *eee, uint8_t *payload, uint16_t payload_size);
} network_traffic_filter_t;
#endif
/* *************************************************** */
typedef struct n2n_tuntap_priv_config { typedef struct n2n_tuntap_priv_config {
char tuntap_dev_name[N2N_IFNAMSIZ]; char tuntap_dev_name[N2N_IFNAMSIZ];
char ip_mode[N2N_IF_MODE_SIZE]; char ip_mode[N2N_IF_MODE_SIZE];
@ -463,9 +546,7 @@ 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;
@ -520,12 +601,9 @@ struct n2n_edge {
n2n_tuntap_priv_config_t tuntap_priv_conf; /**< Tuntap config */ n2n_tuntap_priv_config_t tuntap_priv_conf; /**< Tuntap config */
#ifdef FILTER_TRAFFIC
network_traffic_filter_t *network_traffic_filter; network_traffic_filter_t *network_traffic_filter;
#endif
}; };
typedef struct sn_stats typedef struct sn_stats
{ {
size_t errors; /* Number of errors encountered. */ size_t errors; /* Number of errors encountered. */

View File

@ -23,24 +23,15 @@
#ifndef N2N_NETWORK_TRAFFIC_FILTER_H #ifndef N2N_NETWORK_TRAFFIC_FILTER_H
#define N2N_NETWORK_TRAFFIC_FILTER_H #define N2N_NETWORK_TRAFFIC_FILTER_H
#include "n2n.h" #include "n2n_typedefs.h"
#ifdef FILTER_TRAFFIC
/*
* add feature to drop or accept specific packet transmit over edge network interface by rules.
*
* below structs and function used 'n2n_verdict' and other structs, so defined in 'n2n.h', to avoid header files circular dependency.
* port_range_t, filter_rule_key_t, filter_rule_t, network_traffic_filter_t
* uint8_t process_traffic_filter_rule_str(const char* rule_str, filter_rule_t* rule_struct);
*/
network_traffic_filter_t* create_network_traffic_filter(); 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);
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);
#endif
//rule_str format: src_ip/len:[b_port,e_port],dst_ip/len:[s_port,e_port],TCP+/-,UDP+/-,ICMP+/-
uint8_t process_traffic_filter_rule_str(const char* rule_str, filter_rule_t* rule_struct);
#endif //N2N_NETWORK_TRAFFIC_FILTER_H #endif //N2N_NETWORK_TRAFFIC_FILTER_H

View File

@ -145,9 +145,7 @@ static void help() {
"[-D] " "[-D] "
#endif #endif
"[-r] [-E] [-v] [-i <reg_interval>] [-L <reg_ttl>] [-t <mgmt port>] [-A[<cipher>]] [-H] [-z[<compression algo>]] " "[-r] [-E] [-v] [-i <reg_interval>] [-L <reg_ttl>] [-t <mgmt port>] [-A[<cipher>]] [-H] [-z[<compression algo>]] "
#ifdef FILTER_TRAFFIC
"[-R <rule_str>] " "[-R <rule_str>] "
#endif
"[-h]\n\n"); "[-h]\n\n");
#if defined(N2N_CAN_NAME_IFACE) #if defined(N2N_CAN_NAME_IFACE)
@ -523,7 +521,6 @@ 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));
@ -538,8 +535,6 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
} }
break; break;
} }
#endif
default: default:
{ {
traceEvent(TRACE_WARNING, "Unknown option -%c: Ignored", (char)optkey); traceEvent(TRACE_WARNING, "Unknown option -%c: Ignored", (char)optkey);

View File

@ -16,8 +16,8 @@
* *
*/ */
#include "network_traffic_filter.h"
#include "n2n.h" #include "n2n.h"
#include "network_traffic_filter.h"
#include "edge_utils_win32.h" #include "edge_utils_win32.h"
/* heap allocation for compression as per lzo example doc */ /* heap allocation for compression as per lzo example doc */
@ -272,11 +272,9 @@ 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;
return(eee); return(eee);
@ -1172,14 +1170,12 @@ static int handle_PACKET(n2n_edge_t * eee,
} }
} }
#ifdef FILTER_TRAFFIC
if(eee->network_traffic_filter->filter_packet_from_peer( eee->network_traffic_filter, eee, orig_sender, 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); traceEvent(TRACE_DEBUG, "Filtered packet %u", (unsigned int)eth_size);
return(0); return(0);
} }
#endif
if(eee->cb.packet_from_peer) { if(eee->cb.packet_from_peer) {
uint16_t tmp_eth_size = eth_size; uint16_t tmp_eth_size = eth_size;
if(eee->cb.packet_from_peer(eee, orig_sender, eth_payload, &tmp_eth_size) == N2N_DROP) { if(eee->cb.packet_from_peer(eee, orig_sender, eth_payload, &tmp_eth_size) == N2N_DROP) {
@ -1755,7 +1751,6 @@ void edge_read_from_tap(n2n_edge_t * eee) {
} }
else else
{ {
#ifdef FILTER_TRAFFIC
if(eee->network_traffic_filter) { 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){
@ -1763,8 +1758,7 @@ void edge_read_from_tap(n2n_edge_t * eee) {
return; return;
} }
} }
#endif
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) {
@ -2335,10 +2329,8 @@ 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();
free(eee); free(eee);
@ -2838,7 +2830,6 @@ 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;
@ -2848,7 +2839,6 @@ void edge_term_conf(n2n_edge_conf_t *conf) {
free(el); free(el);
} }
} }
#endif
} }
/* ************************************** */ /* ************************************** */

View File

@ -16,13 +16,10 @@
* *
*/ */
#ifdef FILTER_TRAFFIC #include "n2n.h"
#include "network_traffic_filter.h" #include "network_traffic_filter.h"
#include "uthash.h" #include "uthash.h"
#include "netinet/tcp.h"
#include <inttypes.h>
// cache that hit less than 10 while 10000 package processed will be delete; // cache that hit less than 10 while 10000 package processed will be delete;
#define CLEAR_CACHE_EVERY_X_COUNT 10000 #define CLEAR_CACHE_EVERY_X_COUNT 10000
#define CLAER_CACHE_ACTIVE_COUNT 10 #define CLAER_CACHE_ACTIVE_COUNT 10
@ -92,14 +89,16 @@ 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) {
ether_hdr_t *hdr_ether = (ether_hdr_t*)buffer; ether_hdr_t *hdr_ether = (ether_hdr_t*)buffer;
uint16_t ether_type = ntohs(hdr_ether->type); uint16_t ether_type = ntohs(hdr_ether->type);
struct n2n_iphdr *hdr_ip = NULL;
struct n2n_tcphdr *hdr_tcp = NULL;
struct n2n_udphdr *udp_hdr = NULL;
memset(out_info, 0, sizeof(packet_address_proto_info_t)); memset(out_info, 0, sizeof(packet_address_proto_info_t));
switch (ether_type) { switch (ether_type) {
case 0x0800: case 0x0800:
{ {
buffer += sizeof(ether_hdr_t); size -= sizeof(ether_hdr_t); if(size <= 0) return; buffer += sizeof(ether_hdr_t); size -= sizeof(ether_hdr_t); if(size <= 0) return;
struct n2n_iphdr *hdr_ip = (struct n2n_iphdr*)buffer; hdr_ip = (struct n2n_iphdr*)buffer;
switch (hdr_ip->version) switch (hdr_ip->version)
{ {
@ -118,7 +117,7 @@ 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 n2n_tcphdr *hdr_tcp = (struct n2n_tcphdr*)buffer; hdr_tcp = (struct n2n_tcphdr*)buffer;
out_info->src_port = ntohs(hdr_tcp->source); out_info->src_port = ntohs(hdr_tcp->source);
out_info->dst_port = ntohs(hdr_tcp->dest); out_info->dst_port = ntohs(hdr_tcp->dest);
break; break;
@ -127,7 +126,7 @@ void collect_packet_info(packet_address_proto_info_t* out_info, unsigned char *b
{ {
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 n2n_udphdr *udp_hdr = (struct n2n_udphdr*)buffer; udp_hdr = (struct n2n_udphdr*)buffer;
out_info->src_port = ntohs(udp_hdr->source); out_info->src_port = ntohs(udp_hdr->source);
out_info->dst_port = ntohs(udp_hdr->dest); out_info->dst_port = ntohs(udp_hdr->dest);
break; break;
@ -377,17 +376,17 @@ 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; filter_rule_pair_cache_t* el1 = 0, * tmp1 = 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);
} }
HASH_ITER(hh, _filter->connections_rule_cache, el, tmp) HASH_ITER(hh, _filter->connections_rule_cache, el1, tmp1)
{ {
HASH_DEL(_filter->connections_rule_cache, el); HASH_DEL(_filter->connections_rule_cache, el1);
free(el); free(el);
} }
@ -409,19 +408,12 @@ 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); return inet_addr(buf);
if(1 == inet_aton(buf, &addr) )
return addr.s_addr;
else
return -1;
} }
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)
@ -521,7 +513,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')
@ -547,7 +539,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')
@ -564,7 +556,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 == '[')
@ -762,5 +754,3 @@ uint8_t process_traffic_filter_rule_str(const char *rule_str, filter_rule_t *rul
return 1; return 1;
} }
#endif

View File

@ -28,26 +28,6 @@
#include "wintap.h" #include "wintap.h"
#ifdef _MSC_VER
#include "getopt.h"
/* Other Win environments are expected to support stdint.h */
/* stdint.h typedefs (C99) (not present in Visual Studio) */
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
/* sys/types.h typedefs (not present in Visual Studio) */
typedef unsigned int u_int32_t;
typedef unsigned short u_int16_t;
typedef unsigned char u_int8_t;
typedef int ssize_t;
#endif /* #ifdef _MSC_VER */
typedef unsigned long in_addr_t;
#undef EAFNOSUPPORT #undef EAFNOSUPPORT
#define EAFNOSUPPORT WSAEAFNOSUPPORT #define EAFNOSUPPORT WSAEAFNOSUPPORT
#define MAX(a,b) (a > b ? a : b) #define MAX(a,b) (a > b ? a : b)
@ -58,18 +38,6 @@ typedef unsigned long in_addr_t;
#define socklen_t int #define socklen_t int
#define ETH_ADDR_LEN 6
/*
* Structure of a 10Mb/s Ethernet header.
*/
struct ether_hdr
{
uint8_t dhost[ETH_ADDR_LEN];
uint8_t shost[ETH_ADDR_LEN];
uint16_t type; /* higher layer protocol encapsulated */
};
typedef struct ether_hdr ether_hdr_t;
/* ************************************* */ /* ************************************* */