jumper - bring up network links on demand


jumper [-Edf] [-P FILE] [-l PRIO] [-D SYMBOL[=VALUE]] [-I DIR]
[--debug] [--foreground] [--define=SYMBOL[=VALUE]]
[--no-preprocessor] [--preprocessor=COMMAND]
[--pidfile=FILE] [CONFIG]
[-HhV] [--help] [--version] [--config-help]


Jumper monitors network interfaces for certain kinds of traffic and starts preconfigured external programs when such traffic is detected. It is designed mainly to bring up network links (such as VPN and the like) on demand.

The configuration file tells the program on which interfaces to listen, what packets to catch and what program to start when such packets are detected. The default location for the configuration file is /etc/jumper.conf. If the CONFIG argument is supplied, it names the configuration file to be read instead of the default one.

See the section CONFIGURATION, for a detailed description of configuration file syntax.

Unless instructed otherwise, jumper uses m4(1) to preprocess its configuration file. See the section PREPROCESSOR for a detailed discussion.

After successful parsing of the configuration file, the program switches the configured interfaces to promiscuous mode, detaches itself from the controlling terminal and begins listening on the interfaces.

When a packet arrives that matches the specified conditions, jumper checks whether the program configured for this kind of packets is already running. If it is not, it will be started. Thus, for example, the following configuration fragment instructs the program to start openvpn whenever a packet coming to any IP address from the network is detected:

listen myvpn {
interface eth1;
command "/usr/bin/openvpn /etc/openvpn.conf";


-D, --define=SYMBOL[=VALUE]

Define preprocessor symbol.


Preprocess configuration file and exit.

-I, --include-directory=DIR

Add DIR to the list of preprocessor include directories.

-P FILE, --pidfile=FILE

Set PID file name.

-d, --debug

Increase debugging level. See the description of debug statement in CONFIGURATION STATEMENTS, for a detailed discussion of debugging levels and their effect on the program output.

-f, --foreground

Remain in foreground.


When running in the foreground (see the -f option above), log messages with priority PRIO and higher to the stderr, as well as to the syslog. PRIO is one of the usual syslog.conf(8) priorities: debug, info, notice, warning, err, crit, alert, emerg, or none, which suppresses any output to standard error.

By default, all priorities are logged.


Disable preprocessing of the configuration file. Read it verbatim.


Use COMMAND instead of the default preprocessor.

Informational options:
, --help

Give a concise help summary.

-H, --config-help

Show configuration file summary and exit.


Print a short usage message.

-V, --version

Print program version.


The configuration file consists of statements and comments.

There are three classes of lexical tokens: keywords, values, and separators. Blanks, tabs, newlines and comments, collectively called white space are ignored except as they serve to separate tokens. Some white space is required to separate otherwise adjacent keywords and values.

Comments may appear anywhere where white space may appear in the configuration file. There are two kinds of comments: single-line and multi-line comments. Single-line comments start with # or // and continue to the end of the line:

# This is a comment
// This too is a comment

Multi-line or C-style comments start with the two characters /* (slash, star) and continue until the first occurrence of */ (star, slash).

Multi-line comments cannot be nested. However, single-line comments may well appear within multi-line ones.

Pragmatic Comments
Pragmatic comments are similar to the usual single-line comments, except that they cause some changes in the way the configuration is parsed. Pragmatic comments begin with a # sign and end with the next physical newline character.
#include <

Include the contents of the file file. Both forms are equivalent. The FILE must be an absolute file name.

#include_once <FILE>

Same as #include, except that, if the FILE has already been included, it will not be included again.

#line num
num "FILE"

This line causes the parser to believe, for purposes of error diagnostics, that the line number of the next source line is given by num and the current input file is named by FILE. If the latter is absent, the remembered file name does not change.

# num "FILE"

This is a special form of the #line statement, understood for compatibility with the C preprocessor.

Simple statement
A simple statement consists of a keyword and value separated by any amount of whitespace. Simple statement is terminated with a semicolon (;).

The following is a simple statement:

pidfile /var/run/jumper.pid;

A value can be one of the following:


A number is a sequence of decimal digits.


One of: yes, true, t or 1, meaning true, and no, false, nil, 0 meaning false.

unquoted string

Any sequence of letters, digits, and any of the following characters: _, -, ., /, @, *, : is treated as a string.

quoted string

Any sequence of characters enclosed in double-quotes ("). A backslash appearing within a quoted string introduces an escape sequence, which is replaced with a single character according to the following rules:

Sequence Expansion ASCII








audible bell









new line



charriage return



horizontal tabulation



vertical tabulation


In addition, the sequence \newline is removed from the string. This allows to split long strings over several physical lines, e.g.:

"a long string may be\
split over several lines"

If the character following a backslash is not one of those specified above, the backslash is ignored and a warning is issued.

Two or more adjacent quoted strings are concatenated, which gives another way to split long strings over several lines to improve readability. The following fragment produces the same result as the example above:

"a long string may be"
" split over several lines"


A here-document is a special construct that allows to introduce strings of text containing embedded newlines.

The <<word construct instructs the parser to read all the following lines up to the line containing only word, with possible trailing blanks. Any lines thus read are concatenated together into a single string. For example:

A multiline

The body of a here-document is interpreted the same way as a double-quoted string, unless word is preceded by a backslash (e.g. <<\EOT) or enclosed in double-quotes, in which case the text is read as is, without interpretation of escape sequences.

If word is prefixed with - (a dash), then all leading tab characters are stripped from input lines and the line containing word. Furthermore, - is followed by a single space, all leading whitespace is stripped from them. This allows to indent here-documents in a natural fashion. For example:

<<- TEXT
The leading whitespace will be
ignored when reading these lines.

It is important that the terminating delimiter be the only token on its line. The only exception to this rule is allowed if a here-document appears as the last element of a statement. In this case a semicolon can be placed on the same line with its terminating delimiter, as in:

help-text <<-EOT
A sample help text.


A comma-separated list of values, enclosed in parentheses. The following example shows a statement whose value is a list of strings:

option (wait, stderr);

In any context where a list is appropriate, a single value is allowed without being a member of a list: it is equivalent to a list with a single member. This means that, e.g.

option stderr;

is equivalent to

option (stderr);

Block Statement
A block statement introduces a logical group of statements. It consists of a keyword, optionally followed by a value, called a tag, and a sequence of statements enclosed in curly braces, as shown in the example below:

listen vpn {
interface eth0;
command "openvpn";

The closing curly brace may be followed by a semicolon, although this is not required.

Arguments to certain statements undergo macro expansion before further use. During the macro expansion any occurrence of ${NAME} is replaced with the value of macro NAME. Macro names follow the usual convention: they begin with a letter and contain letters, digits and underscores. Curly braces around the NAME are optional. They are required only if the macro reference is followed by a character that is not to be interpreted as part of its name, as in ${command}string.

The sets of macro names available for expansion differs depending on the configuration context and are discussed in detail below.


If BOOL is true, do not detach from the controlling terminal.

pidfile FILE;

After successful startup, write the PID of the running process to FILE. The file will be removed before normal termination. The default FILE is /usr/var/run/jumper.pid.

debug NUMBER;

Set debugging level. Implemented levels are:


No debugging info.


Additional information regarding process management.


Log information about I/O redirection processes.


Log captured IP packets.

shutdown-timeout NUMBER;

When jumper is terminated, it shuts down all subprocesses launched so far. This statement sets the time to wait for them to exit properly. If any processes are left after NUMBER of seconds, jumper will terminate them forcefully, delivering them the SIGKILL signal. The default timeout is 15 seconds.

listen NAME { ... }

Define a listener. The NAME is a unique string identifying this listener in the configuration. The following instructions are available for use in the { ... } block:

interface IFACE;

Listen on the specified interface. This statement is mandatory.

match-source CIDR-LIST;

Match only packets coming from one of the listed networks.

match-destination CIDR-LIST;

Match only packets going to one of the listed networks. This statement must be present.

If both match-source and match-destination are supplied, their conditions are joined by logical AND.


Run COMMAND-LINE if the conditions are satisfied. The argument is parsed using the same algorithm as used by the shell. It is subject to macro expansion. The following macro names are defined:

The program name (jumper).


Name of the configuration file where the command statement is located.


Line number in that file.


Source IP address.


Destination IP address.


A list of additional options. Currently the following options are defined:


Capture the standard output of the command and redirect it to the syslog with the LOG_INFO priority.


Capture the standard error of the command and redirect it to the syslog with the LOG_ERR priority.


Do not close standard input. Redirect it from /dev/null instead. Use this option with commands that require their standard input to be open (e.g. pppd nodetach).

environ ENV-SPEC;

Modify command environment. By default the command inherits the environment of jumper augmented with the following variables:


Name of the program.


Program version.


Location in the configuration file which caused execution of the command (file name and line number separated with a colon).


Name of the event that triggered the action; one of: startup, cleanup, exit, or signal.

The environ statement allows for trimming the environment. Its argument is a list of one or more of the following environment modification directives. Before applying, the argument undergoes macro expansion using the same set of macros as the command statement (which see).

- (a single dash)

Clear the inherited environment, but retain the variables added by jumper. The removed environment variables can be selectively restored by the directives that follow. This must be the first directive in the list.

-- (double-dash)

Clear the entire environment, including the variables added by jumper. This must be the first directive in the list.


Unset the variable NAME.


Unset the environment variable NAME only if its value is VAL.


Restore the environment variable NAME. This directive is useful after - or -- to retain some variables from the environment.


Define environment variable NAME to the VALUE. VALUE can contain macro variables, which will be expanded prior to the assignment.


Retain the variable NAME and append VALUE to its existing value. If no such variable is present in the environment, it will be created and assigned the VALUE. If VALUE begins with a punctuation character, this character is removed from it before the assignment. This is convenient for using this construct with environment variables like PATH, e.g.:


In this example, if PATH exists, :/sbin will be appended to it. Otherwise, it will be created and assigned the value /sbin.

The VALUE can contain macro variables, which will be expanded prior to the assignment.


Retain the variable NAME and prepend VALUE to its existing value. If no such variable is present in the environment, it will be created and assigned the VALUE. In this case, if VALUE ends with a punctuation character, this character will be removed from it before the assignment.

The VALUE can contain macro variables, which will be expanded prior to the assignment.

onevent EVLIST { ... };

This block statement instructs jumper to perform a specified action when an event listed in EVLIST is detected. EVLIST can be either a single event, or a whitespace separated list of events, or a comma-separated list of events in parentheses. Valid events are:


The action is run immediately after jumper starts up, before it begins listening on interfaces. It can be used to set up firewall rules, etc.


The action is run before jumper terminates, right after termination of all commands.

Decimal number in range 0..127

The action is performed when the command terminates with the given code.


The action is performed when the command terminates with the code N.

Symbolic name of exit code from sysexits.h

The action is performed when the command terminates with the given exit code. Currently the following symbolic names are used: EX_OK (0), EX_USAGE (64), EX_DATAERR (65), EX_NOINPUT (66), EX_NOUSER (67), EX_NOHOST (68), EX_UNAVAILABLE (69), EX_SOFTWARE (70), EX_OSERR (71), EX_OSFILE (72), EX_CANTCREAT (73), EX_IOERR (74), EX_TEMPFAIL (75), EX_PROTOCOL (76), EX_NOPERM (77), and EX_CONFIG (78).


The action is performed when the command terminates on signal N (decimal number)

Symbolic signal name as defined in signal.h

The action is performed when the command terminates on this signal.

The following statements can be used within the block:

Run COMMAND-LINE. The following macros are expanded in the argument prior to execution:

The program name (jumper).


Name of the configuration file where the command statement is located.


Line number in that file.


Name of the event that triggered the action; one of: startup, cleanup, exit, or signal.


Program termination status as returned by the waitpid(2) call.


Exit code returned by the program, or the number of the signal that caused its termination.

environ ENV-SPEC;

Modify command environment. See the description of the environ statement above, for a detailed discussion.

timeout NUMBER

If the command does not exit within NUMBER seconds from its start, terminate it forcefully. The default is 5 seconds.


Prior to parsing, the configuration file is preprocessed using m4(1).

The include path is set initially to the following two directories:


It can be further modified using the -I (--include-directory) command line option.

If the file pp-setup is found in the include path, it is sourced before the configuration file. This can be used to provide macros and constants for the configuration.

Additional definitions can also be provided from the command line using the -D (--define) option.

To view preprocessed configuration, use the -E option. It prints the preprocessed text on the standard output.

To disable preprocessing, use the --no-preprocessor option.


Delivering the SIGHUP signal causes jumper to re-read its configuration file. When doing so, it will not touch any running processes started on behalf of listeners that underwent no changes, compared to the previous configuration. However, any command which was started for a listener whose configuration did change will be terminated prior to updating configuration.

If any errors are detected in the configuration file, the current configuration will remain unchanged.

The SIGALRM and SIGCHLD signals are used internally.

The following signals cause normal program termination: SIGTERM, SIGQUIT, SIGINT.

The signals SIGUSR1 and SIGUSR2 are reserved for future use.



Successful termination.


Command line usage error.


Internal software error (unknown data link or the like).


System error (can’t fork, out of memory, etc.)


Configuration error.


Run openvpn whenever a packet directed to one of the addresses from the network is detected on the interface eth1. Redirect both its standard error and standard output to syslog:

listen vpn {
interface eth0;

match-destination (;

command "/usr/sbin/openvpn /etc/openvpn.conf";

option (stderr, stdout);



When using jumper to start VPN, the usual operation sequence is as follows:


A client initiates connection to an IP address that should be provided by the VPN which is currently not active.


Jumper detects packets destined to that address and launches external program that brings the VPN up.


Once the VPN is up, the client successfully connects to the required IP.

To make this possible the following provisions should be made:


The iptables(8) FORWARD chain must initially contain a statement preventing packets for the IP addresses covered by the VPN from reaching their destination, e.g.:



Upon successful startup, the VPN handler must insert to this chain a rule allowing connections to that particular range of addresses. This rule must, of course, be inserted before the DROP rule. As a result, the FORWARD chain will contain something similar to:


Exact ways of achieving this depend on the program used to establish VPN connection. For openvpn(8), use the --client-connect option. For vpnc(8), modify the handling of reason=connect in the /etc/vpnc/vpnc-script file.


Upon VPN termination, that additional rule must be removed. For openvpn(8), use the --client-disconnect option. For vpnc(8), modify the handling of reason=disconnect in the /etc/vpnc/vpnc-script file.

Notice also, that you might have to specify additional onevent rules to clean-up the firewall table in case of the hang-up or similar conditions. For example, vpnc(8) fails to invoke the /etc/vpnc/vpnc-script if the connection is terminated by the server. In that case it exits with code 1. If you modify the script so that it handles reason=cleanup to clean up the firewall rules, add the following to the listen statement:

onevent 1 {

command "/etc/vpnc/vpnc-script";

environ "reason=cleanup";


Jumper is available for download from this location.

The latest version is jumper-1.2.

Recent news, changes and bugfixes can be tracked from the project's development page.


m4(1), cfpeek(1), ifalive(8).


Sergey Poznyakoff


Report bugs to <bug-jumper@gnu.org.ua>.


Copyright © 2013-2018 Sergey Poznyakoff
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.

Manpage server at man.gnu.org.ua.

Powered by mansrv 1.1