netsed
Data Structures | Macros | Enumerations | Functions | Variables
netsed.c File Reference

netsed is implemented in this single file. More...

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <getopt.h>
Include dependency graph for netsed.c:

Go to the source code of this file.

Data Structures

struct  rule_s
 Rule item. More...
 
struct  tracker_s
 This structure is used to track information about open connections. More...
 

Macros

#define PARSE_LONG_OPT
 Define to use getopt_long: GNU extension, should check _GNU_SOURCE. More...
 
#define VERSION   "1.2"
 Current version (recovered by Makefile for several release checks) More...
 
#define MAX_BUF   100000
 max size for buffers More...
 
#define ERR(x...)   fprintf(stderr,x)
 printf to stderr More...
 
#define DBG(x...)
 Disabled debug prints. More...
 
#define UDP_TIMEOUT   30
 Timeout for udp 'connections' in seconds. More...
 

Enumerations

enum  { ALL = 0, IN = 1, OUT = 2 }
 Direction specifier of replacement rule. More...
 
enum  state_e { UNREPLIED, ESTABLISHED, DISCONNECTED, TIMEOUT }
 Connection state. More...
 

Functions

void short_usage_hints (const char *why)
 Display an error message followed by short usage information. More...
 
void usage_hints (const char *why)
 Display an error message followed by usage information. More...
 
void freetracker (struct tracker_s *conn)
 Helper function to free a tracker_s item. csa will be freed if needed, sockets will be closed. More...
 
void clean_socks (void)
 Close all sockets to use before exit. More...
 
in_port_t get_port (struct sockaddr *sa)
 Extract the port information from a sockaddr for both IPv4 and IPv6. More...
 
void set_port (struct sockaddr *sa, in_port_t port)
 Set the port information in a sockaddr for both IPv4 and IPv6. More...
 
int is_addr_any (struct sockaddr *sa)
 Detect if address in the addr_any value for both IPv4 and IPv6. More...
 
void error (const char *reason)
 Display an error message and exit. More...
 
void shrink_to_binary (struct rule_s *r)
 Convert the % notation in rules to plain binary data. More...
 
void parse_params (int argc, char *argv[])
 parse the command line parameters More...
 
void bind_and_listen (int af, int tcp, const char *portstr)
 Bind and optionally listen to a socket for netsed server port. More...
 
int sed_the_buffer (int siz, int *live, int dir)
 Applies the rules to global buffer buf. More...
 
void b2server_sed (struct tracker_s *conn, ssize_t rd)
 Send the content of global buffer b2 to the server as packet or datagram. More...
 
void server2client_sed (struct tracker_s *conn)
 Receive a packet or datagram from the server, 'sed' it, send it to the client. More...
 
void client2server_sed (struct tracker_s *conn)
 Receive a packet from the client, 'sed' it, send it to the server. More...
 
void sig_int (int signo)
 Handle SIGINT signal for clean exit. More...
 
int main (int argc, char *argv[])
 This is main... More...
 

Variables

time_t now
 Store current time (just after select returned). More...
 
int lsock
 Listening socket. More...
 
int family = AF_UNSPEC
 Address family used for parameter resolution. More...
 
int tcp
 TCP or UDP. More...
 
char * lport
 Local Port. More...
 
char * rhost
 Remote Host. More...
 
char * rport
 Remote Port. More...
 
int rules
 Number of rules. More...
 
struct rule_srule
 Array of all rules. More...
 
int * rule_live
 TTL part of the rule as a flat array to be able to copy it in tracker_s::live for each connections. More...
 
struct tracker_sconnections = NULL
 List of connections. More...
 
volatile int stop =0
 True when SIGINT signal was received. More...
 
char hex [] ="0123456789ABCDEF"
 Hex digit to parsing the % notation in rules. More...
 
char buf [MAX_BUF]
 Buffer for receiving a single packet or datagram. More...
 
char b2 [MAX_BUF]
 Buffer containing modified packet or datagram. More...
 

Detailed Description

netsed is implemented in this single file.

Architecture
Netsed is implemented as a select socket dispatcher. First a main socket server is created (lsock), each connection to this socket create a context stored in the tracker_s structure and added to the connections list. Each connection has
  • a connected socket (tracker_s::csock) returned by the accept() function for tcp, or
  • a connection socket address (tracker_s::csa) filled by recvfrom() for udp.
  • a dedicated forwarding socket (tracker_s::fsock) connected to the server.
All sockets are added to the select() call and managed by the dispatcher as follows:
  • When packets are received from the client, the rules are applied by sed_the_buffer() and the packet is sent to the server. Direction is OUT. This is the role of client2server_sed() function. It is only used for tcp.
  • When packets are received from the server, the rules are applied by sed_the_buffer() and the packet is sent to the corresponding client. Direction is IN. This is the role of server2client_sed() function.
  • For udp only, connection from client to netsed are not established so netsed need to lookup existing connections to find the corresponding established link, if any. The lookup is done by comparing tracker_s::csa. Once the connection is found or created, the rules are applied by sed_the_buffer() and the packet is sent to the server. This is the role of b2server_sed() function.
Note
For tcp tracker_s::csa is NULL and for udp the tracker_s::csock is filled with lsock. This is done in order to share code and avoid discriminating between tcp or udp everywhere, sendto are done on tracker_s::csock with tracker_s::csa only and the actual value of those will reflect the needs.
I'm saying packets and connections, but for udp these are actually datagrams and pseudo-connections. The pseudo-connection is defined by the fact that the client uses the same address and port (same tracker_s::csa) with a life time defined by UDP_TIMEOUT to clean the connection list.
Todo:
Implements features listed in TODO file.

Definition in file netsed.c.

Macro Definition Documentation

◆ DBG

#define DBG (   x...)

Disabled debug prints.

Definition at line 144 of file netsed.c.

◆ ERR

#define ERR (   x...)    fprintf(stderr,x)

printf to stderr

Definition at line 135 of file netsed.c.

◆ MAX_BUF

#define MAX_BUF   100000

max size for buffers

Definition at line 132 of file netsed.c.

◆ PARSE_LONG_OPT

#define PARSE_LONG_OPT

Define to use getopt_long: GNU extension, should check _GNU_SOURCE.

Definition at line 124 of file netsed.c.

◆ UDP_TIMEOUT

#define UDP_TIMEOUT   30

Timeout for udp 'connections' in seconds.

Definition at line 148 of file netsed.c.

◆ VERSION

#define VERSION   "1.2"

Current version (recovered by Makefile for several release checks)

Definition at line 130 of file netsed.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Direction specifier of replacement rule.

Enumerator
ALL 
IN 
OUT 

Definition at line 168 of file netsed.c.

◆ state_e

enum state_e

Connection state.

Enumerator
UNREPLIED 

udp datagram received by netsed and send to server, no response yet.

ESTABLISHED 

tcp accepted connection or udp 'connection' with a response from server.

DISCONNECTED 

tcp or udp disconnected (detected by an error on read or send).

Note
all values after and including DISCONNECTED are considered as error and the connection will be discarded.
TIMEOUT 

udp timeout expired.

Definition at line 175 of file netsed.c.

Function Documentation

◆ b2server_sed()

void b2server_sed ( struct tracker_s conn,
ssize_t  rd 
)

Send the content of global buffer b2 to the server as packet or datagram.

Parameters
connconnection giving the sockets to use.
rdsize of b2 content.

Definition at line 693 of file netsed.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bind_and_listen()

void bind_and_listen ( int  af,
int  tcp,
const char *  portstr 
)

Bind and optionally listen to a socket for netsed server port.

Parameters
afaddress family.
tcp1 tcp, 0 udp.
portstrstring representing the port to bind (will be resolved using getaddrinfo()).

Definition at line 548 of file netsed.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clean_socks()

void clean_socks ( void  )

Close all sockets to use before exit.

Definition at line 317 of file netsed.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ client2server_sed()

void client2server_sed ( struct tracker_s conn)

Receive a packet from the client, 'sed' it, send it to the server.

Parameters
connconnection giving the sockets to use.

Definition at line 674 of file netsed.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ error()

void error ( const char *  reason)

Display an error message and exit.

Definition at line 379 of file netsed.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ freetracker()

void freetracker ( struct tracker_s conn)

Helper function to free a tracker_s item. csa will be freed if needed, sockets will be closed.

Parameters
connpointer to free.

Definition at line 304 of file netsed.c.

Here is the caller graph for this function:

◆ get_port()

in_port_t get_port ( struct sockaddr *  sa)

Extract the port information from a sockaddr for both IPv4 and IPv6.

Parameters
sasockaddr to get port from

Definition at line 337 of file netsed.c.

Here is the caller graph for this function:

◆ is_addr_any()

int is_addr_any ( struct sockaddr *  sa)

Detect if address in the addr_any value for both IPv4 and IPv6.

Parameters
sasockaddr to test
Returns
true if sa in addr_any

Definition at line 366 of file netsed.c.

Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *  argv[] 
)

This is main...

Definition at line 713 of file netsed.c.

Here is the call graph for this function:

◆ parse_params()

void parse_params ( int  argc,
char *  argv[] 
)

parse the command line parameters

Parameters
argcnumber of arguments
argvarray of string parameters

Definition at line 460 of file netsed.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sed_the_buffer()

int sed_the_buffer ( int  siz,
int *  live,
int  dir 
)

Applies the rules to global buffer buf.

Parameters
sizuseful size of the data in buf.
liveTTL state of current connection.
packetdirection

Definition at line 605 of file netsed.c.

Here is the caller graph for this function:

◆ server2client_sed()

void server2client_sed ( struct tracker_s conn)

Receive a packet or datagram from the server, 'sed' it, send it to the client.

Parameters
connconnection giving the sockets to use.

Definition at line 647 of file netsed.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_port()

void set_port ( struct sockaddr *  sa,
in_port_t  port 
)

Set the port information in a sockaddr for both IPv4 and IPv6.

Parameters
sasockaddr to update
portport value

Definition at line 351 of file netsed.c.

Here is the caller graph for this function:

◆ short_usage_hints()

void short_usage_hints ( const char *  why)

Display an error message followed by short usage information.

Parameters
whythe error message.

Definition at line 247 of file netsed.c.

Here is the caller graph for this function:

◆ shrink_to_binary()

void shrink_to_binary ( struct rule_s r)

Convert the % notation in rules to plain binary data.

Parameters
rrule to update

Definition at line 391 of file netsed.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sig_int()

void sig_int ( int  signo)

Handle SIGINT signal for clean exit.

Definition at line 706 of file netsed.c.

Here is the caller graph for this function:

◆ usage_hints()

void usage_hints ( const char *  why)

Display an error message followed by usage information.

Parameters
whythe error message.

Definition at line 257 of file netsed.c.

Here is the caller graph for this function:

Variable Documentation

◆ b2

char b2[MAX_BUF]

Buffer containing modified packet or datagram.

Definition at line 599 of file netsed.c.

◆ buf

char buf[MAX_BUF]

Buffer for receiving a single packet or datagram.

Definition at line 597 of file netsed.c.

◆ connections

struct tracker_s* connections = NULL

List of connections.

Definition at line 240 of file netsed.c.

◆ family

int family = AF_UNSPEC

Address family used for parameter resolution.

Definition at line 218 of file netsed.c.

◆ hex

char hex[] ="0123456789ABCDEF"

Hex digit to parsing the % notation in rules.

Definition at line 387 of file netsed.c.

◆ lport

char* lport

Local Port.

Definition at line 224 of file netsed.c.

◆ lsock

int lsock

Listening socket.

Definition at line 213 of file netsed.c.

◆ now

time_t now

Store current time (just after select returned).

Definition at line 210 of file netsed.c.

◆ rhost

char* rhost

Remote Host.

Definition at line 227 of file netsed.c.

◆ rport

char* rport

Remote Port.

Definition at line 229 of file netsed.c.

◆ rule

struct rule_s* rule

Array of all rules.

Definition at line 234 of file netsed.c.

◆ rule_live

int* rule_live

TTL part of the rule as a flat array to be able to copy it in tracker_s::live for each connections.

Definition at line 237 of file netsed.c.

◆ rules

int rules

Number of rules.

Definition at line 232 of file netsed.c.

◆ stop

volatile int stop =0

True when SIGINT signal was received.

Definition at line 243 of file netsed.c.

◆ tcp

int tcp

TCP or UDP.

Definition at line 221 of file netsed.c.