Skip to content

Commit

Permalink
SIGUSR1 support and some code improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
root committed Oct 20, 2021
1 parent 5b8e0fb commit acbd12a
Show file tree
Hide file tree
Showing 11 changed files with 295 additions and 212 deletions.
51 changes: 39 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# tuninetd

Simple yet powerful event emitter by **tun/tap** (with/without **pcap** filter) or **nflog** source. Could be used as: VPN dispatcher, simplified detection system, by demand services handler, etc...
Simple yet powerful event emitter by **tun/tap** (with/without **pcap** filter) or **nflog** source.

### 1. How it works.
#### tun/tap device: ####
Could be used as: VPN dispatcher, simplified detection system, by demand service handler, tricky lock etc...

### 1. How it works:
#### 1.1. tun/tap + pcap mode:
You should create and configure tun/tap device first, then run **tuninetd**. It starts listening on this interface, until network traffic will be detected. After that, interface immediately releasing and specified command (with -c) will execute. From now on, daemon in monitoring state.

---
Expand All @@ -24,7 +26,7 @@ Since **tuninetd** based on **libpcap**, you can specify capture filter. To test

>**! Notice !** *Modern Linux distributions periodically send 'icmpv6 router solicitation' packets, which cause tuninetd keep or change state. This situation appears in tun/tap mode without pcap filter applied.*
#### NFLOG: ####
#### 1.2. nflog mode:

In general, behavior the same as tun/tap in part of start/stop. You could simply use netfilter nfgroup (*iptables **NFLOG** target*) to reading packets from. No binding to tun/tap device nor libpcap sensor. This is more lightweight mode and, because of that, - more reliable.

Expand All @@ -43,19 +45,28 @@ To install from sources download src folder. In case Debian/Ubuntu, you should a
Congrats! Tuninend ready to use. Check ./bin folder.

### 3. Usage:
#### 3.1. Launch:

tuninetd {-i \<ifname> | -n \<nflog-group>} -c \<path> [-m \<iftype>] [-f \<filter>] [-t \<ttl>] [-d]
```sh
# tuninetd {-i <ifname> | -n <nflog-group>} -c <path> [-m <iftype>] [-f <filter>] [-t <ttl>] [-d]
```

**-i \<ifname>**: interface to use (tun or tap). Must be up and configured.<br/>
**-n \<nflog-group>**: iptables NFLOG group number ('-i', '-m' and '-f' will be ignored).<br/>
**-c \<path>**: will be executed with 'start' and 'stop' parameter.<br/>
**-n \<nflog-group>**: iptables NFLOG group ('-i', '-m' and '-f' will be ignored).<br/>
**-c \<path>**: will execute with 'start' and 'stop' parameter.<br/>
**-m \<iftype>**: 'tun' or 'tap' mode. By default 'tun', should be set properly.<br/>
**-f \<filter>**: specify pcap filter, similar to tcpdump<br/>
**-t \<ttl>**: seconds of interface (traffic) idle, before 'stop' command (default is 600).<br/>
**-d**: demonize process<br/>
**-t \<ttl>**: seconds since last packet before 'stop' command (default is 600).<br/>
**-d**: daemonize process<br/>
**-h**: print this help

`--- If tuninetd stuck in start condition for any reason, you can reset to "standby" (i.e. stop state) with SIGHUP. ---`
---

#### 3.2. Signals:
SIGHUP (-1): switch tuninetd to standby mode (deadlock resolving)<br/>
SIGUSR1 (-10): write to syslog current state (debug information)



### 4. Examples:
Before launching as a daemon make sure there is no errors. In daemon mode tuninetd write status messages and errors to syslog.
Expand All @@ -67,13 +78,29 @@ Before launching as a daemon make sure there is no errors. In daemon mode tunine

Check ```example``` folder to find some shell scripts.

To create and bring up ```tun``` device, could be used following commands:
To create and bring up ```tun``` device could be used following commands:
```sh
# ip tuntap add dev tun0 mode tun
# ip link set tun0 up
```

For more information about routing and configuring network devices, I strongly suggest LARCT how-to.
For more information about routing and configuring network devices, I strongly suggest LARTC how-to.

<br/>

---
```sh
# killall -10 tuninetd
```
syslog:<br/>

>Oct 20 18:42:20 router1 tuninetd: SIGUSR1 caught:<br/>
>Oct 20 18:42:20 router1 tuninetd: - Capture engine: nflog group 1<br/>
>Oct 20 18:42:20 router1 tuninetd: - cmd_path = /etc/tuninetd/toggletunnel.sh<br/>
>Oct 20 18:42:20 router1 tuninetd: - TTL = 600 sec.<br/>
>Oct 20 18:42:20 router1 tuninetd: - Current status: up (ON), time since last captured packet: 2 sec.
---


### License:
MIT
Expand Down
Binary file added deb-packages/tuninetd_1.3.0_amd64.deb
Binary file not shown.
35 changes: 19 additions & 16 deletions src/Makefile
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
CFLAGS = -Wall -O2

all: tuninetd
tuninetd: main.o nflog.o pcap.o thread.o tun.o utils.o

tuninetd: main.o xnflog.o xpcap.o thread.o xtun.o utils.o
[ -d ./bin ] || mkdir -p ./bin
gcc main.o nflog.o pcap.o thread.o tun.o utils.o -o ./bin/tuninetd -lpthread -lpcap -lnetfilter_log
gcc main.o xnflog.o xpcap.o thread.o xtun.o utils.o -o ./bin/tuninetd -lpthread -lpcap -lnetfilter_log

main.o: main.c main.h
gcc -c main.c
main.o: main.c main.h common.h
gcc $(CFLAGS) -c main.c

nflog.o: nflog.c main.h
gcc -c nflog.c
xnflog.o: xnflog.c common.h
gcc $(CFLAGS) -c xnflog.c

pcap.o: pcap.c main.h
gcc -c pcap.c
xpcap.o: xpcap.c common.h
gcc $(CFLAGS) -c xpcap.c

thread.o: thread.c main.h
gcc -c thread.c
thread.o: thread.c common.h
gcc $(CFLAGS) -c thread.c

tun.o: tun.c main.h
gcc -c tun.c
xtun.o: xtun.c common.h
gcc $(CFLAGS) -c xtun.c

utils.o: utils.c main.h
gcc -c utils.c
utils.o: utils.c common.h
gcc $(CFLAGS) -c utils.c

clean:
rm -f *.o tuninetd
rm -rf ./bin
rm -f *.o
rm -rf ./bin
61 changes: 61 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#ifndef H_TUNINETD_COMMON
#define H_TUNINETD_COMMON

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_tun.h>
#include <unistd.h>
#include <time.h>

#define BUFSIZE 2000
#define ON 1
#define OFF 0

#define ERROR 0
#define WARNING 1
#define INFO 2

#define VERSION "\ntuninetd 1.3.0\n"

//global vars.
short int debug;
short int status;
unsigned long ts;
unsigned long curts;

struct globcfg_t {
short int isdaemon;
pid_t pid;
char *cmd_path;
char *cmd_path_start;
char *cmd_path_stop;
char *pcap_filter;
char *dev_name;
long nf_group;
int dev_mode;
long ttl;
} globcfg;


//from utils.c
void do_debug(const char *msg, ...);
void message(int, const char *msg, ...);

void sighup_handler(int signo);
void sigusr_handler(int signo);
void usage();
void version();

//from thread.c
void switch_guard(short action);
void thread_init();

void *tun_x(void *x_void_ptr);
void *nflog_x(void *x_void_ptr);
void *pcap_x(void *x_void_ptr);

#endif
113 changes: 62 additions & 51 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,60 @@

int main(int argc, char *argv[])
{
int opt = 0;

struct timespec tim;
curts = time(NULL);

//debug = 1;
build_config(argc, argv);
check_config_and_daemonize();
thread_init(); //Initialize our workers (thread.c)

struct timespec tim;

tim.tv_sec = 1;
tim.tv_nsec = 0;


//debug = 1;

if (signal(SIGHUP, sighup_handler) == SIG_ERR) {
message(WARNING, "Warning! Can't catch SIGHUP");
}

if (signal(SIGUSR1, sigusr_handler) == SIG_ERR) {
message(WARNING, "Warning! Can't catch SIGUSR1");
}

while (1) {

nanosleep(&tim, NULL); //Tick

curts = time(NULL);

if (ts != 0 && status == ON && ((long)(curts - ts) >= globcfg.ttl)) {
message(INFO, "CORE: executing STOP command...");
switch_guard(OFF);
}
}

free(globcfg.cmd_path_start);
free(globcfg.cmd_path_stop);

return 0;
}


void build_config(int argc, char **argv)
{
int opt = 0;
static const char *optString = "i:t:c:f:m:n:dhv";

curts = time(NULL);


globcfg.isdaemon = 0;
globcfg.pid = 0;
globcfg.cmd_path = NULL;
globcfg.ttl = 600;
globcfg.dev_mode = IFF_TUN;
globcfg.nf_group = -1;

opt = getopt( argc, argv, optString);

while( opt != -1 ) {
switch( opt ) {
case 'v':
Expand All @@ -41,12 +73,12 @@ int main(int argc, char *argv[])
globcfg.cmd_path_start = malloc(strlen(optarg) + 23);
strcpy(globcfg.cmd_path_start, optarg);
strcat(globcfg.cmd_path_start, " start > /dev/null 2>&1");

globcfg.cmd_path_stop = malloc(strlen(optarg) + 22);
strcpy(globcfg.cmd_path_stop, optarg);
strcat(globcfg.cmd_path_stop, " stop > /dev/null 2>&1");
break;

case 'f':
globcfg.pcap_filter = optarg;
break;
Expand All @@ -69,68 +101,47 @@ int main(int argc, char *argv[])
exit(1);
break;
}
opt = getopt( argc, argv, optString );

opt = getopt(argc, argv, optString);
}

}

void check_config_and_daemonize()
{
if (globcfg.dev_name == NULL && globcfg.nf_group < 0) {
my_err("tun/tap device OR nfgroup must be specified.");
message(ERROR, "tun/tap device OR nfgroup must be specified. Abort.");
usage();
exit(1);
}

if (globcfg.cmd_path == NULL) {
my_err("Executable path must be specified");
message(ERROR, "Executable path must be specified. Abort.");
usage();
exit(1);
}



if (globcfg.isdaemon == 1) {
globcfg.pid = fork();

if (globcfg.pid < 0) {
my_err("Can't fork process. Abort.");
message(ERROR, "Can't fork process. Abort.");
exit(1);
}

if (globcfg.pid > 0) {
my_info("---");
my_info("Success! tuninetd has been started with pid: %i", globcfg.pid);
message(INFO, "---");
message(INFO, "Success! Tuninetd has been started with PID: %i", globcfg.pid);
exit(0);
}

chdir("/");

setsid();

close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
} else
my_info("Started with pid %d", getpid());

thread_init(); //Initialization our workers (thread.c)

if (signal(SIGHUP, sig_handler) == SIG_ERR)
my_info("Can't catch SIGHUP\n");


while (1) {

nanosleep(&tim, NULL); //Tick

curts = time(NULL);
//do_debug("Tick %lu ...\n", curts);//

if (ts != 0 && status == 1 && ((curts - ts) >= globcfg.ttl) ) {
my_info("CORE: executing STOP command...");
switch_guard(OFF);
}
} else {
message(INFO, "Started with pid %d", getpid());
}

free(globcfg.cmd_path_start);
free(globcfg.cmd_path_stop);

return 0;
}
Loading

0 comments on commit acbd12a

Please sign in to comment.