Synchronise HEAD with CABAL branch.
This commit is contained in:
parent
efa5148bc7
commit
013a2e159e
173 changed files with 12252 additions and 28046 deletions
|
|
@ -1,17 +1,15 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
# $Id: Makefile.am,v 1.9 2002/05/02 13:11:55 zarq Exp $
|
||||
# $Id: Makefile.am,v 1.10 2003/08/24 20:38:20 guus Exp $
|
||||
|
||||
noinst_LIBRARIES = libtinc.a
|
||||
noinst_LIBRARIES = libvpn.a
|
||||
|
||||
INCLUDES = @INCLUDES@ -I. -I$(top_builddir) -I$(top_srcdir)/intl
|
||||
INCLUDES = @INCLUDES@ -I. -I$(top_builddir)
|
||||
|
||||
libtinc_a_SOURCES = xmalloc.c pidfile.c utils.c getopt.c getopt1.c \
|
||||
list.c avl_tree.c hooks.c dropin.c edge.c conf.c netutl.c logging.c connection.c subnet.c node.c graph.c event.c
|
||||
libvpn_a_SOURCES = xmalloc.c pidfile.c utils.c getopt.c getopt1.c list.c avl_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c
|
||||
|
||||
libtinc_a_LIBADD = @LIBOBJS@ @ALLOCA@
|
||||
libtinc_a_DEPENDENCIES = $(libvpn_a_LIBADD)
|
||||
libvpn_a_LIBADD = @LIBOBJS@ @ALLOCA@
|
||||
libvpn_a_DEPENDENCIES = $(libvpn_a_LIBADD)
|
||||
|
||||
noinst_HEADERS = xalloc.h pidfile.h utils.h getopt.h list.h avl_tree.h \
|
||||
hooks.h dropin.h edge.h net.h conf.h netutl.h logging.h connection.h subnet.h node.h graph.h event.h
|
||||
noinst_HEADERS = xalloc.h pidfile.h utils.h getopt.h list.h avl_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h gettext.h ipv6.h ipv4.h ethernet.h
|
||||
|
||||
EXTRA_DIST = README
|
||||
EXTRA_DIST =
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
The files in this directory were merely copied from fileutils 4.0.
|
||||
930
lib/avl_tree.c
930
lib/avl_tree.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
avl_tree.h -- header file for avl_tree.c
|
||||
Copyright (C) 1998 Michael H. Buselli
|
||||
2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>,
|
||||
2000,2001 Guus Sliepen <guus@sliepen.warande.net>
|
||||
2000,2001 Wessel Dankers <wsl@nl.linux.org>
|
||||
2000-2003 Ivo Timmermans <ivo@o2w.nl>,
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
2000-2003 Wessel Dankers <wsl@nl.linux.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -27,9 +27,9 @@
|
|||
|
||||
Cleaned up and incorporated some of the ideas from the red-black tree
|
||||
library for inclusion into tinc (http://tinc.nl.linux.org/) by
|
||||
Guus Sliepen <guus@sliepen.warande.net>.
|
||||
Guus Sliepen <guus@sliepen.eu.org>.
|
||||
|
||||
$Id: avl_tree.h,v 1.2 2002/04/09 15:26:00 zarq Exp $
|
||||
$Id: avl_tree.h,v 1.3 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -37,54 +37,54 @@
|
|||
#define __AVL_TREE_H__
|
||||
|
||||
#ifndef AVL_DEPTH
|
||||
#ifndef AVL_COUNT
|
||||
#define AVL_DEPTH
|
||||
#endif
|
||||
#ifndef AVL_COUNT
|
||||
#define AVL_DEPTH
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct avl_node_t {
|
||||
|
||||
/* Linked list part */
|
||||
/* Linked list part */
|
||||
|
||||
struct avl_node_t *next;
|
||||
struct avl_node_t *prev;
|
||||
struct avl_node_t *next;
|
||||
struct avl_node_t *prev;
|
||||
|
||||
/* Tree part */
|
||||
/* Tree part */
|
||||
|
||||
struct avl_node_t *parent;
|
||||
struct avl_node_t *left;
|
||||
struct avl_node_t *right;
|
||||
struct avl_node_t *parent;
|
||||
struct avl_node_t *left;
|
||||
struct avl_node_t *right;
|
||||
|
||||
#ifdef AVL_COUNT
|
||||
unsigned int count;
|
||||
unsigned int count;
|
||||
#endif
|
||||
#ifdef AVL_DEPTH
|
||||
unsigned char depth;
|
||||
unsigned char depth;
|
||||
#endif
|
||||
|
||||
/* Payload */
|
||||
/* Payload */
|
||||
|
||||
void *data;
|
||||
void *data;
|
||||
|
||||
} avl_node_t;
|
||||
|
||||
typedef int (*avl_compare_t) (const void *, const void *);
|
||||
typedef void (*avl_action_t) (const void *);
|
||||
typedef void (*avl_action_node_t) (const avl_node_t *);
|
||||
typedef int (*avl_compare_t)(const void *, const void *);
|
||||
typedef void (*avl_action_t)(const void *);
|
||||
typedef void (*avl_action_node_t)(const avl_node_t *);
|
||||
|
||||
typedef struct avl_tree_t {
|
||||
|
||||
/* Linked list part */
|
||||
/* Linked list part */
|
||||
|
||||
avl_node_t *head;
|
||||
avl_node_t *tail;
|
||||
avl_node_t *head;
|
||||
avl_node_t *tail;
|
||||
|
||||
/* Tree part */
|
||||
/* Tree part */
|
||||
|
||||
avl_node_t *root;
|
||||
avl_node_t *root;
|
||||
|
||||
avl_compare_t compare;
|
||||
avl_action_t delete;
|
||||
avl_compare_t compare;
|
||||
avl_action_t delete;
|
||||
|
||||
} avl_tree_t;
|
||||
|
||||
|
|
@ -128,18 +128,18 @@ extern avl_node_t *avl_search_closest_greater_node(const avl_tree_t *, const voi
|
|||
|
||||
/* Tree walking */
|
||||
|
||||
extern void avl_foreach(avl_tree_t *, avl_action_t);
|
||||
extern void avl_foreach_node(avl_tree_t *, avl_action_t);
|
||||
extern void avl_foreach(const avl_tree_t *, avl_action_t);
|
||||
extern void avl_foreach_node(const avl_tree_t *, avl_action_t);
|
||||
|
||||
/* Indexing */
|
||||
|
||||
#ifdef AVL_COUNT
|
||||
extern unsigned int avl_count(avl_tree_t *);
|
||||
extern unsigned int avl_count(const avl_tree_t *);
|
||||
extern avl_node_t *avl_get_node(const avl_tree_t *, unsigned int);
|
||||
extern unsigned int avl_index(const avl_node_t *);
|
||||
#endif
|
||||
#ifdef AVL_DEPTH
|
||||
extern unsigned int avl_depth(avl_tree_t *);
|
||||
extern unsigned int avl_depth(const avl_tree_t *);
|
||||
#endif
|
||||
|
||||
#endif /* __AVL_TREE_H__ */
|
||||
#endif /* __AVL_TREE_H__ */
|
||||
|
|
|
|||
269
lib/conf.c
269
lib/conf.c
|
|
@ -1,269 +0,0 @@
|
|||
/*
|
||||
conf.c -- configuration storage & retrieval code
|
||||
Copyright (C) 1998 Robert van der Meulen
|
||||
1998-2002 Ivo Timmermans <ivo@o2w.nl>
|
||||
2000-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
2000 Cris van Pelt <tribbel@arise.dhs.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: conf.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xalloc.h>
|
||||
#include <utils.h> /* for cp */
|
||||
#include <avl_tree.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "netutl.h" /* for str2address */
|
||||
#include "logging.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
avl_tree_t *config_tree;
|
||||
|
||||
int pingtimeout = 0; /* seconds before timeout */
|
||||
char *confbase = NULL; /* directory in which all config files are */
|
||||
char *netname = NULL; /* name of the vpn network */
|
||||
|
||||
int config_compare(config_t *a, config_t *b)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = strcasecmp(a->variable, b->variable);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = a->line - b->line;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
else
|
||||
return strcmp(a->file, b->file);
|
||||
}
|
||||
|
||||
void init_configuration(avl_tree_t **config_tree)
|
||||
{
|
||||
cp
|
||||
*config_tree = avl_alloc_tree((avl_compare_t)config_compare, (avl_action_t)free_config);
|
||||
cp
|
||||
}
|
||||
|
||||
void exit_configuration(avl_tree_t **config_tree)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(*config_tree);
|
||||
*config_tree = NULL;
|
||||
cp
|
||||
}
|
||||
|
||||
config_t *new_config(void)
|
||||
{
|
||||
config_t *cfg;
|
||||
cp
|
||||
cfg = (config_t *)xmalloc_and_zero(sizeof(*cfg));
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
void free_config(config_t *cfg)
|
||||
{
|
||||
cp
|
||||
if(cfg->variable)
|
||||
free(cfg->variable);
|
||||
if(cfg->value)
|
||||
free(cfg->value);
|
||||
if(cfg->file)
|
||||
free(cfg->file);
|
||||
free(cfg);
|
||||
cp
|
||||
}
|
||||
|
||||
void config_add(avl_tree_t *config_tree, config_t *cfg)
|
||||
{
|
||||
cp
|
||||
avl_insert(config_tree, cfg);
|
||||
cp
|
||||
}
|
||||
|
||||
config_t *lookup_config(avl_tree_t *config_tree, char *variable)
|
||||
{
|
||||
config_t cfg, *found;
|
||||
cp
|
||||
cfg.variable = variable;
|
||||
cfg.file = "";
|
||||
cfg.line = 0;
|
||||
|
||||
found = avl_search_closest_greater(config_tree, &cfg);
|
||||
|
||||
if(!found)
|
||||
return NULL;
|
||||
|
||||
if(strcasecmp(found->variable, variable))
|
||||
return NULL;
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
config_t *lookup_config_next(avl_tree_t *config_tree, config_t *cfg)
|
||||
{
|
||||
avl_node_t *node;
|
||||
config_t *found;
|
||||
cp
|
||||
node = avl_search_node(config_tree, cfg);
|
||||
|
||||
if(node)
|
||||
{
|
||||
if(node->next)
|
||||
{
|
||||
found = (config_t *)node->next->data;
|
||||
if(!strcasecmp(found->variable, cfg->variable))
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int get_config_bool(config_t *cfg, int *result)
|
||||
{
|
||||
cp
|
||||
if(!cfg)
|
||||
return 0;
|
||||
|
||||
if(!strcasecmp(cfg->value, "yes"))
|
||||
{
|
||||
*result = 1;
|
||||
return 1;
|
||||
}
|
||||
else if(!strcasecmp(cfg->value, "no"))
|
||||
{
|
||||
*result = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
syslog(LOG_ERR, _("\"yes\" or \"no\" expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_config_int(config_t *cfg, int *result)
|
||||
{
|
||||
cp
|
||||
if(!cfg)
|
||||
return 0;
|
||||
|
||||
if(sscanf(cfg->value, "%d", result) == 1)
|
||||
return 1;
|
||||
|
||||
syslog(LOG_ERR, _("Integer expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_config_string(config_t *cfg, char **result)
|
||||
{
|
||||
cp
|
||||
if(!cfg)
|
||||
return 0;
|
||||
|
||||
*result = xstrdup(cfg->value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int get_config_address(config_t *cfg, struct addrinfo **result)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
cp
|
||||
if(!cfg)
|
||||
return 0;
|
||||
|
||||
ai = str2addrinfo(cfg->value, NULL, 0);
|
||||
|
||||
if(ai)
|
||||
{
|
||||
*result = ai;
|
||||
return 1;
|
||||
}
|
||||
|
||||
syslog(LOG_ERR, _("Hostname or IP address expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_config_port(config_t *cfg, port_t *result)
|
||||
{
|
||||
cp
|
||||
if(!cfg)
|
||||
return 0;
|
||||
|
||||
if(sscanf(cfg->value, "%hu", result) == 1)
|
||||
{
|
||||
*result = htons(*result);
|
||||
return 1;
|
||||
}
|
||||
|
||||
syslog(LOG_ERR, _("Port number expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_config_subnet(config_t *cfg, subnet_t **result)
|
||||
{
|
||||
subnet_t *subnet;
|
||||
cp
|
||||
if(!cfg)
|
||||
return 0;
|
||||
|
||||
subnet = str2net(cfg->value);
|
||||
|
||||
if(!subnet)
|
||||
{
|
||||
syslog(LOG_ERR, _("Subnet expected for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Teach newbies what subnets are... */
|
||||
|
||||
if(((subnet->type == SUBNET_IPV4) && maskcheck((char *)&subnet->net.ipv4.address, subnet->net.ipv4.prefixlength, sizeof(ipv4_t)))
|
||||
|| ((subnet->type == SUBNET_IPV6) && maskcheck((char *)&subnet->net.ipv6.address, subnet->net.ipv6.prefixlength, sizeof(ipv6_t))))
|
||||
{
|
||||
syslog(LOG_ERR, _("Network address and prefix length do not match for configuration variable %s in %s line %d"),
|
||||
cfg->variable, cfg->file, cfg->line);
|
||||
free(subnet);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*result = subnet;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
65
lib/conf.h
65
lib/conf.h
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
conf.h -- header for conf.c
|
||||
Copyright (C) 1998-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: conf.h,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_CONF_H__
|
||||
#define __TINC_CONF_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
#include "net.h"
|
||||
#include "subnet.h"
|
||||
|
||||
typedef struct config_t {
|
||||
char *variable;
|
||||
char *value;
|
||||
char *file;
|
||||
int line;
|
||||
} config_t;
|
||||
|
||||
extern avl_tree_t *config_tree;
|
||||
|
||||
extern int pingtimeout;
|
||||
extern int maxtimeout;
|
||||
extern int bypass_security;
|
||||
extern char *confbase;
|
||||
extern char *netname;
|
||||
|
||||
extern void init_configuration(avl_tree_t **);
|
||||
extern void exit_configuration(avl_tree_t **);
|
||||
extern config_t *new_config(void);
|
||||
extern void free_config(config_t *);
|
||||
extern void config_add(avl_tree_t *, config_t *);
|
||||
extern config_t *lookup_config(avl_tree_t *, char *);
|
||||
extern config_t *lookup_config_next(avl_tree_t *, config_t *);
|
||||
extern int get_config_bool(config_t *, int *);
|
||||
extern int get_config_int(config_t *, int *);
|
||||
extern int get_config_port(config_t *, port_t *);
|
||||
extern int get_config_string(config_t *, char **);
|
||||
extern int get_config_address(config_t *, struct addrinfo **);
|
||||
struct subnet_t; /* Needed for next line. */
|
||||
extern int get_config_subnet(config_t *, struct subnet_t **);
|
||||
|
||||
#endif /* __TINC_CONF_H__ */
|
||||
126
lib/connection.c
126
lib/connection.c
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
connection.c -- connection list management
|
||||
Copyright (C) 2000-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2000-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: connection.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
#include <list.h>
|
||||
|
||||
#include "net.h" /* Don't ask. */
|
||||
#include "netutl.h"
|
||||
#include "config.h"
|
||||
#include "conf.h"
|
||||
#include <utils.h>
|
||||
#include "subnet.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include "xalloc.h"
|
||||
#include "system.h"
|
||||
|
||||
avl_tree_t *connection_tree; /* Meta connections */
|
||||
|
||||
int connection_compare(connection_t *a, connection_t *b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
void init_connections(void)
|
||||
{
|
||||
cp
|
||||
connection_tree = avl_alloc_tree((avl_compare_t)connection_compare, NULL);
|
||||
cp
|
||||
}
|
||||
|
||||
void exit_connections(void)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(connection_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
connection_t *new_connection(void)
|
||||
{
|
||||
connection_t *c;
|
||||
cp
|
||||
c = (connection_t *)xmalloc_and_zero(sizeof(connection_t));
|
||||
|
||||
if(!c)
|
||||
return NULL;
|
||||
|
||||
gettimeofday(&c->start, NULL);
|
||||
cp
|
||||
return c;
|
||||
}
|
||||
|
||||
void free_connection(connection_t *c)
|
||||
{
|
||||
cp
|
||||
if(c->hostname)
|
||||
free(c->hostname);
|
||||
if(c->inkey)
|
||||
free(c->inkey);
|
||||
if(c->outkey)
|
||||
free(c->outkey);
|
||||
if(c->mychallenge)
|
||||
free(c->mychallenge);
|
||||
if(c->hischallenge)
|
||||
free(c->hischallenge);
|
||||
free(c);
|
||||
cp
|
||||
}
|
||||
|
||||
void connection_add(connection_t *c)
|
||||
{
|
||||
cp
|
||||
avl_insert(connection_tree, c);
|
||||
cp
|
||||
}
|
||||
|
||||
void connection_del(connection_t *c)
|
||||
{
|
||||
cp
|
||||
avl_delete(connection_tree, c);
|
||||
cp
|
||||
}
|
||||
|
||||
void dump_connections(void)
|
||||
{
|
||||
avl_node_t *node;
|
||||
connection_t *c;
|
||||
cp
|
||||
syslog(LOG_DEBUG, _("Connections:"));
|
||||
|
||||
for(node = connection_tree->head; node; node = node->next)
|
||||
{
|
||||
c = (connection_t *)node->data;
|
||||
syslog(LOG_DEBUG, _(" %s at %s options %lx socket %d status %04x"),
|
||||
c->name, c->hostname, c->options, c->socket, c->status);
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, _("End of connections."));
|
||||
cp
|
||||
}
|
||||
141
lib/connection.h
141
lib/connection.h
|
|
@ -1,141 +0,0 @@
|
|||
/*
|
||||
connection.h -- header for connection.c
|
||||
Copyright (C) 2000-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2000-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: connection.h,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_CONNECTION_H__
|
||||
#define __TINC_CONNECTION_H__
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
#include <list.h>
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
# ifdef HAVE_OPENSSL_EVP_H
|
||||
# include <openssl/evp.h>
|
||||
# else
|
||||
# include <evp.h>
|
||||
# endif
|
||||
|
||||
# ifdef HAVE_OPENSSL_RSA_H
|
||||
# include <openssl/rsa.h>
|
||||
# else
|
||||
# include <rsa.h>
|
||||
# endif
|
||||
#endif /* USE_OPENSSL */
|
||||
|
||||
#ifdef USE_GCRYPT
|
||||
# include <gcrypt.h>
|
||||
#endif
|
||||
|
||||
#include "net.h"
|
||||
#include "conf.h"
|
||||
|
||||
#include "node.h"
|
||||
#include "edge.h"
|
||||
|
||||
#define OPTION_INDIRECT 0x0001
|
||||
#define OPTION_TCPONLY 0x0002
|
||||
|
||||
typedef struct connection_status_t {
|
||||
int pinged:1; /* sent ping */
|
||||
int active:1; /* 1 if active.. */
|
||||
int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */
|
||||
int termreq:1; /* the termination of this connection was requested */
|
||||
int remove:1; /* Set to 1 if you want this connection removed */
|
||||
int timeout:1; /* 1 if gotten timeout */
|
||||
int encryptout:1; /* 1 if we can encrypt outgoing traffic */
|
||||
int decryptin:1; /* 1 if we have to decrypt incoming traffic */
|
||||
int mst:1; /* 1 if this connection is part of a minimum spanning tree */
|
||||
int unused:18;
|
||||
} connection_status_t;
|
||||
|
||||
typedef struct connection_t {
|
||||
char *name; /* name he claims to have */
|
||||
|
||||
sockaddr_t address; /* his real (internet) ip */
|
||||
char *hostname; /* the hostname of its real ip */
|
||||
int protocol_version; /* used protocol */
|
||||
|
||||
int socket; /* socket used for this connection */
|
||||
long int options; /* options for this connection */
|
||||
struct connection_status_t status; /* status info */
|
||||
int estimated_weight; /* estimation for the weight of the edge for this connection */
|
||||
struct timeval start; /* time this connection was started, used for above estimation */
|
||||
struct outgoing_t *outgoing; /* used to keep track of outgoing connections */
|
||||
|
||||
struct node_t *node; /* node associated with the other end */
|
||||
struct edge_t *edge; /* edge associated with this connection */
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
RSA *rsa_key; /* his public/private key */
|
||||
const EVP_CIPHER *incipher; /* Cipher he will use to send data to us */
|
||||
const EVP_CIPHER *outcipher; /* Cipher we will use to send data to him */
|
||||
EVP_CIPHER_CTX *inctx; /* Context of encrypted meta data that will come from him to us */
|
||||
EVP_CIPHER_CTX *outctx; /* Context of encrypted meta data that will be sent from us to him */
|
||||
const EVP_MD *indigest;
|
||||
const EVP_MD *outdigest;
|
||||
#endif
|
||||
|
||||
#ifdef USE_GCRYPT
|
||||
GCRY_SEXP rsa_key;
|
||||
GCRY_CIPHER_HD incipher;
|
||||
GCRY_CIPHER_HD outcipher;
|
||||
GCRY_CIPHER_HD inctx;
|
||||
GCRY_CIPHER_HD outctx;
|
||||
GCRY_MD_HD indigest;
|
||||
GCRY_MD_HD outdigest;
|
||||
/* FIXME */
|
||||
#endif
|
||||
|
||||
char *inkey; /* His symmetric meta key + iv */
|
||||
char *outkey; /* Our symmetric meta key + iv */
|
||||
int inkeylength; /* Length of his key + iv */
|
||||
int outkeylength; /* Length of our key + iv */
|
||||
int inmaclength;
|
||||
int outmaclength;
|
||||
int incompression;
|
||||
int outcompression;
|
||||
char *mychallenge; /* challenge we received from him */
|
||||
char *hischallenge; /* challenge we sent to him */
|
||||
|
||||
char buffer[MAXBUFSIZE]; /* metadata input buffer */
|
||||
int buflen; /* bytes read into buffer */
|
||||
int tcplen; /* length of incoming TCPpacket */
|
||||
int allow_request; /* defined if there's only one request possible */
|
||||
|
||||
time_t last_ping_time; /* last time we saw some activity from the other end */
|
||||
|
||||
avl_tree_t *config_tree; /* Pointer to configuration tree belonging to him */
|
||||
} connection_t;
|
||||
|
||||
extern avl_tree_t *connection_tree;
|
||||
|
||||
extern void init_connections(void);
|
||||
extern void exit_connections(void);
|
||||
extern connection_t *new_connection(void);
|
||||
extern void free_connection(connection_t *);
|
||||
extern void connection_add(connection_t *);
|
||||
extern void connection_del(connection_t *);
|
||||
extern void dump_connections(void);
|
||||
extern int read_connection_config(connection_t *);
|
||||
|
||||
#endif /* __TINC_CONNECTION_H__ */
|
||||
206
lib/dropin.c
206
lib/dropin.c
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
dropin.c -- a set of drop-in replacements for libc functions
|
||||
Copyright (C) 2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>,
|
||||
2000,2001 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 2000-2003 Ivo Timmermans <ivo@o2w.nl>,
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -17,23 +17,12 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: dropin.c,v 1.2 2002/04/09 15:26:00 zarq Exp $
|
||||
$Id: dropin.c,v 1.3 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <xalloc.h>
|
||||
|
||||
#include <system.h>
|
||||
#include <errno.h>
|
||||
#include "xalloc.h"
|
||||
|
||||
#ifndef HAVE_DAEMON
|
||||
/*
|
||||
|
|
@ -51,61 +40,55 @@
|
|||
*/
|
||||
int daemon(int nochdir, int noclose)
|
||||
{
|
||||
pid_t pid;
|
||||
int fd;
|
||||
|
||||
pid = fork();
|
||||
|
||||
/* Check if forking failed */
|
||||
if(pid < 0)
|
||||
{
|
||||
perror("fork");
|
||||
exit(-1);
|
||||
}
|
||||
#ifdef HAVE_FORK
|
||||
pid_t pid;
|
||||
int fd;
|
||||
|
||||
/* If we are the parent, terminate */
|
||||
if(pid)
|
||||
exit(0);
|
||||
pid = fork();
|
||||
|
||||
/* Detach by becoming the new process group leader */
|
||||
if(setsid() < 0)
|
||||
{
|
||||
perror("setsid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Change working directory to the root (to avoid keeping mount
|
||||
points busy) */
|
||||
if(!nochdir)
|
||||
{
|
||||
chdir("/");
|
||||
}
|
||||
|
||||
/* Redirect stdin/out/err to /dev/null */
|
||||
if(!noclose)
|
||||
{
|
||||
fd = open("/dev/null", O_RDWR);
|
||||
/* Check if forking failed */
|
||||
if(pid < 0) {
|
||||
perror("fork");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if(fd < 0)
|
||||
{
|
||||
perror("opening /dev/null");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
}
|
||||
}
|
||||
/* If we are the parent, terminate */
|
||||
if(pid)
|
||||
exit(0);
|
||||
|
||||
return 0;
|
||||
/* Detach by becoming the new process group leader */
|
||||
if(setsid() < 0) {
|
||||
perror("setsid");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Change working directory to the root (to avoid keeping mount
|
||||
points busy) */
|
||||
if(!nochdir) {
|
||||
chdir("/");
|
||||
}
|
||||
|
||||
/* Redirect stdin/out/err to /dev/null */
|
||||
if(!noclose) {
|
||||
fd = open("/dev/null", O_RDWR);
|
||||
|
||||
if(fd < 0) {
|
||||
perror("opening /dev/null");
|
||||
return -1;
|
||||
} else {
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef HAVE_GET_CURRENT_DIR_NAME
|
||||
/*
|
||||
Replacement for the GNU get_current_dir_name function:
|
||||
|
|
@ -116,56 +99,75 @@ int daemon(int nochdir, int noclose)
|
|||
*/
|
||||
char *get_current_dir_name(void)
|
||||
{
|
||||
size_t size;
|
||||
char *buf;
|
||||
char *r;
|
||||
size_t size;
|
||||
char *buf;
|
||||
char *r;
|
||||
|
||||
/* Start with 100 bytes. If this turns out to be insufficient to
|
||||
contain the working directory, double the size. */
|
||||
size = 100;
|
||||
buf = xmalloc(size);
|
||||
/* Start with 100 bytes. If this turns out to be insufficient to
|
||||
contain the working directory, double the size. */
|
||||
size = 100;
|
||||
buf = xmalloc(size);
|
||||
|
||||
errno = 0; /* Success */
|
||||
r = getcwd(buf, size);
|
||||
/* getcwd returns NULL and sets errno to ERANGE if the bufferspace
|
||||
is insufficient to contain the entire working directory. */
|
||||
while(r == NULL && errno == ERANGE)
|
||||
{
|
||||
free(buf);
|
||||
size <<= 1; /* double the size */
|
||||
buf = xmalloc(size);
|
||||
r = getcwd(buf, size);
|
||||
}
|
||||
errno = 0; /* Success */
|
||||
r = getcwd(buf, size);
|
||||
|
||||
return buf;
|
||||
/* getcwd returns NULL and sets errno to ERANGE if the bufferspace
|
||||
is insufficient to contain the entire working directory. */
|
||||
while(r == NULL && errno == ERANGE) {
|
||||
free(buf);
|
||||
size <<= 1; /* double the size */
|
||||
buf = xmalloc(size);
|
||||
r = getcwd(buf, size);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
int asprintf(char **buf, const char *fmt, ...)
|
||||
{
|
||||
int status;
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
len = 4096;
|
||||
*buf = xmalloc(len);
|
||||
int status;
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
va_start(ap, fmt);
|
||||
status = vsnprintf (*buf, len, fmt, ap);
|
||||
va_end (ap);
|
||||
len = 4096;
|
||||
*buf = xmalloc(len);
|
||||
|
||||
if(status >= 0)
|
||||
*buf = xrealloc(*buf, status);
|
||||
va_start(ap, fmt);
|
||||
status = vsnprintf(*buf, len, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if(status > len-1)
|
||||
{
|
||||
len = status;
|
||||
va_start(ap, fmt);
|
||||
status = vsnprintf (*buf, len, fmt, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
if(status >= 0)
|
||||
*buf = xrealloc(*buf, status + 1);
|
||||
|
||||
return status;
|
||||
if(status > len - 1) {
|
||||
len = status;
|
||||
va_start(ap, fmt);
|
||||
status = vsnprintf(*buf, len, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETTIMEOFDAY
|
||||
int gettimeofday(struct timeval *tv, void *tz) {
|
||||
tv->tv_sec = time(NULL);
|
||||
tv->tv_usec = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RANDOM
|
||||
#include <openssl/rand.h>
|
||||
|
||||
long int random(void) {
|
||||
long int x;
|
||||
|
||||
RAND_pseudo_bytes((unsigned char *)&x, sizeof(x));
|
||||
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
26
lib/dropin.h
26
lib/dropin.h
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
dropin.h -- header file for dropin.c
|
||||
Copyright (C) 2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>,
|
||||
2000,2001 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 2000-2003 Ivo Timmermans <ivo@o2w.nl>,
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -17,22 +17,38 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: dropin.h,v 1.2 2002/04/09 15:26:00 zarq Exp $
|
||||
$Id: dropin.h,v 1.3 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __DROPIN_H__
|
||||
#define __DROPIN_H__
|
||||
|
||||
#include "fake-getaddrinfo.h"
|
||||
#include "fake-getnameinfo.h"
|
||||
|
||||
#ifndef HAVE_DAEMON
|
||||
extern int daemon(int, int);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GET_CURRENT_DIR_NAME
|
||||
extern char* get_current_dir_name(void);
|
||||
extern char *get_current_dir_name(void);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
extern int asprintf(char **, const char *, ...);
|
||||
#endif
|
||||
|
||||
#endif /* __DROPIN_H__ */
|
||||
#ifndef HAVE_GETNAMEINFO
|
||||
extern int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
|
||||
size_t hostlen, char *serv, size_t servlen, int flags);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETTIMEOFDAY
|
||||
extern int gettimeofday(struct timeval *, void *);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RANDOM
|
||||
extern long int random(void);
|
||||
#endif
|
||||
|
||||
#endif /* __DROPIN_H__ */
|
||||
|
|
|
|||
212
lib/edge.c
212
lib/edge.c
|
|
@ -1,212 +0,0 @@
|
|||
/*
|
||||
edge.c -- edge tree management
|
||||
Copyright (C) 2000-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2000-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: edge.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
#include <list.h>
|
||||
|
||||
#include "net.h" /* Don't ask. */
|
||||
#include "netutl.h"
|
||||
#include "config.h"
|
||||
#include "conf.h"
|
||||
#include <utils.h>
|
||||
#include "subnet.h"
|
||||
|
||||
#include "xalloc.h"
|
||||
#include "system.h"
|
||||
|
||||
avl_tree_t *edge_tree; /* Tree with all known edges (replaces active_tree) */
|
||||
avl_tree_t *edge_weight_tree; /* Tree with all edges, sorted on weight */
|
||||
|
||||
int edge_compare(edge_t *a, edge_t *b)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = strcmp(a->from.node->name, b->from.node->name);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
else
|
||||
return strcmp(a->to.node->name, b->to.node->name);
|
||||
}
|
||||
|
||||
/* Evil edge_compare() from a parallel universe ;)
|
||||
|
||||
int edge_compare(edge_t *a, edge_t *b)
|
||||
{
|
||||
int result;
|
||||
|
||||
return (result = strcmp(a->from.node->name, b->from.node->name)) || (result = strcmp(a->to.node->name, b->to.node->name)), result;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
int edge_name_compare(edge_t *a, edge_t *b)
|
||||
{
|
||||
int result;
|
||||
char *name_a1, *name_a2, *name_b1, *name_b2;
|
||||
|
||||
if(strcmp(a->from.node->name, a->to.node->name) < 0)
|
||||
name_a1 = a->from.node->name, name_a2 = a->to.node->name;
|
||||
else
|
||||
name_a1 = a->to.node->name, name_a2 = a->from.node->name;
|
||||
|
||||
if(strcmp(b->from.node->name, b->to.node->name) < 0)
|
||||
name_b1 = b->from.node->name, name_b2 = b->to.node->name;
|
||||
else
|
||||
name_b1 = b->to.node->name, name_b2 = b->from.node->name;
|
||||
|
||||
result = strcmp(name_a1, name_b1);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
else
|
||||
return strcmp(name_a2, name_b2);
|
||||
}
|
||||
|
||||
int edge_weight_compare(edge_t *a, edge_t *b)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = a->weight - b->weight;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
else
|
||||
return edge_name_compare(a, b);
|
||||
}
|
||||
|
||||
void init_edges(void)
|
||||
{
|
||||
cp
|
||||
edge_tree = avl_alloc_tree((avl_compare_t)edge_compare, NULL);
|
||||
edge_weight_tree = avl_alloc_tree((avl_compare_t)edge_weight_compare, NULL);
|
||||
cp
|
||||
}
|
||||
|
||||
avl_tree_t *new_edge_tree(void)
|
||||
{
|
||||
cp
|
||||
return avl_alloc_tree((avl_compare_t)edge_name_compare, NULL);
|
||||
cp
|
||||
}
|
||||
|
||||
void free_edge_tree(avl_tree_t *edge_tree)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(edge_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
void exit_edges(void)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(edge_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
/* Creation and deletion of connection elements */
|
||||
|
||||
edge_t *new_edge(void)
|
||||
{
|
||||
edge_t *e;
|
||||
cp
|
||||
e = (edge_t *)xmalloc_and_zero(sizeof(*e));
|
||||
cp
|
||||
return e;
|
||||
}
|
||||
|
||||
void free_edge(edge_t *e)
|
||||
{
|
||||
cp
|
||||
free(e);
|
||||
cp
|
||||
}
|
||||
|
||||
void edge_add(edge_t *e)
|
||||
{
|
||||
cp
|
||||
avl_insert(edge_tree, e);
|
||||
avl_insert(edge_weight_tree, e);
|
||||
avl_insert(e->from.node->edge_tree, e);
|
||||
avl_insert(e->to.node->edge_tree, e);
|
||||
cp
|
||||
}
|
||||
|
||||
void edge_del(edge_t *e)
|
||||
{
|
||||
cp
|
||||
avl_delete(edge_tree, e);
|
||||
avl_delete(edge_weight_tree, e);
|
||||
avl_delete(e->from.node->edge_tree, e);
|
||||
avl_delete(e->to.node->edge_tree, e);
|
||||
cp
|
||||
}
|
||||
|
||||
edge_t *lookup_edge(node_t *from, node_t *to)
|
||||
{
|
||||
edge_t v, *result;
|
||||
cp
|
||||
v.from.node = from;
|
||||
v.to.node = to;
|
||||
|
||||
result = avl_search(edge_tree, &v);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
cp
|
||||
v.from.node = to;
|
||||
v.to.node = from;
|
||||
|
||||
return avl_search(edge_tree, &v);
|
||||
}
|
||||
|
||||
void dump_edges(void)
|
||||
{
|
||||
avl_node_t *node;
|
||||
edge_t *e;
|
||||
char *from_udp, *to_udp;
|
||||
cp
|
||||
syslog(LOG_DEBUG, _("Edges:"));
|
||||
|
||||
for(node = edge_tree->head; node; node = node->next)
|
||||
{
|
||||
e = (edge_t *)node->data;
|
||||
from_udp = sockaddr2hostname(&e->from.udpaddress);
|
||||
to_udp = sockaddr2hostname(&e->to.udpaddress);
|
||||
syslog(LOG_DEBUG, _(" %s at %s - %s at %s options %lx weight %d"),
|
||||
e->from.node->name, from_udp,
|
||||
e->to.node->name, to_udp,
|
||||
e->options, e->weight);
|
||||
free(from_udp);
|
||||
free(to_udp);
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, _("End of edges."));
|
||||
cp
|
||||
}
|
||||
64
lib/edge.h
64
lib/edge.h
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
edge.h -- header for edge.c
|
||||
Copyright (C) 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2001-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: edge.h,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_EDGE_H__
|
||||
#define __TINC_EDGE_H__
|
||||
|
||||
#include <avl_tree.h>
|
||||
|
||||
#include "net.h"
|
||||
#include "node.h"
|
||||
#include "connection.h"
|
||||
|
||||
typedef struct halfconnection_t {
|
||||
struct node_t *node; /* node associated with this end of the connection */
|
||||
/* sockaddr_t tcpaddress; */ /* real (internet) ip on this end of the meta connection */
|
||||
sockaddr_t udpaddress; /* real (internet) ip on this end of the vpn connection */
|
||||
} halfconnection_t;
|
||||
|
||||
typedef struct edge_t {
|
||||
struct halfconnection_t from;
|
||||
struct halfconnection_t to;
|
||||
|
||||
long int options; /* options turned on for this edge */
|
||||
int weight; /* weight of this edge */
|
||||
|
||||
struct connection_t *connection; /* connection associated with this edge, if available */
|
||||
|
||||
void *if_data; /* Interface data */
|
||||
} edge_t;
|
||||
|
||||
extern avl_tree_t *edge_tree; /* Tree with all known edges (replaces active_tree) */
|
||||
extern avl_tree_t *edge_weight_tree; /* Tree with all known edges sorted on weight */
|
||||
|
||||
extern void init_edges(void);
|
||||
extern void exit_edges(void);
|
||||
extern edge_t *new_edge(void);
|
||||
extern void free_edge(edge_t *);
|
||||
extern avl_tree_t *new_edge_tree(void);
|
||||
extern void free_edge_tree(avl_tree_t *);
|
||||
extern void edge_add(edge_t *);
|
||||
extern void edge_del(edge_t *);
|
||||
extern edge_t *lookup_edge(struct node_t *, struct node_t *);
|
||||
extern void dump_edges(void);
|
||||
|
||||
#endif /* __TINC_EDGE_H__ */
|
||||
60
lib/error.c
60
lib/error.c
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
error.c -- generalized error handling
|
||||
Copyright (C) 2000 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: error.c,v 1.1 2000/10/19 20:56:49 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
# include <syslog.h>
|
||||
#endif
|
||||
|
||||
#include <error.h>
|
||||
#include <system.h>
|
||||
|
||||
void error(int severity, const char *message, ...)
|
||||
{
|
||||
va_list v;
|
||||
extern int detached;
|
||||
|
||||
va_start(v, message);
|
||||
|
||||
#ifdef HAVE_SYSLOG
|
||||
if(detached)
|
||||
{
|
||||
syslog(LOG_ERR, _(message), v);
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_SYSLOG */
|
||||
{
|
||||
vfprintf(stderr, _(message), v);
|
||||
fputs("\n", stderr);
|
||||
}
|
||||
va_end(v);
|
||||
|
||||
if(severity | ERR_FATAL)
|
||||
exit(1);
|
||||
}
|
||||
34
lib/error.h
34
lib/error.h
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
error.h -- header file for error.h
|
||||
Copyright (C) 2000 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: error.h,v 1.1 2000/10/19 20:56:49 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_ERROR_H__
|
||||
#define __TINC_ERROR_H__
|
||||
|
||||
#define ERR_IGNORE 00000 /* Ignore this error */
|
||||
#define ERR_FATAL 00001 /* Terminate program */
|
||||
#define ERR_UNLOAD 00002 /* Unload associated module */
|
||||
#define ERR_WARNING 01000 /* Warning message only */
|
||||
#define ERR_DEBUG 04000 /* Debug message */
|
||||
|
||||
extern void error(int severity, const char *message, ...);
|
||||
|
||||
#endif /* __TINC_ERROR_H__ */
|
||||
75
lib/ethernet.h
Normal file
75
lib/ethernet.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
ethernet.h -- missing Ethernet related definitions
|
||||
Copyright (C) 2003 Ivo Timmermans <ivo@o2w.nl>
|
||||
2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: ethernet.h,v 1.2 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_ETHERNET_H__
|
||||
#define __TINC_ETHERNET_H__
|
||||
|
||||
#ifndef ETH_ALEN
|
||||
#define ETH_ALEN 6
|
||||
#endif
|
||||
|
||||
#ifndef ETHER_ADDR_LEN
|
||||
#define ETHER_ADDR_LEN 6
|
||||
#endif
|
||||
|
||||
#ifndef ARPHRD_ETHER
|
||||
#define ARPHRD_ETHER 1
|
||||
#endif
|
||||
|
||||
#ifndef ETHERTYPE_IP
|
||||
#define ETHERTYPE_IP 0x0800
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ARPHDR
|
||||
struct arphdr {
|
||||
unsigned short int ar_hrd;
|
||||
unsigned short int ar_pro;
|
||||
unsigned char ar_hln;
|
||||
unsigned char ar_pln;
|
||||
unsigned short int ar_op;
|
||||
};
|
||||
|
||||
#define ARPOP_REQUEST 1
|
||||
#define ARPOP_REPLY 2
|
||||
#define ARPOP_RREQUEST 3
|
||||
#define ARPOP_RREPLY 4
|
||||
#define ARPOP_InREQUEST 8
|
||||
#define ARPOP_InREPLY 9
|
||||
#define ARPOP_NAK 10
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ETHER_ARP
|
||||
struct ether_arp {
|
||||
struct arphdr ea_hdr;
|
||||
uint8_t arp_sha[ETH_ALEN];
|
||||
uint8_t arp_spa[4];
|
||||
uint8_t arp_tha[ETH_ALEN];
|
||||
uint8_t arp_tpa[4];
|
||||
};
|
||||
#define arp_hrd ea_hdr.ar_hrd
|
||||
#define arp_pro ea_hdr.ar_pro
|
||||
#define arp_hln ea_hdr.ar_hln
|
||||
#define arp_pln ea_hdr.ar_pln
|
||||
#define arp_op ea_hdr.ar_op
|
||||
#endif
|
||||
|
||||
#endif /* __TINC_ETHERNET_H__ */
|
||||
110
lib/event.c
110
lib/event.c
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
event.c -- event queue
|
||||
Copyright (C) 2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: event.c,v 1.1 2002/05/02 13:11:55 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <xalloc.h>
|
||||
#include <string.h>
|
||||
#include <utils.h>
|
||||
#include <avl_tree.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "event.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
avl_tree_t *event_tree;
|
||||
extern time_t now;
|
||||
|
||||
int id;
|
||||
|
||||
int event_compare(event_t *a, event_t *b)
|
||||
{
|
||||
if(a->time > b->time)
|
||||
return 1;
|
||||
if(a->time < b->time)
|
||||
return -1;
|
||||
return a->id - b->id;
|
||||
}
|
||||
|
||||
void init_events(void)
|
||||
{
|
||||
cp
|
||||
event_tree = avl_alloc_tree((avl_compare_t)event_compare, NULL);
|
||||
cp
|
||||
}
|
||||
|
||||
void exit_events(void)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(event_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
event_t *new_event(void)
|
||||
{
|
||||
event_t *event;
|
||||
cp
|
||||
event = (event_t *)xmalloc_and_zero(sizeof(*event));
|
||||
cp
|
||||
return event;
|
||||
}
|
||||
|
||||
void free_event(event_t *event)
|
||||
{
|
||||
cp
|
||||
free(event);
|
||||
cp
|
||||
}
|
||||
|
||||
void event_add(event_t *event)
|
||||
{
|
||||
cp
|
||||
event->id = ++id;
|
||||
avl_insert(event_tree, event);
|
||||
cp
|
||||
}
|
||||
|
||||
void event_del(event_t *event)
|
||||
{
|
||||
cp
|
||||
avl_delete(event_tree, event);
|
||||
cp
|
||||
}
|
||||
|
||||
event_t *get_expired_event(void)
|
||||
{
|
||||
event_t *event;
|
||||
cp
|
||||
if(event_tree->head)
|
||||
{
|
||||
event = (event_t *)event_tree->head->data;
|
||||
if(event->time < now)
|
||||
{
|
||||
avl_delete(event_tree, event);
|
||||
return event;
|
||||
}
|
||||
}
|
||||
cp
|
||||
return NULL;
|
||||
}
|
||||
48
lib/event.h
48
lib/event.h
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
event.h -- header for event.c
|
||||
Copyright (C) 2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: event.h,v 1.1 2002/05/02 13:11:55 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_EVENT_H__
|
||||
#define __TINC_EVENT_H__
|
||||
|
||||
#include <time.h>
|
||||
#include <avl_tree.h>
|
||||
|
||||
avl_tree_t *event_tree;
|
||||
|
||||
typedef void (*event_handler_t)(void *);
|
||||
|
||||
typedef struct {
|
||||
time_t time;
|
||||
int id;
|
||||
event_handler_t handler;
|
||||
void *data;
|
||||
} event_t;
|
||||
|
||||
extern void init_events(void);
|
||||
extern void exit_events(void);
|
||||
extern event_t *new_event(void);
|
||||
extern void free_event(event_t *);
|
||||
extern void event_add(event_t *);
|
||||
extern void event_del(event_t *);
|
||||
extern event_t *get_expired_event(void);
|
||||
|
||||
#endif /* __TINC_EVENT_H__ */
|
||||
15
lib/fake-gai-errnos.h
Normal file
15
lib/fake-gai-errnos.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* fake library for ssh
|
||||
*
|
||||
* This file is included in getaddrinfo.c and getnameinfo.c.
|
||||
* See getaddrinfo.c and getnameinfo.c.
|
||||
*/
|
||||
|
||||
/* $Id: fake-gai-errnos.h,v 1.2 2003/08/24 20:38:20 guus Exp $ */
|
||||
|
||||
/* for old netdb.h */
|
||||
#ifndef EAI_NODATA
|
||||
#define EAI_NODATA 1
|
||||
#define EAI_MEMORY 2
|
||||
#define EAI_FAMILY 3
|
||||
#endif
|
||||
104
lib/fake-getaddrinfo.c
Normal file
104
lib/fake-getaddrinfo.c
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* fake library for ssh
|
||||
*
|
||||
* This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
|
||||
* These funtions are defined in rfc2133.
|
||||
*
|
||||
* But these functions are not implemented correctly. The minimum subset
|
||||
* is implemented for ssh use only. For exapmle, this routine assumes
|
||||
* that ai_family is AF_INET. Don't use it for another purpose.
|
||||
*/
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "ipv4.h"
|
||||
#include "ipv6.h"
|
||||
#include "fake-getaddrinfo.h"
|
||||
|
||||
#ifndef HAVE_GAI_STRERROR
|
||||
char *gai_strerror(int ecode)
|
||||
{
|
||||
switch (ecode) {
|
||||
case EAI_NODATA:
|
||||
return "No address associated with hostname";
|
||||
case EAI_MEMORY:
|
||||
return "Memory allocation failure";
|
||||
case EAI_FAMILY:
|
||||
return "Address family not supported";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
}
|
||||
#endif /* !HAVE_GAI_STRERROR */
|
||||
|
||||
#ifndef HAVE_FREEADDRINFO
|
||||
void freeaddrinfo(struct addrinfo *ai)
|
||||
{
|
||||
struct addrinfo *next;
|
||||
|
||||
while(ai) {
|
||||
next = ai->ai_next;
|
||||
free(ai);
|
||||
ai = next;
|
||||
}
|
||||
}
|
||||
#endif /* !HAVE_FREEADDRINFO */
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
static struct addrinfo *malloc_ai(uint16_t port, uint32_t addr)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
|
||||
ai = xmalloc_and_zero(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
|
||||
|
||||
ai->ai_addr = (struct sockaddr *)(ai + 1);
|
||||
ai->ai_addrlen = sizeof(struct sockaddr_in);
|
||||
ai->ai_addr->sa_family = ai->ai_family = AF_INET;
|
||||
|
||||
((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
|
||||
((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
|
||||
{
|
||||
struct addrinfo *prev = NULL;
|
||||
struct hostent *hp;
|
||||
struct in_addr in = {0};
|
||||
int i;
|
||||
uint16_t port = 0;
|
||||
|
||||
if(hints && hints->ai_family != AF_INET && hints->ai_family != AF_UNSPEC)
|
||||
return EAI_FAMILY;
|
||||
|
||||
if (servname)
|
||||
port = htons(atoi(servname));
|
||||
|
||||
if (hints && hints->ai_flags & AI_PASSIVE) {
|
||||
*res = malloc_ai(port, htonl(0x00000000));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hostname) {
|
||||
*res = malloc_ai(port, htonl(0x7f000001));
|
||||
return 0;
|
||||
}
|
||||
|
||||
hp = gethostbyname(hostname);
|
||||
|
||||
if(!hp || !hp->h_addr_list || !hp->h_addr_list[0])
|
||||
return EAI_NODATA;
|
||||
|
||||
for (i = 0; hp->h_addr_list[i]; i++) {
|
||||
*res = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr);
|
||||
|
||||
if(prev)
|
||||
prev->ai_next = *res;
|
||||
|
||||
prev = *res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !HAVE_GETADDRINFO */
|
||||
49
lib/fake-getaddrinfo.h
Normal file
49
lib/fake-getaddrinfo.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/* $Id: fake-getaddrinfo.h,v 1.2 2003/08/24 20:38:20 guus Exp $ */
|
||||
|
||||
#ifndef _FAKE_GETADDRINFO_H
|
||||
#define _FAKE_GETADDRINFO_H
|
||||
|
||||
#include "fake-gai-errnos.h"
|
||||
|
||||
#ifndef AI_PASSIVE
|
||||
# define AI_PASSIVE 1
|
||||
# define AI_CANONNAME 2
|
||||
#endif
|
||||
|
||||
#ifndef NI_NUMERICHOST
|
||||
# define NI_NUMERICHOST 2
|
||||
# define NI_NAMEREQD 4
|
||||
# define NI_NUMERICSERV 8
|
||||
#endif
|
||||
|
||||
#ifndef AI_NUMERICHOST
|
||||
#define AI_NUMERICHOST 4
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ADDRINFO
|
||||
struct addrinfo {
|
||||
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
|
||||
int ai_family; /* PF_xxx */
|
||||
int ai_socktype; /* SOCK_xxx */
|
||||
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
|
||||
size_t ai_addrlen; /* length of ai_addr */
|
||||
char *ai_canonname; /* canonical name for hostname */
|
||||
struct sockaddr *ai_addr; /* binary address */
|
||||
struct addrinfo *ai_next; /* next structure in linked list */
|
||||
};
|
||||
#endif /* !HAVE_STRUCT_ADDRINFO */
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
int getaddrinfo(const char *hostname, const char *servname,
|
||||
const struct addrinfo *hints, struct addrinfo **res);
|
||||
#endif /* !HAVE_GETADDRINFO */
|
||||
|
||||
#ifndef HAVE_GAI_STRERROR
|
||||
char *gai_strerror(int ecode);
|
||||
#endif /* !HAVE_GAI_STRERROR */
|
||||
|
||||
#ifndef HAVE_FREEADDRINFO
|
||||
void freeaddrinfo(struct addrinfo *ai);
|
||||
#endif /* !HAVE_FREEADDRINFO */
|
||||
|
||||
#endif /* _FAKE_GETADDRINFO_H */
|
||||
55
lib/fake-getnameinfo.c
Normal file
55
lib/fake-getnameinfo.c
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* fake library for ssh
|
||||
*
|
||||
* This file includes getnameinfo().
|
||||
* These funtions are defined in rfc2133.
|
||||
*
|
||||
* But these functions are not implemented correctly. The minimum subset
|
||||
* is implemented for ssh use only. For exapmle, this routine assumes
|
||||
* that ai_family is AF_INET. Don't use it for another purpose.
|
||||
*/
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "fake-getnameinfo.h"
|
||||
#include "fake-getaddrinfo.h"
|
||||
|
||||
#ifndef HAVE_GETNAMEINFO
|
||||
|
||||
int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags)
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
struct hostent *hp;
|
||||
int len;
|
||||
|
||||
if(sa->sa_family != AF_INET)
|
||||
return EAI_FAMILY;
|
||||
|
||||
if(serv && servlen) {
|
||||
len = snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
|
||||
if(len < 0 || len >= servlen)
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
if(!host || !hostlen)
|
||||
return 0;
|
||||
|
||||
if(flags & NI_NUMERICHOST) {
|
||||
len = snprintf(host, hostlen, "%s", inet_ntoa(sin->sin_addr));
|
||||
if(len < 0 || len >= hostlen)
|
||||
return EAI_MEMORY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr), AF_INET);
|
||||
|
||||
if(!hp || !hp->h_name || !hp->h_name[0])
|
||||
return EAI_NODATA;
|
||||
|
||||
len = snprintf(host, hostlen, "%s", hp->h_name);
|
||||
if(len < 0 || len >= hostlen)
|
||||
return EAI_MEMORY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !HAVE_GETNAMEINFO */
|
||||
18
lib/fake-getnameinfo.h
Normal file
18
lib/fake-getnameinfo.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/* $Id: fake-getnameinfo.h,v 1.2 2003/08/24 20:38:20 guus Exp $ */
|
||||
|
||||
#ifndef _FAKE_GETNAMEINFO_H
|
||||
#define _FAKE_GETNAMEINFO_H
|
||||
|
||||
#ifndef HAVE_GETNAMEINFO
|
||||
int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
|
||||
size_t hostlen, char *serv, size_t servlen, int flags);
|
||||
#endif /* !HAVE_GETNAMEINFO */
|
||||
|
||||
#ifndef NI_MAXSERV
|
||||
# define NI_MAXSERV 32
|
||||
#endif /* !NI_MAXSERV */
|
||||
#ifndef NI_MAXHOST
|
||||
# define NI_MAXHOST 1025
|
||||
#endif /* !NI_MAXHOST */
|
||||
|
||||
#endif /* _FAKE_GETNAMEINFO_H */
|
||||
13
lib/getopt.c
13
lib/getopt.c
|
|
@ -85,16 +85,7 @@ USA. */
|
|||
#define getpid() GetCurrentProcessId()
|
||||
#endif
|
||||
|
||||
#ifndef _
|
||||
/* This is for other GNU distributions with internationalized messages.
|
||||
When compiling libc, the _ macro is predefined. */
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
# define _(msgid) gettext (msgid)
|
||||
#else
|
||||
# define _(msgid) (msgid)
|
||||
#endif
|
||||
#endif
|
||||
#include "gettext.h"
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
|
|
@ -268,7 +259,7 @@ extern pid_t __libc_pid;
|
|||
is valid for the getopt call we must make sure that the ARGV passed
|
||||
to getopt is that one passed to the process. */
|
||||
static void
|
||||
__attribute__ ((unused))
|
||||
__attribute__ ((__unused__))
|
||||
store_args_and_env (int argc, char *const *argv)
|
||||
{
|
||||
/* XXX This is no good solution. We should rather copy the args so
|
||||
|
|
|
|||
79
lib/gettext.h
Normal file
79
lib/gettext.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/* Convenience header for conditional use of GNU <libintl.h>.
|
||||
Copyright (C) 1995-1998, 2000-2003 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public License as published
|
||||
by the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
USA. */
|
||||
|
||||
#ifndef _LIBGETTEXT_H
|
||||
#define _LIBGETTEXT_H 1
|
||||
|
||||
/* NLS can be disabled through the configure --disable-nls option. */
|
||||
#if ENABLE_NLS
|
||||
|
||||
/* Get declarations of GNU message catalog functions. */
|
||||
# include <libintl.h>
|
||||
# include <locale.h>
|
||||
|
||||
/* Shorthand notation */
|
||||
|
||||
# define _(Text) gettext (Text)
|
||||
|
||||
#else
|
||||
|
||||
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
|
||||
chokes if dcgettext is defined as a macro. So include it now, to make
|
||||
later inclusions of <locale.h> a NOP. We don't include <libintl.h>
|
||||
as well because people using "gettext.h" will not include <libintl.h>,
|
||||
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
|
||||
is OK. */
|
||||
#if defined(__sun)
|
||||
# include <locale.h>
|
||||
#endif
|
||||
|
||||
/* Disabled NLS.
|
||||
The casts to 'const char *' serve the purpose of producing warnings
|
||||
for invalid uses of the value returned from these functions.
|
||||
On pre-ANSI systems without 'const', the config.h file is supposed to
|
||||
contain "#define const". */
|
||||
# define gettext(Msgid) ((const char *) (Msgid))
|
||||
# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
|
||||
# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
|
||||
# define ngettext(Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define dngettext(Domainname, Msgid1, Msgid2, N) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
|
||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||
# define textdomain(Domainname) ((const char *) (Domainname))
|
||||
# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
|
||||
# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
|
||||
|
||||
# define _(Text) Text
|
||||
# define setlocale(Category, Locale) ((const char *) (Locale))
|
||||
|
||||
#endif
|
||||
|
||||
/* A pseudo function call that serves as a marker for the automated
|
||||
extraction of messages, but does not call gettext(). The run-time
|
||||
translation is done at a different place in the code.
|
||||
The argument, String, should be a literal string. Concatenated strings
|
||||
and other string expressions won't work.
|
||||
The macro's expansion is not parenthesized, so that it is suitable as
|
||||
initializer for static 'char[]' or 'const char[]' variables. */
|
||||
#define gettext_noop(String) String
|
||||
|
||||
#define N_(Text) Text
|
||||
|
||||
#endif /* _LIBGETTEXT_H */
|
||||
285
lib/graph.c
285
lib/graph.c
|
|
@ -1,285 +0,0 @@
|
|||
/*
|
||||
graph.c -- graph algorithms
|
||||
Copyright (C) 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2001-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: graph.c,v 1.1 2002/05/02 11:50:07 zarq Exp $
|
||||
*/
|
||||
|
||||
/* We need to generate two trees from the graph:
|
||||
|
||||
1. A minimum spanning tree for broadcasts,
|
||||
2. A single-source shortest path tree for unicasts.
|
||||
|
||||
Actually, the first one alone would suffice but would make unicast packets
|
||||
take longer routes than necessary.
|
||||
|
||||
For the MST algorithm we can choose from Prim's or Kruskal's. I personally
|
||||
favour Kruskal's, because we make an extra AVL tree of edges sorted on
|
||||
weights (metric). That tree only has to be updated when an edge is added or
|
||||
removed, and during the MST algorithm we just have go linearly through that
|
||||
tree, adding safe edges until #edges = #nodes - 1. The implementation here
|
||||
however is not so fast, because I tried to avoid having to make a forest and
|
||||
merge trees.
|
||||
|
||||
For the SSSP algorithm Dijkstra's seems to be a nice choice. Currently a
|
||||
simple breadth-first search is presented here.
|
||||
|
||||
The SSSP algorithm will also be used to determine whether nodes are directly,
|
||||
indirectly or not reachable from the source. It will also set the correct
|
||||
destination address and port of a node if possible.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined(HAVE_FREEBSD) || defined(HAVE_OPENBSD)
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
#include <hooks.h>
|
||||
#include <utils.h>
|
||||
|
||||
#include "netutl.h"
|
||||
#include "node.h"
|
||||
#include "edge.h"
|
||||
#include "connection.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
/* Implementation of Kruskal's algorithm.
|
||||
Running time: O(EN)
|
||||
Please note that sorting on weight is already done by add_edge().
|
||||
*/
|
||||
|
||||
void mst_kruskal(void)
|
||||
{
|
||||
avl_node_t *node, *next;
|
||||
edge_t *e;
|
||||
node_t *n;
|
||||
connection_t *c;
|
||||
int nodes = 0;
|
||||
int safe_edges = 0;
|
||||
int skipped;
|
||||
|
||||
/* Clear MST status on connections */
|
||||
|
||||
for(node = connection_tree->head; node; node = node->next)
|
||||
{
|
||||
c = (connection_t *)node->data;
|
||||
c->status.mst = 0;
|
||||
}
|
||||
|
||||
/* Do we have something to do at all? */
|
||||
|
||||
if(!edge_weight_tree->head)
|
||||
return;
|
||||
|
||||
if(debug_lvl >= DEBUG_SCARY_THINGS)
|
||||
syslog(LOG_DEBUG, "Running Kruskal's algorithm:");
|
||||
|
||||
/* Clear visited status on nodes */
|
||||
|
||||
for(node = node_tree->head; node; node = node->next)
|
||||
{
|
||||
n = (node_t *)node->data;
|
||||
n->status.visited = 0;
|
||||
nodes++;
|
||||
}
|
||||
|
||||
/* Starting point */
|
||||
|
||||
((edge_t *)edge_weight_tree->head->data)->from.node->status.visited = 1;
|
||||
|
||||
/* Add safe edges */
|
||||
|
||||
for(skipped = 0, node = edge_weight_tree->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
e = (edge_t *)node->data;
|
||||
|
||||
if(e->from.node->status.visited == e->to.node->status.visited)
|
||||
{
|
||||
skipped = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
e->from.node->status.visited = 1;
|
||||
e->to.node->status.visited = 1;
|
||||
if(e->connection)
|
||||
e->connection->status.mst = 1;
|
||||
|
||||
safe_edges++;
|
||||
|
||||
if(debug_lvl >= DEBUG_SCARY_THINGS)
|
||||
syslog(LOG_DEBUG, " Adding edge %s - %s weight %d", e->from.node->name, e->to.node->name, e->weight);
|
||||
|
||||
if(skipped)
|
||||
{
|
||||
next = edge_weight_tree->head;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(debug_lvl >= DEBUG_SCARY_THINGS)
|
||||
syslog(LOG_DEBUG, "Done, counted %d nodes and %d safe edges.", nodes, safe_edges);
|
||||
}
|
||||
|
||||
/* Implementation of a simple breadth-first search algorithm.
|
||||
Running time: O(E)
|
||||
*/
|
||||
|
||||
void sssp_bfs(void)
|
||||
{
|
||||
avl_node_t *node, *from, *next, *to;
|
||||
edge_t *e;
|
||||
node_t *n;
|
||||
halfconnection_t to_hc, from_hc;
|
||||
avl_tree_t *todo_tree;
|
||||
int indirect;
|
||||
|
||||
todo_tree = avl_alloc_tree(NULL, NULL);
|
||||
|
||||
/* Clear visited status on nodes */
|
||||
|
||||
for(node = node_tree->head; node; node = node->next)
|
||||
{
|
||||
n = (node_t *)node->data;
|
||||
n->status.visited = 0;
|
||||
n->status.indirect = 1;
|
||||
}
|
||||
|
||||
/* Begin with myself */
|
||||
|
||||
myself->status.visited = 1;
|
||||
myself->status.indirect = 0;
|
||||
myself->nexthop = myself;
|
||||
myself->via = myself;
|
||||
node = avl_alloc_node();
|
||||
node->data = myself;
|
||||
avl_insert_top(todo_tree, node);
|
||||
|
||||
/* Loop while todo_tree is filled */
|
||||
|
||||
while(todo_tree->head)
|
||||
{
|
||||
for(from = todo_tree->head; from; from = next) /* "from" is the node from which we start */
|
||||
{
|
||||
next = from->next;
|
||||
n = (node_t *)from->data;
|
||||
|
||||
for(to = n->edge_tree->head; to; to = to->next) /* "to" is the edge connected to "from" */
|
||||
{
|
||||
e = (edge_t *)to->data;
|
||||
|
||||
if(e->from.node == n) /* "from_hc" is the halfconnection with .node == from */
|
||||
to_hc = e->to, from_hc = e->from;
|
||||
else
|
||||
to_hc = e->from, from_hc = e->to;
|
||||
|
||||
/* Situation:
|
||||
|
||||
/
|
||||
/
|
||||
------(n)from_hc-----to_hc
|
||||
\
|
||||
\
|
||||
|
||||
n->address is set to the to_hc.udpaddress of the edge left of n.
|
||||
We are currently examining the edge right of n:
|
||||
|
||||
- If from_hc.udpaddress != n->address, then to_hc.node is probably
|
||||
not reachable for the nodes left of n. We do as if the indirectdata
|
||||
flag is set on edge e.
|
||||
- If edge e provides for better reachability of to_hc.node, update
|
||||
to_hc.node and (re)add it to the todo_tree to (re)examine the reachability
|
||||
of nodes behind it.
|
||||
*/
|
||||
|
||||
indirect = n->status.indirect || e->options & OPTION_INDIRECT || ((n != myself) && sockaddrcmp(&n->address, &from_hc.udpaddress));
|
||||
|
||||
if(to_hc.node->status.visited && (!to_hc.node->status.indirect || indirect))
|
||||
continue;
|
||||
|
||||
to_hc.node->status.visited = 1;
|
||||
to_hc.node->status.indirect = indirect;
|
||||
to_hc.node->nexthop = (n->nexthop == myself) ? to_hc.node : n->nexthop;
|
||||
to_hc.node->via = indirect ? n->via : to_hc.node;
|
||||
to_hc.node->options = e->options;
|
||||
if(sockaddrcmp(&to_hc.node->address, &to_hc.udpaddress))
|
||||
{
|
||||
node = avl_unlink(node_udp_tree, to_hc.node);
|
||||
to_hc.node->address = to_hc.udpaddress;
|
||||
if(to_hc.node->hostname)
|
||||
free(to_hc.node->hostname);
|
||||
to_hc.node->hostname = sockaddr2hostname(&to_hc.udpaddress);
|
||||
avl_insert_node(node_udp_tree, node);
|
||||
}
|
||||
node = avl_alloc_node();
|
||||
node->data = to_hc.node;
|
||||
avl_insert_before(todo_tree, from, node);
|
||||
}
|
||||
|
||||
avl_delete_node(todo_tree, from);
|
||||
}
|
||||
}
|
||||
|
||||
avl_free_tree(todo_tree);
|
||||
|
||||
/* Check reachability status. */
|
||||
|
||||
for(node = node_tree->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
n = (node_t *)node->data;
|
||||
|
||||
if(n->status.visited)
|
||||
{
|
||||
if(!n->status.reachable)
|
||||
{
|
||||
if(debug_lvl >= DEBUG_TRAFFIC)
|
||||
syslog(LOG_DEBUG, _("Node %s (%s) became reachable"), n->name, n->hostname);
|
||||
n->status.reachable = 1;
|
||||
run_hooks("node-visible", n);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(n->status.reachable)
|
||||
{
|
||||
if(debug_lvl >= DEBUG_TRAFFIC)
|
||||
syslog(LOG_DEBUG, _("Node %s (%s) became unreachable"), n->name, n->hostname);
|
||||
n->status.reachable = 0;
|
||||
n->status.validkey = 0;
|
||||
n->status.waitingforkey = 0;
|
||||
n->sent_seqno = 0;
|
||||
run_hooks("node-invisible", n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void graph(void)
|
||||
{
|
||||
mst_kruskal();
|
||||
sssp_bfs();
|
||||
}
|
||||
25
lib/graph.h
25
lib/graph.h
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
graph.h -- header for graph.c
|
||||
Copyright (C) 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2001-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: graph.h,v 1.1 2002/05/02 11:50:07 zarq Exp $
|
||||
*/
|
||||
|
||||
extern void graph(void);
|
||||
extern void mst_kruskal(void);
|
||||
extern void sssp_bfs(void);
|
||||
56
lib/hash.c
56
lib/hash.c
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
hash.c -- Handle hash datastructures
|
||||
Copyright (C) 2000 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: hash.c,v 1.1 2000/10/20 16:44:32 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
hash_delete
|
||||
delete one element, indicated by key, from hash
|
||||
*/
|
||||
int hash_delete(hash_t hash, char *key)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
hash_insert_maybe
|
||||
insert an element into the hash, unless an element with the
|
||||
same key already exists.
|
||||
*/
|
||||
int hash_insert_maybe(hash_t hash, void *data, char *key)
|
||||
{
|
||||
if(hash_retrieve(hash, key))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
hash_insert_or_update
|
||||
|
||||
If an element indicated by key exists in the hash, update the
|
||||
associated pointer. Otherwise, insert this pointer as a new
|
||||
element.
|
||||
*/
|
||||
int hash_insert_or_update(hash_t hash, void *data, char *key)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1 +0,0 @@
|
|||
/* */
|
||||
34
lib/hooks.h
34
lib/hooks.h
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
hooks.h -- header file for hooks.c
|
||||
Copyright (C) 2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2002 Ivo Timmermans <ivo@o2w.nl>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: hooks.h,v 1.2 2002/05/07 14:48:41 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_HOOKS_H__
|
||||
#define __TINC_HOOKS_H__
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef void (hook_function_t)(const char*,va_list);
|
||||
|
||||
void run_hooks(const char *type, ...);
|
||||
void add_hook(const char *type, hook_function_t *hook);
|
||||
void del_hook(const char *type, hook_function_t *hook);
|
||||
|
||||
#endif /* __TINC_HOOKS_H__ */
|
||||
132
lib/ipv4.h
Normal file
132
lib/ipv4.h
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
ipv4.h -- missing IPv4 related definitions
|
||||
Copyright (C) 2003 Ivo Timmermans <ivo@o2w.nl>
|
||||
2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: ipv4.h,v 1.2 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_IPV4_H__
|
||||
#define __TINC_IPV4_H__
|
||||
|
||||
#ifndef AF_INET
|
||||
#define AF_INET 2
|
||||
#endif
|
||||
|
||||
#ifndef IPPROTO_ICMP
|
||||
#define IPPROTO_ICMP 1
|
||||
#endif
|
||||
|
||||
#ifndef ICMP_DEST_UNREACH
|
||||
#define ICMP_DEST_UNREACH 3
|
||||
#endif
|
||||
|
||||
#ifndef ICMP_NET_UNKNOWN
|
||||
#define ICMP_NET_UNKNOWN 6
|
||||
#endif
|
||||
|
||||
#ifndef ICMP_NET_UNREACH
|
||||
#define ICMP_NET_UNREACH 0
|
||||
#endif
|
||||
|
||||
#ifndef IP_MSS
|
||||
#define IP_MSS 576
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_IP
|
||||
struct ip {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int ip_hl:4;
|
||||
unsigned int ip_v:4;
|
||||
#else
|
||||
unsigned int ip_v:4;
|
||||
unsigned int ip_hl:4;
|
||||
#endif
|
||||
uint8_t ip_tos;
|
||||
uint16_t ip_len;
|
||||
uint16_t ip_id;
|
||||
uint16_t ip_off;
|
||||
#define IP_RF 0x8000
|
||||
#define IP_DF 0x4000
|
||||
#define IP_MF 0x2000
|
||||
#define IP_OFFMASK 0x1fff
|
||||
uint8_t ip_ttl;
|
||||
uint8_t ip_p;
|
||||
uint16_t ip_sum;
|
||||
struct in_addr ip_src, ip_dst;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ICMP
|
||||
struct icmp {
|
||||
uint8_t icmp_type;
|
||||
uint8_t icmp_code;
|
||||
uint16_t icmp_cksum;
|
||||
union {
|
||||
uint8_t ih_pptr;
|
||||
struct in_addr ih_gwaddr;
|
||||
struct ih_idseq {
|
||||
uint16_t icd_id;
|
||||
uint16_t icd_seq;
|
||||
} ih_idseq;
|
||||
uint32_t ih_void;
|
||||
|
||||
|
||||
struct ih_pmtu {
|
||||
uint16_t ipm_void;
|
||||
uint16_t ipm_nextmtu;
|
||||
} ih_pmtu;
|
||||
|
||||
struct ih_rtradv {
|
||||
uint8_t irt_num_addrs;
|
||||
uint8_t irt_wpa;
|
||||
uint16_t irt_lifetime;
|
||||
} ih_rtradv;
|
||||
} icmp_hun;
|
||||
#define icmp_pptr icmp_hun.ih_pptr
|
||||
#define icmp_gwaddr icmp_hun.ih_gwaddr
|
||||
#define icmp_id icmp_hun.ih_idseq.icd_id
|
||||
#define icmp_seq icmp_hun.ih_idseq.icd_seq
|
||||
#define icmp_void icmp_hun.ih_void
|
||||
#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
|
||||
#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
|
||||
#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
|
||||
#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
|
||||
#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
|
||||
union {
|
||||
struct {
|
||||
uint32_t its_otime;
|
||||
uint32_t its_rtime;
|
||||
uint32_t its_ttime;
|
||||
} id_ts;
|
||||
struct {
|
||||
struct ip idi_ip;
|
||||
} id_ip;
|
||||
uint32_t id_mask;
|
||||
uint8_t id_data[1];
|
||||
} icmp_dun;
|
||||
#define icmp_otime icmp_dun.id_ts.its_otime
|
||||
#define icmp_rtime icmp_dun.id_ts.its_rtime
|
||||
#define icmp_ttime icmp_dun.id_ts.its_ttime
|
||||
#define icmp_ip icmp_dun.id_ip.idi_ip
|
||||
#define icmp_radv icmp_dun.id_radv
|
||||
#define icmp_mask icmp_dun.id_mask
|
||||
#define icmp_data icmp_dun.id_data
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* __TINC_IPV4_H__ */
|
||||
120
lib/ipv6.h
Normal file
120
lib/ipv6.h
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
ipv6.h -- missing IPv6 related definitions
|
||||
Copyright (C) 2003 Ivo Timmermans <ivo@o2w.nl>
|
||||
2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: ipv6.h,v 1.2 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_IPV6_H__
|
||||
#define __TINC_IPV6_H__
|
||||
|
||||
#ifndef AF_INET6
|
||||
#define AF_INET6 10
|
||||
#endif
|
||||
|
||||
#ifndef IPPROTO_ICMPV6
|
||||
#define IPPROTO_ICMPV6 58
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_IN6_ADDR
|
||||
struct in6_addr {
|
||||
union {
|
||||
uint8_t u6_addr8[16];
|
||||
uint16_t u6_addr16[8];
|
||||
uint32_t u6_addr32[4];
|
||||
} in6_u;
|
||||
};
|
||||
#define s6_addr in6_u.u6_addr8
|
||||
#define s6_addr16 in6_u.u6_addr16
|
||||
#define s6_addr32 in6_u.u6_addr32
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_SOCKADDR_IN6
|
||||
struct sockaddr_in6 {
|
||||
uint16_t sin6_family;
|
||||
uint16_t sin6_port;
|
||||
uint32_t sin6_flowinfo;
|
||||
struct in6_addr sin6_addr;
|
||||
uint32_t sin6_scope_id;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef IN6_IS_ADDR_V4MAPPED
|
||||
#define IN6_IS_ADDR_V4MAPPED(a) \
|
||||
((((__const uint32_t *) (a))[0] == 0) \
|
||||
&& (((__const uint32_t *) (a))[1] == 0) \
|
||||
&& (((__const uint32_t *) (a))[2] == htonl (0xffff)))
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_IP6_HDR
|
||||
struct ip6_hdr {
|
||||
union {
|
||||
struct ip6_hdrctl {
|
||||
uint32_t ip6_un1_flow;
|
||||
uint16_t ip6_un1_plen;
|
||||
uint8_t ip6_un1_nxt;
|
||||
uint8_t ip6_un1_hlim;
|
||||
} ip6_un1;
|
||||
uint8_t ip6_un2_vfc;
|
||||
} ip6_ctlun;
|
||||
struct in6_addr ip6_src;
|
||||
struct in6_addr ip6_dst;
|
||||
};
|
||||
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
|
||||
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
|
||||
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
|
||||
#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
|
||||
#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
|
||||
#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ICMP6_HDR
|
||||
struct icmp6_hdr {
|
||||
uint8_t icmp6_type;
|
||||
uint8_t icmp6_code;
|
||||
uint16_t icmp6_cksum;
|
||||
union {
|
||||
uint32_t icmp6_un_data32[1];
|
||||
uint16_t icmp6_un_data16[2];
|
||||
uint8_t icmp6_un_data8[4];
|
||||
} icmp6_dataun;
|
||||
};
|
||||
#define ICMP6_DST_UNREACH_NOROUTE 0
|
||||
#define ICMP6_DST_UNREACH 1
|
||||
#define ICMP6_DST_UNREACH_ADDR 3
|
||||
#define ND_NEIGHBOR_SOLICIT 135
|
||||
#define ND_NEIGHBOR_ADVERT 136
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ND_NEIGHBOR_SOLICIT
|
||||
struct nd_neighbor_solicit {
|
||||
struct icmp6_hdr nd_ns_hdr;
|
||||
struct in6_addr nd_ns_target;
|
||||
};
|
||||
#define ND_OPT_SOURCE_LINKADDR 1
|
||||
#define ND_OPT_TARGET_LINKADDR 2
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRUCT_ND_OPT_HDR
|
||||
struct nd_opt_hdr {
|
||||
uint8_t nd_opt_type;
|
||||
uint8_t nd_opt_len;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* __TINC_IPV6_H__ */
|
||||
183
lib/list.c
183
lib/list.c
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
list.c -- functions to deal with double linked lists
|
||||
Copyright (C) 2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000,2001 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 2000-2003 Ivo Timmermans <ivo@o2w.nl>
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -17,181 +17,170 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: list.c,v 1.2 2002/04/09 15:26:00 zarq Exp $
|
||||
$Id: list.c,v 1.3 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <xalloc.h>
|
||||
#include <system.h>
|
||||
#include "system.h"
|
||||
|
||||
#include "list.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
/* (De)constructors */
|
||||
|
||||
list_t *list_alloc(list_action_t delete)
|
||||
{
|
||||
list_t *list;
|
||||
list_t *list;
|
||||
|
||||
list = xmalloc_and_zero(sizeof(list_t));
|
||||
list->delete = delete;
|
||||
list = xmalloc_and_zero(sizeof(list_t));
|
||||
list->delete = delete;
|
||||
|
||||
return list;
|
||||
return list;
|
||||
}
|
||||
|
||||
void list_free(list_t *list)
|
||||
{
|
||||
free(list);
|
||||
free(list);
|
||||
}
|
||||
|
||||
list_node_t *list_alloc_node(void)
|
||||
{
|
||||
list_node_t *node;
|
||||
|
||||
node = xmalloc_and_zero(sizeof(list_node_t));
|
||||
|
||||
return node;
|
||||
return (list_node_t *)xmalloc_and_zero(sizeof(list_node_t));
|
||||
}
|
||||
|
||||
void list_free_node(list_t *list, list_node_t *node)
|
||||
{
|
||||
if(node->data && list->delete)
|
||||
list->delete(node->data);
|
||||
|
||||
free(node);
|
||||
if(node->data && list->delete)
|
||||
list->delete(node->data);
|
||||
|
||||
free(node);
|
||||
}
|
||||
|
||||
/* Insertion and deletion */
|
||||
|
||||
list_node_t *list_insert_head(list_t *list, void *data)
|
||||
{
|
||||
list_node_t *node;
|
||||
|
||||
node = list_alloc_node();
|
||||
|
||||
node->data = data;
|
||||
node->prev = NULL;
|
||||
node->next = list->head;
|
||||
list->head = node;
|
||||
|
||||
if(node->next)
|
||||
node->next->prev = node;
|
||||
else
|
||||
list->tail = node;
|
||||
list_node_t *node;
|
||||
|
||||
list->count++;
|
||||
node = list_alloc_node();
|
||||
|
||||
return node;
|
||||
node->data = data;
|
||||
node->prev = NULL;
|
||||
node->next = list->head;
|
||||
list->head = node;
|
||||
|
||||
if(node->next)
|
||||
node->next->prev = node;
|
||||
else
|
||||
list->tail = node;
|
||||
|
||||
list->count++;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
list_node_t *list_insert_tail(list_t *list, void *data)
|
||||
{
|
||||
list_node_t *node;
|
||||
|
||||
node = list_alloc_node();
|
||||
|
||||
node->data = data;
|
||||
node->next = NULL;
|
||||
node->prev = list->tail;
|
||||
list->tail = node;
|
||||
|
||||
if(node->prev)
|
||||
node->prev->next = node;
|
||||
else
|
||||
list->head = node;
|
||||
list_node_t *node;
|
||||
|
||||
list->count++;
|
||||
|
||||
return node;
|
||||
node = list_alloc_node();
|
||||
|
||||
node->data = data;
|
||||
node->next = NULL;
|
||||
node->prev = list->tail;
|
||||
list->tail = node;
|
||||
|
||||
if(node->prev)
|
||||
node->prev->next = node;
|
||||
else
|
||||
list->head = node;
|
||||
|
||||
list->count++;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void list_unlink_node(list_t *list, list_node_t *node)
|
||||
{
|
||||
if(node->prev)
|
||||
node->prev->next = node->next;
|
||||
else
|
||||
list->head = node->next;
|
||||
|
||||
if(node->next)
|
||||
node->next->prev = node->prev;
|
||||
else
|
||||
list->tail = node->prev;
|
||||
if(node->prev)
|
||||
node->prev->next = node->next;
|
||||
else
|
||||
list->head = node->next;
|
||||
|
||||
list->count--;
|
||||
if(node->next)
|
||||
node->next->prev = node->prev;
|
||||
else
|
||||
list->tail = node->prev;
|
||||
|
||||
list->count--;
|
||||
}
|
||||
|
||||
void list_delete_node(list_t *list, list_node_t *node)
|
||||
{
|
||||
list_unlink_node(list, node);
|
||||
list_free_node(list, node);
|
||||
list_unlink_node(list, node);
|
||||
list_free_node(list, node);
|
||||
}
|
||||
|
||||
void list_delete_head(list_t *list)
|
||||
{
|
||||
list_delete_node(list, list->head);
|
||||
list_delete_node(list, list->head);
|
||||
}
|
||||
|
||||
void list_delete_tail(list_t *list)
|
||||
{
|
||||
list_delete_node(list, list->tail);
|
||||
list_delete_node(list, list->tail);
|
||||
}
|
||||
|
||||
/* Head/tail lookup */
|
||||
|
||||
void *list_get_head(list_t *list)
|
||||
{
|
||||
if(list->head)
|
||||
return list->head->data;
|
||||
else
|
||||
return NULL;
|
||||
if(list->head)
|
||||
return list->head->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *list_get_tail(list_t *list)
|
||||
{
|
||||
if(list->tail)
|
||||
return list->tail->data;
|
||||
else
|
||||
return NULL;
|
||||
if(list->tail)
|
||||
return list->tail->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Fast list deletion */
|
||||
|
||||
void list_delete_list(list_t *list)
|
||||
{
|
||||
list_node_t *node, *next;
|
||||
|
||||
for(node = list->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
list_free_node(list, node);
|
||||
}
|
||||
list_node_t *node, *next;
|
||||
|
||||
list_free(list);
|
||||
for(node = list->head; node; node = next) {
|
||||
next = node->next;
|
||||
list_free_node(list, node);
|
||||
}
|
||||
|
||||
list_free(list);
|
||||
}
|
||||
|
||||
/* Traversing */
|
||||
|
||||
void list_foreach_node(list_t *list, list_action_node_t action)
|
||||
{
|
||||
list_node_t *node, *next;
|
||||
list_node_t *node, *next;
|
||||
|
||||
for(node = list->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
action(node);
|
||||
}
|
||||
for(node = list->head; node; node = next) {
|
||||
next = node->next;
|
||||
action(node);
|
||||
}
|
||||
}
|
||||
|
||||
void list_foreach(list_t *list, list_action_t action)
|
||||
{
|
||||
list_node_t *node, *next;
|
||||
list_node_t *node, *next;
|
||||
|
||||
for(node = list->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
if(node->data)
|
||||
action(node->data);
|
||||
}
|
||||
for(node = list->head; node; node = next) {
|
||||
next = node->next;
|
||||
if(node->data)
|
||||
action(node->data);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
38
lib/list.h
38
lib/list.h
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
list.h -- header file for list.c
|
||||
Copyright (C) 2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000,2001 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 2000-2003 Ivo Timmermans <ivo@o2w.nl>
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -17,39 +17,37 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: list.h,v 1.2 2002/04/09 15:26:00 zarq Exp $
|
||||
$Id: list.h,v 1.3 2003/08/24 20:38:20 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_LIST_H__
|
||||
#define __TINC_LIST_H__
|
||||
|
||||
typedef struct list_node_t
|
||||
{
|
||||
struct list_node_t *prev;
|
||||
struct list_node_t *next;
|
||||
typedef struct list_node_t {
|
||||
struct list_node_t *prev;
|
||||
struct list_node_t *next;
|
||||
|
||||
/* Payload */
|
||||
/* Payload */
|
||||
|
||||
void *data;
|
||||
void *data;
|
||||
} list_node_t;
|
||||
|
||||
typedef void (*list_action_t) (const void *);
|
||||
typedef void (*list_action_node_t) (const list_node_t *);
|
||||
typedef void (*list_action_t)(const void *);
|
||||
typedef void (*list_action_node_t)(const list_node_t *);
|
||||
|
||||
typedef struct list_t
|
||||
{
|
||||
list_node_t *head;
|
||||
list_node_t *tail;
|
||||
int count;
|
||||
typedef struct list_t {
|
||||
list_node_t *head;
|
||||
list_node_t *tail;
|
||||
int count;
|
||||
|
||||
/* Callbacks */
|
||||
/* Callbacks */
|
||||
|
||||
list_action_t delete;
|
||||
list_action_t delete;
|
||||
} list_t;
|
||||
|
||||
/* (De)constructors */
|
||||
|
||||
extern list_t *list_alloc(list_action_t);
|
||||
extern list_t *list_alloc(list_action_t) __attribute__ ((__malloc__));
|
||||
extern void list_free(list_t *);
|
||||
extern list_node_t *list_alloc_node(void);
|
||||
extern void list_free_node(list_t *, list_node_t *);
|
||||
|
|
@ -79,4 +77,4 @@ extern void list_delete_list(list_t *);
|
|||
extern void list_foreach(list_t *, list_action_t);
|
||||
extern void list_foreach_node(list_t *, list_action_node_t);
|
||||
|
||||
#endif /* __TINC_LIST_H__ */
|
||||
#endif /* __TINC_LIST_H__ */
|
||||
|
|
|
|||
106
lib/logging.c
106
lib/logging.c
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
logging.c -- log messages to e.g. syslog
|
||||
Copyright (C) 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2001-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: logging.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
avl_tree_t *log_hooks_tree = NULL;
|
||||
|
||||
int debug_lvl = 0;
|
||||
|
||||
int log_compare(const void *a, const void *b)
|
||||
{
|
||||
if(a < b)
|
||||
return -1;
|
||||
if(a > b)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void log(int level, int priority, char *fmt, ...)
|
||||
{
|
||||
avl_node_t *avlnode;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
for(avlnode = log_hooks_tree->head; avlnode; avlnode = avlnode->next)
|
||||
{
|
||||
assert(avlnode->data);
|
||||
((log_function_t*)(avlnode->data))(level, priority, fmt, args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void log_add_hook(log_function_t *fn)
|
||||
{
|
||||
if(!log_hooks_tree)
|
||||
log_hooks_tree = avl_alloc_tree(log_compare, NULL);
|
||||
|
||||
avl_insert(log_hooks_tree, (void*)fn);
|
||||
}
|
||||
|
||||
void log_del_hook(log_function_t *fn)
|
||||
{
|
||||
avl_delete(log_hooks_tree, (void*)fn);
|
||||
}
|
||||
|
||||
void log_default(int level, int priority, char *fmt, va_list ap)
|
||||
{
|
||||
if(debug_lvl >= level)
|
||||
{
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void log_syslog(int level, int priority, char *fmt, va_list ap)
|
||||
{
|
||||
const int priorities[] = { LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_ERR, LOG_CRIT };
|
||||
|
||||
if(debug_lvl >= level)
|
||||
vsyslog(priorities[priority], fmt, ap);
|
||||
}
|
||||
|
||||
void tinc_syslog(int priority, char *fmt, ...)
|
||||
{
|
||||
/* Mapping syslog prio -> tinc prio */
|
||||
const int priorities[] = { TLOG_CRITICAL, TLOG_CRITICAL, TLOG_CRITICAL, TLOG_ERROR,
|
||||
TLOG_NOTICE, TLOG_NOTICE, TLOG_INFO, TLOG_DEBUG };
|
||||
avl_node_t *avlnode;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
for(avlnode = log_hooks_tree->head; avlnode; avlnode = avlnode->next)
|
||||
{
|
||||
assert(avlnode->data);
|
||||
((log_function_t*)(avlnode->data))(0, priorities[priority], fmt, args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
logging.h -- header for logging.c
|
||||
Copyright (C) 2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2002 Ivo Timmermans <ivo@o2w.nl>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: logging.h,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_LOGGING_H__
|
||||
#define __TINC_LOGGING_H__
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
enum {
|
||||
TLOG_DEBUG,
|
||||
TLOG_INFO,
|
||||
TLOG_NOTICE,
|
||||
TLOG_ERROR,
|
||||
TLOG_CRITICAL
|
||||
};
|
||||
|
||||
enum {
|
||||
DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */
|
||||
DEBUG_CONNECTIONS = 1, /* Show (dis)connects of other tinc daemons via TCP */
|
||||
DEBUG_ERROR = 2, /* Show error messages received from other hosts */
|
||||
DEBUG_STATUS = 2, /* Show status messages received from other hosts */
|
||||
DEBUG_PROTOCOL = 3, /* Show the requests that are sent/received */
|
||||
DEBUG_META = 4, /* Show contents of every request that is sent/received */
|
||||
DEBUG_TRAFFIC = 5, /* Show network traffic information */
|
||||
DEBUG_PACKET = 6, /* Show contents of each packet that is being sent/received */
|
||||
DEBUG_SCARY_THINGS = 10 /* You have been warned */
|
||||
};
|
||||
|
||||
typedef void (log_function_t)(int,int,char*,va_list);
|
||||
|
||||
extern int debug_lvl;
|
||||
extern avl_tree_t *log_hooks_tree;
|
||||
|
||||
extern void log(int, int, char *, ...);
|
||||
extern void log_add_hook(log_function_t *);
|
||||
extern void log_del_hook(log_function_t *);
|
||||
extern log_function_t log_default;
|
||||
extern log_function_t log_syslog;
|
||||
extern void tinc_syslog(int, char *, ...);
|
||||
|
||||
#ifndef LOG_ERR /* Something from syslog.h */
|
||||
# define syslog tinc_syslog
|
||||
#define LOG_EMERG 0 /* system is unusable */
|
||||
#define LOG_ALERT 1 /* action must be taken immediately */
|
||||
#define LOG_CRIT 2 /* critical conditions */
|
||||
#define LOG_ERR 3 /* error conditions */
|
||||
#define LOG_WARNING 4 /* warning conditions */
|
||||
#define LOG_NOTICE 5 /* normal but significant condition */
|
||||
#define LOG_INFO 6 /* informational */
|
||||
#define LOG_DEBUG 7 /* debug-level messages */
|
||||
#else
|
||||
# warning dont include syslog!
|
||||
#endif
|
||||
|
||||
#endif /* __TINC_LOGGING_H__ */
|
||||
153
lib/net.h
153
lib/net.h
|
|
@ -1,153 +0,0 @@
|
|||
/*
|
||||
net.h -- header for net.c
|
||||
Copyright (C) 1998-2002 Ivo Timmermans <zarq@iname.com>
|
||||
2000-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: net.h,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_NET_H__
|
||||
#define __TINC_NET_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef ENABLE_JUMBOGRAMS
|
||||
#define MTU 9014 /* 9000 bytes payload + 14 bytes ethernet header */
|
||||
#define MAXSIZE 9100 /* MTU + header (seqno) and trailer (CBC padding and HMAC) */
|
||||
#define MAXBUFSIZE 9100 /* Must support TCP packets of length 9000. */
|
||||
#else
|
||||
#define MTU 1514 /* 1500 bytes payload + 14 bytes ethernet header */
|
||||
#define MAXSIZE 1600 /* MTU + header (seqno) and trailer (CBC padding and HMAC) */
|
||||
#define MAXBUFSIZE 2100 /* Quite large but needed for support of keys up to 8192 bits. */
|
||||
#endif
|
||||
|
||||
#define MAXSOCKETS 128 /* Overkill... */
|
||||
|
||||
#define MAXQUEUELENGTH 8 /* Maximum number of packats in a single queue */
|
||||
|
||||
typedef struct mac_t
|
||||
{
|
||||
unsigned char x[6];
|
||||
} mac_t;
|
||||
|
||||
typedef struct ipv4_t
|
||||
{
|
||||
unsigned char x[4];
|
||||
} ipv4_t;
|
||||
|
||||
typedef struct ip_mask_t {
|
||||
ipv4_t address;
|
||||
ipv4_t mask;
|
||||
} ip_mask_t;
|
||||
|
||||
typedef struct ipv6_t
|
||||
{
|
||||
unsigned short x[8];
|
||||
} ipv6_t;
|
||||
|
||||
typedef unsigned short port_t;
|
||||
|
||||
typedef short length_t;
|
||||
|
||||
typedef union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in in;
|
||||
struct sockaddr_in6 in6;
|
||||
} sockaddr_t;
|
||||
|
||||
#ifdef SA_LEN
|
||||
#define SALEN(s) SA_LEN(&s)
|
||||
#else
|
||||
#define SALEN(s) (s.sa_family==AF_INET?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6))
|
||||
#endif
|
||||
|
||||
typedef struct vpn_packet_t {
|
||||
length_t len; /* the actual number of bytes in the `data' field */
|
||||
int priority; /* priority or TOS */
|
||||
unsigned int seqno; /* 32 bits sequence number (network byte order of course) */
|
||||
unsigned char data[MAXSIZE];
|
||||
} vpn_packet_t;
|
||||
|
||||
typedef struct queue_element_t {
|
||||
void *packet;
|
||||
struct queue_element_t *prev;
|
||||
struct queue_element_t *next;
|
||||
} queue_element_t;
|
||||
|
||||
typedef struct packet_queue_t {
|
||||
queue_element_t *head;
|
||||
queue_element_t *tail;
|
||||
} packet_queue_t;
|
||||
|
||||
typedef struct outgoing_t {
|
||||
char *name;
|
||||
int timeout;
|
||||
struct config_t *cfg;
|
||||
struct addrinfo *ai;
|
||||
struct addrinfo *aip;
|
||||
} outgoing_t;
|
||||
|
||||
typedef struct listen_socket_t {
|
||||
int tcp;
|
||||
int udp;
|
||||
sockaddr_t sa;
|
||||
} listen_socket_t;
|
||||
|
||||
extern int maxtimeout;
|
||||
extern int seconds_till_retry;
|
||||
extern int addressfamily;
|
||||
|
||||
extern char *request_name[];
|
||||
extern char *status_text[];
|
||||
|
||||
#include "connection.h" /* Yes, very strange placement indeed, but otherwise the typedefs get all tangled up */
|
||||
|
||||
extern listen_socket_t listen_socket[MAXSOCKETS];
|
||||
extern int listen_sockets;
|
||||
extern int keyexpires;
|
||||
extern int keylifetime;
|
||||
extern int do_prune;
|
||||
extern int do_purge;
|
||||
extern char *myport;
|
||||
extern time_t now;
|
||||
|
||||
extern void retry_outgoing(outgoing_t *);
|
||||
extern void handle_incoming_vpn_data(int);
|
||||
extern void finish_connecting(connection_t *);
|
||||
extern void do_outgoing_connection(connection_t *);
|
||||
extern int handle_new_meta_connection(int);
|
||||
extern int setup_listen_socket(sockaddr_t *);
|
||||
extern int setup_vpn_in_socket(sockaddr_t *);
|
||||
extern void send_packet(struct node_t *, vpn_packet_t *);
|
||||
extern void receive_packet(struct node_t *, vpn_packet_t *);
|
||||
extern void receive_tcppacket(struct connection_t *, char *, int);
|
||||
extern void broadcast_packet(struct node_t *, vpn_packet_t *);
|
||||
extern int setup_network_connections(void);
|
||||
extern void setup_outgoing_connection(struct outgoing_t *);
|
||||
extern void try_outgoing_connections(void);
|
||||
extern void close_network_connections(void);
|
||||
extern void main_loop(void);
|
||||
extern void terminate_connection(connection_t *, int);
|
||||
extern void flush_queue(struct node_t *);
|
||||
extern int read_rsa_public_key(struct connection_t *);
|
||||
|
||||
#endif /* __TINC_NET_H__ */
|
||||
247
lib/netutl.c
247
lib/netutl.c
|
|
@ -1,247 +0,0 @@
|
|||
/*
|
||||
netutl.c -- some supporting network utility code
|
||||
Copyright (C) 1998-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
2000-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: netutl.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <utils.h>
|
||||
#include <xalloc.h>
|
||||
|
||||
#include "errno.h"
|
||||
#include "conf.h"
|
||||
#include "net.h"
|
||||
#include "netutl.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
int hostnames = 0;
|
||||
|
||||
/*
|
||||
Turn a string into a struct addrinfo.
|
||||
Return NULL on failure.
|
||||
*/
|
||||
struct addrinfo *str2addrinfo(char *address, char *service, int socktype)
|
||||
{
|
||||
struct addrinfo hint, *ai;
|
||||
int err;
|
||||
cp
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
|
||||
hint.ai_family = addressfamily;
|
||||
hint.ai_socktype = socktype;
|
||||
|
||||
if((err = getaddrinfo(address, service, &hint, &ai)))
|
||||
{
|
||||
if(debug_lvl >= DEBUG_ERROR)
|
||||
syslog(LOG_WARNING, _("Error looking up %s port %s: %s\n"), address, service, gai_strerror(err));
|
||||
cp_trace();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cp
|
||||
return ai;
|
||||
}
|
||||
|
||||
sockaddr_t str2sockaddr(char *address, char *port)
|
||||
{
|
||||
struct addrinfo hint, *ai;
|
||||
sockaddr_t result;
|
||||
int err;
|
||||
cp
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
|
||||
hint.ai_family = AF_UNSPEC;
|
||||
hint.ai_flags = AI_NUMERICHOST;
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if((err = getaddrinfo(address, port, &hint, &ai) || !ai))
|
||||
{
|
||||
syslog(LOG_ERR, _("Error looking up %s port %s: %s\n"), address, port, gai_strerror(err));
|
||||
cp_trace();
|
||||
raise(SIGFPE);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
result = *(sockaddr_t *)ai->ai_addr;
|
||||
freeaddrinfo(ai);
|
||||
cp
|
||||
return result;
|
||||
}
|
||||
|
||||
void sockaddr2str(sockaddr_t *sa, char **addrstr, char **portstr)
|
||||
{
|
||||
char address[NI_MAXHOST];
|
||||
char port[NI_MAXSERV];
|
||||
char *scopeid;
|
||||
int err;
|
||||
cp
|
||||
if((err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV)))
|
||||
{
|
||||
syslog(LOG_ERR, _("Error while translating addresses: %s"), gai_strerror(err));
|
||||
cp_trace();
|
||||
raise(SIGFPE);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUX
|
||||
if((scopeid = strchr(address, '%')))
|
||||
*scopeid = '\0'; /* Descope. */
|
||||
#endif
|
||||
|
||||
*addrstr = xstrdup(address);
|
||||
*portstr = xstrdup(port);
|
||||
cp
|
||||
}
|
||||
|
||||
char *sockaddr2hostname(sockaddr_t *sa)
|
||||
{
|
||||
char *str;
|
||||
char address[NI_MAXHOST] = "unknown";
|
||||
char port[NI_MAXSERV] = "unknown";
|
||||
int err;
|
||||
cp
|
||||
if((err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), hostnames?0:(NI_NUMERICHOST|NI_NUMERICSERV))))
|
||||
{
|
||||
syslog(LOG_ERR, _("Error while looking up hostname: %s"), gai_strerror(err));
|
||||
}
|
||||
|
||||
asprintf(&str, _("%s port %s"), address, port);
|
||||
cp
|
||||
return str;
|
||||
}
|
||||
|
||||
int sockaddrcmp(sockaddr_t *a, sockaddr_t *b)
|
||||
{
|
||||
int result;
|
||||
cp
|
||||
result = a->sa.sa_family - b->sa.sa_family;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
switch(a->sa.sa_family)
|
||||
{
|
||||
case AF_UNSPEC:
|
||||
return 0;
|
||||
case AF_INET:
|
||||
result = memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr));
|
||||
if(result)
|
||||
return result;
|
||||
return memcmp(&a->in.sin_port, &b->in.sin_port, sizeof(a->in.sin_port));
|
||||
case AF_INET6:
|
||||
result = memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr));
|
||||
if(result)
|
||||
return result;
|
||||
return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof(a->in6.sin6_port));
|
||||
default:
|
||||
syslog(LOG_ERR, _("sockaddrcmp() was called with unknown address family %d, exitting!"), a->sa.sa_family);
|
||||
cp_trace();
|
||||
raise(SIGFPE);
|
||||
exit(0);
|
||||
}
|
||||
cp
|
||||
}
|
||||
|
||||
void sockaddrunmap(sockaddr_t *sa)
|
||||
{
|
||||
if(sa->sa.sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sa->in6.sin6_addr))
|
||||
{
|
||||
sa->in.sin_addr.s_addr = ((uint32_t *)&sa->in6.sin6_addr)[3];
|
||||
sa->in.sin_family = AF_INET;
|
||||
}
|
||||
}
|
||||
|
||||
/* Subnet mask handling */
|
||||
|
||||
int maskcmp(char *a, char *b, int masklen, int len)
|
||||
{
|
||||
int i, m, result;
|
||||
cp
|
||||
for(m = masklen, i = 0; m >= 8; m -= 8, i++)
|
||||
if((result = a[i] - b[i]))
|
||||
return result;
|
||||
|
||||
if(m)
|
||||
return (a[i] & (0x100 - (1 << (8 - m)))) - (b[i] & (0x100 - (1 << (8 - m))));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mask(char *a, int masklen, int len)
|
||||
{
|
||||
int i;
|
||||
cp
|
||||
i = masklen / 8;
|
||||
masklen %= 8;
|
||||
|
||||
if(masklen)
|
||||
a[i++] &= (0x100 - (1 << masklen));
|
||||
|
||||
for(; i < len; i++)
|
||||
a[i] = 0;
|
||||
}
|
||||
|
||||
void maskcpy(char *a, char *b, int masklen, int len)
|
||||
{
|
||||
int i, m;
|
||||
cp
|
||||
for(m = masklen, i = 0; m >= 8; m -= 8, i++)
|
||||
a[i] = b[i];
|
||||
|
||||
if(m)
|
||||
{
|
||||
a[i] = b[i] & (0x100 - (1 << m));
|
||||
i++;
|
||||
}
|
||||
|
||||
for(; i < len; i++)
|
||||
a[i] = 0;
|
||||
}
|
||||
|
||||
int maskcheck(char *a, int masklen, int len)
|
||||
{
|
||||
int i;
|
||||
cp
|
||||
i = masklen / 8;
|
||||
masklen %= 8;
|
||||
|
||||
if(masklen)
|
||||
if(a[i++] & (char)~(0x100 - (1 << masklen)))
|
||||
return -1;
|
||||
|
||||
for(; i < len; i++)
|
||||
if(a[i] != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
46
lib/netutl.h
46
lib/netutl.h
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
netutl.h -- header file for netutl.c
|
||||
Copyright (C) 1998-2002 Ivo Timmermans <zarq@iname.com>
|
||||
2000-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: netutl.h,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_NETUTL_H__
|
||||
#define __TINC_NETUTL_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "net.h"
|
||||
|
||||
extern int hostnames;
|
||||
|
||||
extern char *hostlookup(unsigned long);
|
||||
extern struct addrinfo *str2addrinfo(char *, char *, int);
|
||||
extern sockaddr_t str2sockaddr(char *, char *);
|
||||
extern void sockaddr2str(sockaddr_t *, char **, char **);
|
||||
extern char *sockaddr2hostname(sockaddr_t *);
|
||||
extern int sockaddrcmp(sockaddr_t *, sockaddr_t *);
|
||||
extern void sockaddrunmap(sockaddr_t *);
|
||||
extern int maskcmp(char *, char *, int, int);
|
||||
extern void maskcpy(char *, char *, int, int);
|
||||
extern void mask(char *, int, int);
|
||||
extern int maskcheck(char *, int, int);
|
||||
|
||||
#endif /* __TINC_NETUTL_H__ */
|
||||
188
lib/node.c
188
lib/node.c
|
|
@ -1,188 +0,0 @@
|
|||
/*
|
||||
node.c -- node tree management
|
||||
Copyright (C) 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2001-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: node.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <avl_tree.h>
|
||||
#include "node.h"
|
||||
#include "netutl.h"
|
||||
#include "net.h"
|
||||
#include <utils.h>
|
||||
#include <xalloc.h>
|
||||
#include <hooks.h>
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
avl_tree_t *node_tree; /* Known nodes, sorted by name */
|
||||
avl_tree_t *node_udp_tree; /* Known nodes, sorted by address and port */
|
||||
|
||||
node_t *myself;
|
||||
|
||||
int node_compare(node_t *a, node_t *b)
|
||||
{
|
||||
return strcmp(a->name, b->name);
|
||||
}
|
||||
|
||||
int node_udp_compare(node_t *a, node_t *b)
|
||||
{
|
||||
int result;
|
||||
cp
|
||||
result = sockaddrcmp(&a->address, &b->address);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
return (a->name && b->name)?strcmp(a->name, b->name):0;
|
||||
}
|
||||
|
||||
void init_nodes(void)
|
||||
{
|
||||
cp
|
||||
node_tree = avl_alloc_tree((avl_compare_t)node_compare, NULL);
|
||||
node_udp_tree = avl_alloc_tree((avl_compare_t)node_udp_compare, NULL);
|
||||
cp
|
||||
}
|
||||
|
||||
void exit_nodes(void)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(node_tree);
|
||||
avl_delete_tree(node_udp_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
node_t *new_node(void)
|
||||
{
|
||||
node_t *n = (node_t *)xmalloc_and_zero(sizeof(*n));
|
||||
cp
|
||||
n->subnet_tree = new_subnet_tree();
|
||||
n->edge_tree = new_edge_tree();
|
||||
n->queue = list_alloc((list_action_t)free);
|
||||
cp
|
||||
return n;
|
||||
}
|
||||
|
||||
void free_node(node_t *n)
|
||||
{
|
||||
cp
|
||||
if(n->queue)
|
||||
list_delete_list(n->queue);
|
||||
if(n->name)
|
||||
free(n->name);
|
||||
if(n->hostname)
|
||||
free(n->hostname);
|
||||
if(n->key)
|
||||
free(n->key);
|
||||
if(n->subnet_tree)
|
||||
free_subnet_tree(n->subnet_tree);
|
||||
if(n->edge_tree)
|
||||
free_edge_tree(n->edge_tree);
|
||||
free(n);
|
||||
cp
|
||||
}
|
||||
|
||||
void node_add(node_t *n)
|
||||
{
|
||||
cp
|
||||
avl_insert(node_tree, n);
|
||||
avl_insert(node_udp_tree, n);
|
||||
|
||||
run_hooks("node-add", n);
|
||||
cp
|
||||
}
|
||||
|
||||
void node_del(node_t *n)
|
||||
{
|
||||
avl_node_t *node, *next;
|
||||
edge_t *e;
|
||||
subnet_t *s;
|
||||
cp
|
||||
for(node = n->subnet_tree->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
s = (subnet_t *)node->data;
|
||||
subnet_del(n, s);
|
||||
}
|
||||
|
||||
for(node = n->subnet_tree->head; node; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
e = (edge_t *)node->data;
|
||||
edge_del(e);
|
||||
}
|
||||
cp
|
||||
avl_delete(node_tree, n);
|
||||
avl_delete(node_udp_tree, n);
|
||||
|
||||
run_hooks("node-del", n);
|
||||
cp
|
||||
}
|
||||
|
||||
node_t *lookup_node(char *name)
|
||||
{
|
||||
node_t n;
|
||||
cp
|
||||
n.name = name;
|
||||
return avl_search(node_tree, &n);
|
||||
}
|
||||
|
||||
node_t *lookup_node_udp(sockaddr_t *sa)
|
||||
{
|
||||
node_t n;
|
||||
cp
|
||||
n.address = *sa;
|
||||
n.name = NULL;
|
||||
|
||||
return avl_search(node_udp_tree, &n);
|
||||
}
|
||||
|
||||
void dump_nodes(void)
|
||||
{
|
||||
avl_node_t *node;
|
||||
node_t *n;
|
||||
cp
|
||||
log(0, TLOG_DEBUG,
|
||||
_("Nodes:"));
|
||||
|
||||
for(node = node_tree->head; node; node = node->next)
|
||||
{
|
||||
n = (node_t *)node->data;
|
||||
#ifdef USE_OPENSSL
|
||||
syslog(LOG_DEBUG, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s"),
|
||||
n->name, n->hostname, n->cipher?n->cipher->nid:0, n->digest?n->digest->type:0, n->maclength, n->compression, n->options,
|
||||
n->status, n->nexthop?n->nexthop->name:"-", n->via?n->via->name:"-");
|
||||
#endif
|
||||
#ifdef USE_GCRYPT
|
||||
syslog(LOG_DEBUG, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s"),
|
||||
n->name, n->hostname, n->cipher?-1:0, n->digest?-1:0, n->maclength, n->compression, n->options,
|
||||
n->status, n->nexthop?n->nexthop->name:"-", n->via?n->via->name:"-");
|
||||
#endif
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, _("End of nodes."));
|
||||
cp
|
||||
}
|
||||
106
lib/node.h
106
lib/node.h
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
node.h -- header for node.c
|
||||
Copyright (C) 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2001-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: node.h,v 1.2 2002/05/02 11:50:07 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_NODE_H__
|
||||
#define __TINC_NODE_H__
|
||||
|
||||
#ifdef USE_GCRYPT
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
|
||||
#include <avl_tree.h>
|
||||
|
||||
#include "subnet.h"
|
||||
#include "connection.h"
|
||||
|
||||
typedef struct node_status_t {
|
||||
int active:1; /* 1 if active.. */
|
||||
int validkey:1; /* 1 if we currently have a valid key for him */
|
||||
int waitingforkey:1; /* 1 if we already sent out a request */
|
||||
int visited:1; /* 1 if this node has been visited by one of the graph algorithms */
|
||||
int reachable:1; /* 1 if this node is reachable in the graph */
|
||||
int indirect:1; /* 1 if this node is not directly reachable by us */
|
||||
int unused:26;
|
||||
} node_status_t;
|
||||
|
||||
typedef struct node_t {
|
||||
char *name; /* name of this node */
|
||||
long int options; /* options turned on for this node */
|
||||
|
||||
sockaddr_t address; /* his real (internet) ip to send UDP packets to */
|
||||
char *hostname; /* the hostname of its real ip */
|
||||
|
||||
struct node_status_t status;
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
const EVP_CIPHER *cipher; /* Cipher type for UDP packets */
|
||||
#endif
|
||||
#ifdef USE_GCRYPT
|
||||
GCRY_CIPHER_HD cipher; /* Cipher type for UDP packets */
|
||||
#endif
|
||||
|
||||
char *key; /* Cipher key and iv */
|
||||
int keylength; /* Cipher key and iv length*/
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
const EVP_MD *digest; /* Digest type for MAC */
|
||||
#endif
|
||||
#ifdef USE_GCRYPT
|
||||
GCRY_MD_HD digest; /* Digest type for MAC */
|
||||
#endif
|
||||
|
||||
int maclength; /* Length of MAC */
|
||||
|
||||
int compression; /* Compressionlevel, 0 = no compression */
|
||||
|
||||
list_t *queue; /* Queue for packets awaiting to be encrypted */
|
||||
|
||||
struct node_t *nexthop; /* nearest node from us to him */
|
||||
struct node_t *via; /* next hop for UDP packets */
|
||||
|
||||
avl_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */
|
||||
|
||||
avl_tree_t *edge_tree; /* Edges with this node as one of the endpoints */
|
||||
|
||||
struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */
|
||||
|
||||
unsigned int sent_seqno; /* Sequence number last sent to this node */
|
||||
unsigned int received_seqno; /* Sequence number last received from this node */
|
||||
|
||||
void *data; /* Interface details */
|
||||
} node_t;
|
||||
|
||||
extern struct node_t *myself;
|
||||
extern avl_tree_t *node_tree;
|
||||
extern avl_tree_t *node_udp_tree;
|
||||
|
||||
extern void init_nodes(void);
|
||||
extern void exit_nodes(void);
|
||||
extern node_t *new_node(void);
|
||||
extern void free_node(node_t *);
|
||||
extern void node_add(node_t *);
|
||||
extern void node_del(node_t *);
|
||||
extern node_t *lookup_node(char *);
|
||||
extern node_t *lookup_node_udp(sockaddr_t *);
|
||||
extern void dump_nodes(void);
|
||||
|
||||
#endif /* __TINC_NODE_H__ */
|
||||
|
|
@ -25,16 +25,9 @@
|
|||
* First version (v0.2) released
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include "system.h"
|
||||
|
||||
#ifndef HAVE_MINGW
|
||||
/* read_pid
|
||||
*
|
||||
* Reads the specified pidfile and returns the read pid.
|
||||
|
|
@ -135,4 +128,4 @@ int remove_pid (char *pidfile)
|
|||
{
|
||||
return unlink (pidfile);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_MINGW
|
||||
/* read_pid
|
||||
*
|
||||
* Reads the specified pidfile and returns the read pid.
|
||||
|
|
@ -48,3 +49,4 @@ int write_pid (char *pidfile);
|
|||
* is returned
|
||||
*/
|
||||
int remove_pid (char *pidfile);
|
||||
#endif
|
||||
|
|
|
|||
596
lib/rbl.c
596
lib/rbl.c
|
|
@ -1,596 +0,0 @@
|
|||
/*
|
||||
rbl.c -- red-black tree + linked list convenience
|
||||
Copyright (C) 2000 Ivo Timmermans <itimmermans@bigfoot.com>,
|
||||
2000 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: rbl.c,v 1.2 2002/04/09 15:26:00 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <xalloc.h>
|
||||
|
||||
#include "rbl.h"
|
||||
#include <system.h>
|
||||
|
||||
/* Allocate a new rbl node */
|
||||
rbl_t *new_rbl()
|
||||
{
|
||||
return (rbl_t *)xmalloc_and_zero(sizeof(rbl_t));
|
||||
}
|
||||
|
||||
/* Free a rbl node */
|
||||
void free_rbl(rbl_t *rbl)
|
||||
{
|
||||
if(rbl->data && rbl->tree->delete)
|
||||
rbl->tree->delete(rbl->data);
|
||||
free(rbl);
|
||||
}
|
||||
|
||||
/* Allocate a new rbltree header */
|
||||
rbltree_t *new_rbltree(rbl_compare_t compare, rbl_action_t delete)
|
||||
{
|
||||
rbltree_t *tree;
|
||||
|
||||
tree = (rbltree_t *)xmalloc_and_zero(sizeof(rbltree_t));
|
||||
if(tree)
|
||||
{
|
||||
tree->compare = compare;
|
||||
tree->delete = delete;
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
/* Free a rbltree header */
|
||||
void free_rbltree(rbltree_t *tree)
|
||||
{
|
||||
free(tree);
|
||||
}
|
||||
|
||||
/* Search closest match in the tree */
|
||||
rbl_t *rbl_search_closest_rbl(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl, *next;
|
||||
int result;
|
||||
|
||||
next = rbl = tree->top;
|
||||
|
||||
while(next)
|
||||
{
|
||||
rbl = next;
|
||||
|
||||
result = tree->compare(data, rbl->data);
|
||||
|
||||
if(result < 0)
|
||||
next = rbl->left;
|
||||
else if(result > 0)
|
||||
next = rbl->right;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return rbl;
|
||||
}
|
||||
|
||||
/* Search closest match in the tree */
|
||||
rbl_t *rbl_search_closest_greater_rbl(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_closest_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
{
|
||||
if(tree->compare(data, rbl->data) > 0)
|
||||
rbl = rbl->next;
|
||||
}
|
||||
|
||||
return rbl;
|
||||
}
|
||||
|
||||
/* Search closest match in the tree */
|
||||
rbl_t *rbl_search_closest_smaller_rbl(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_closest_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
{
|
||||
if(tree->compare(data, rbl->data) < 0)
|
||||
rbl = rbl->next;
|
||||
}
|
||||
|
||||
return rbl;
|
||||
}
|
||||
|
||||
void *rbl_search_closest(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_closest_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
return rbl->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *rbl_search_closest_greater(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_closest_greater_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
return rbl->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *rbl_search_closest_smaller(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_closest_smaller_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
return rbl->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Search exact match or return NULL pointer */
|
||||
rbl_t *rbl_search_rbl(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
int result;
|
||||
|
||||
rbl = tree->top;
|
||||
|
||||
while(rbl)
|
||||
{
|
||||
result = tree->compare(data, rbl->data);
|
||||
|
||||
if(result < 0)
|
||||
rbl = rbl->left;
|
||||
else if(result > 0)
|
||||
rbl = rbl->right;
|
||||
else
|
||||
return rbl;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *rbl_search(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
return rbl->data;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Red-black tree operations taken from Introduction to Algorithms,
|
||||
Cormen, Leiserson & Rivest, chapter 14.
|
||||
*/
|
||||
|
||||
void rbl_left_rotate(rbl_t *x)
|
||||
{
|
||||
rbl_t *y;
|
||||
|
||||
y = x->right;
|
||||
x->right = y->left;
|
||||
|
||||
if(y->left)
|
||||
y->left->parent = x;
|
||||
|
||||
y->parent = x->parent;
|
||||
|
||||
if(!x->parent)
|
||||
x->tree->top = y;
|
||||
else
|
||||
if(x == x->parent->left)
|
||||
x->parent->left = y;
|
||||
else
|
||||
x->parent->right = y;
|
||||
|
||||
y->left = x;
|
||||
x->parent = y;
|
||||
}
|
||||
|
||||
void rbl_right_rotate(rbl_t *y)
|
||||
{
|
||||
rbl_t *x;
|
||||
|
||||
x = y->left;
|
||||
y->left = x->right;
|
||||
|
||||
if(x->right)
|
||||
x->right->parent = y;
|
||||
|
||||
x->parent = y->parent;
|
||||
|
||||
if(!y->parent)
|
||||
y->tree->top = x;
|
||||
else
|
||||
if(y == y->parent->right)
|
||||
y->parent->right = x;
|
||||
else
|
||||
y->parent->left = x;
|
||||
|
||||
x->right = y;
|
||||
y->parent = x;
|
||||
}
|
||||
|
||||
/* Insert a node into the rbl tree */
|
||||
rbl_t *rbl_insert_rbl(rbltree_t *tree, rbl_t *rbl)
|
||||
{
|
||||
rbl_t *closest, *x, *y;
|
||||
int result;
|
||||
|
||||
rbl->tree = tree;
|
||||
|
||||
/* Binary tree and linked list insert */
|
||||
|
||||
if(tree->top)
|
||||
{
|
||||
closest = rbl_search_closest_rbl(tree, rbl->data);
|
||||
result = tree->compare(rbl->data, closest->data);
|
||||
if(result < 0)
|
||||
{
|
||||
closest->left = rbl;
|
||||
|
||||
rbl->prev = closest->prev;
|
||||
rbl->next = closest;
|
||||
closest->prev = rbl;
|
||||
|
||||
if(rbl->prev)
|
||||
rbl->prev->next = rbl;
|
||||
else
|
||||
tree->head = rbl;
|
||||
}
|
||||
else if(result > 0)
|
||||
{
|
||||
closest->right = rbl;
|
||||
|
||||
rbl->next = closest->next;
|
||||
rbl->prev = closest;
|
||||
closest->next = rbl;
|
||||
|
||||
if(rbl->next)
|
||||
rbl->next->prev = rbl;
|
||||
else
|
||||
tree->tail = rbl;
|
||||
}
|
||||
else
|
||||
return closest; /* Ofcourse, we cannot add two identical things */
|
||||
|
||||
rbl->parent = closest;
|
||||
}
|
||||
else
|
||||
{
|
||||
tree->top = rbl;
|
||||
tree->head = rbl;
|
||||
tree->tail = rbl;
|
||||
}
|
||||
|
||||
/* Red-black part of insert */
|
||||
|
||||
x = rbl;
|
||||
x->color = RBL_RED;
|
||||
|
||||
while(x != tree->top && x->parent->color == RBL_RED)
|
||||
{
|
||||
if(x->parent == x->parent->parent->left)
|
||||
{
|
||||
y = x->parent->parent->right;
|
||||
if(y && y->color == RBL_RED)
|
||||
{
|
||||
x->parent->color = RBL_BLACK;
|
||||
y->color = RBL_BLACK;
|
||||
x->parent->parent->color = RBL_RED;
|
||||
x = x->parent->parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(x == x->parent->right)
|
||||
{
|
||||
x = x->parent;
|
||||
rbl_left_rotate(x);
|
||||
}
|
||||
x->parent->color = RBL_BLACK;
|
||||
x->parent->parent->color = RBL_RED;
|
||||
rbl_right_rotate(x->parent->parent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
y = x->parent->parent->left;
|
||||
if(y && y->color == RBL_RED)
|
||||
{
|
||||
x->parent->color = RBL_BLACK;
|
||||
y->color = RBL_BLACK;
|
||||
x->parent->parent->color = RBL_RED;
|
||||
x = x->parent->parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(x == x->parent->left)
|
||||
{
|
||||
x = x->parent;
|
||||
rbl_right_rotate(x);
|
||||
}
|
||||
x->parent->color = RBL_BLACK;
|
||||
x->parent->parent->color = RBL_RED;
|
||||
rbl_left_rotate(x->parent->parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tree->top->color = RBL_BLACK;
|
||||
return rbl;
|
||||
}
|
||||
|
||||
/* Create a new node and insert it into the tree */
|
||||
rbl_t *rbl_insert(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = new_rbl();
|
||||
rbl->data = data;
|
||||
|
||||
if(rbl_insert_rbl(tree, rbl) == rbl)
|
||||
return rbl;
|
||||
else
|
||||
{
|
||||
free_rbl(rbl);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore red-black property after violation due to a deletion */
|
||||
void rbl_delete_fixup(rbl_t *x)
|
||||
{
|
||||
rbl_t *w;
|
||||
|
||||
while(x != x->tree->top && x->color == RBL_BLACK)
|
||||
{
|
||||
if(x == x->parent->left)
|
||||
{
|
||||
w = x->parent->right;
|
||||
if(w->color == RBL_RED)
|
||||
{
|
||||
w->color = RBL_BLACK;
|
||||
x->parent->color = RBL_RED;
|
||||
rbl_left_rotate(x->parent);
|
||||
w = x->parent->right;
|
||||
}
|
||||
if(w->left->color == RBL_BLACK && w->right->color == RBL_BLACK)
|
||||
{
|
||||
w->color = RBL_RED;
|
||||
x = x->parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(w->right->color == RBL_BLACK)
|
||||
{
|
||||
w->left->color = RBL_BLACK;
|
||||
w->color = RBL_RED;
|
||||
rbl_right_rotate(w);
|
||||
w = x->parent->right;
|
||||
}
|
||||
w->color = x->parent->color;
|
||||
x->parent->color = RBL_BLACK;
|
||||
w->right->color = RBL_BLACK;
|
||||
rbl_left_rotate(x->parent);
|
||||
x = x->tree->top;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
w = x->parent->left;
|
||||
if(w->color == RBL_RED)
|
||||
{
|
||||
w->color = RBL_BLACK;
|
||||
x->parent->color = RBL_RED;
|
||||
rbl_right_rotate(x->parent);
|
||||
w = x->parent->left;
|
||||
}
|
||||
if(w->right->color == RBL_BLACK && w->left->color == RBL_BLACK)
|
||||
{
|
||||
w->color = RBL_RED;
|
||||
x = x->parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(w->left->color == RBL_BLACK)
|
||||
{
|
||||
w->right->color = RBL_BLACK;
|
||||
w->color = RBL_RED;
|
||||
rbl_left_rotate(w);
|
||||
w = x->parent->left;
|
||||
}
|
||||
w->color = x->parent->color;
|
||||
x->parent->color = RBL_BLACK;
|
||||
w->left->color = RBL_BLACK;
|
||||
rbl_right_rotate(x->parent);
|
||||
x = x->tree->top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x->color = RBL_BLACK;
|
||||
}
|
||||
|
||||
/* Unlink node from the tree, but keep the node intact. */
|
||||
rbl_t *rbl_unlink_rbl(rbl_t *rbl)
|
||||
{
|
||||
rbl_t *x, *y;
|
||||
|
||||
/* Binary tree delete */
|
||||
|
||||
if(rbl->left && rbl->right)
|
||||
y = rbl->next;
|
||||
else
|
||||
y = rbl;
|
||||
|
||||
if(y->left)
|
||||
x = y->left;
|
||||
else
|
||||
x = y->right;
|
||||
|
||||
if(x)
|
||||
x->parent = y->parent;
|
||||
|
||||
if(!y->parent)
|
||||
rbl->tree->top = x;
|
||||
else
|
||||
if(y == y->parent->left)
|
||||
y->parent->left = x;
|
||||
else
|
||||
y->parent->right = x;
|
||||
|
||||
if(y != rbl)
|
||||
{
|
||||
y->left = rbl->left;
|
||||
y->right = rbl->right;
|
||||
y->parent = rbl->parent;
|
||||
if(rbl == rbl->parent->left)
|
||||
rbl->parent->left = y;
|
||||
else
|
||||
rbl->parent->right = y;
|
||||
}
|
||||
|
||||
/* Linked list delete */
|
||||
|
||||
if(rbl->prev)
|
||||
rbl->prev->next = rbl->next;
|
||||
else
|
||||
rbl->tree->head = rbl->next;
|
||||
|
||||
if(rbl->next)
|
||||
rbl->next->prev = rbl->prev;
|
||||
else
|
||||
rbl->tree->tail = rbl->prev;
|
||||
|
||||
/* Red-black part of delete */
|
||||
|
||||
if(y->color == RBL_BLACK && x)
|
||||
rbl_delete_fixup(x);
|
||||
|
||||
return rbl;
|
||||
}
|
||||
|
||||
/* Search node in tree and unlink it */
|
||||
rbl_t *rbl_unlink(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_search_rbl(tree, data);
|
||||
|
||||
if(rbl)
|
||||
rbl_unlink_rbl(rbl);
|
||||
|
||||
return rbl;
|
||||
}
|
||||
|
||||
/* Unlink node and free it */
|
||||
void rbl_delete_rbl(rbl_t *rbl)
|
||||
{
|
||||
rbl_unlink_rbl(rbl);
|
||||
free_rbl(rbl);
|
||||
}
|
||||
|
||||
/* Search node in tree, unlink and free it */
|
||||
void rbl_delete(rbltree_t *tree, void *data)
|
||||
{
|
||||
rbl_t *rbl;
|
||||
|
||||
rbl = rbl_unlink(tree, data);
|
||||
|
||||
if(rbl)
|
||||
free_rbl(rbl);
|
||||
}
|
||||
|
||||
/* Optimized unlinking for a complete tree */
|
||||
void rbl_unlink_rbltree(rbltree_t *tree)
|
||||
{
|
||||
rbl_t *rbl, *next;
|
||||
|
||||
for(rbl = tree->head; rbl; rbl = next)
|
||||
{
|
||||
next = rbl->next;
|
||||
rbl->tree = NULL;
|
||||
rbl->parent = NULL;
|
||||
rbl->left = NULL;
|
||||
rbl->right = NULL;
|
||||
rbl->prev = NULL;
|
||||
rbl->next = NULL;
|
||||
}
|
||||
|
||||
tree->top = NULL;
|
||||
tree->head = NULL;
|
||||
tree->tail = NULL;
|
||||
}
|
||||
|
||||
/* Optimized deletion for a complete tree */
|
||||
void rbl_delete_rbltree(rbltree_t *tree)
|
||||
{
|
||||
rbl_t *rbl, *next;
|
||||
|
||||
for(rbl = tree->head; rbl; rbl = next)
|
||||
{
|
||||
next = rbl->next;
|
||||
free_rbl(rbl);
|
||||
}
|
||||
|
||||
tree->top = NULL;
|
||||
tree->head = NULL;
|
||||
tree->tail = NULL;
|
||||
}
|
||||
|
||||
/* Do action for each list entry (in order)
|
||||
Deletion of entry for which action is called is allowed.
|
||||
*/
|
||||
void rbl_foreach(rbltree_t *tree, rbl_action_t action)
|
||||
{
|
||||
rbl_t *rbl, *next;
|
||||
|
||||
for(rbl = tree->head; rbl; rbl = next)
|
||||
{
|
||||
next = rbl->next;
|
||||
action(rbl->data);
|
||||
}
|
||||
}
|
||||
|
||||
void rbl_foreach_rbl(rbltree_t *tree, rbl_action_rbl_t action)
|
||||
{
|
||||
rbl_t *rbl, *next;
|
||||
|
||||
for(rbl = tree->head; rbl; rbl = next)
|
||||
{
|
||||
next = rbl->next;
|
||||
action(rbl);
|
||||
}
|
||||
}
|
||||
104
lib/rbl.h
104
lib/rbl.h
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
rbl.h -- header file for rbl.c
|
||||
Copyright (C) 2000 Ivo Timmermans <itimmermans@bigfoot.com>,
|
||||
2000 Guus Sliepen <guus@sliepen.warande.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: rbl.h,v 1.2 2002/04/09 15:26:00 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __RBL_H__
|
||||
#define __RBL_H__
|
||||
|
||||
#define RBL_FOREACH(tree,rbl) for(rbl = tree->head; rbl; rbl = rbl->next)
|
||||
|
||||
typedef struct rbl_t
|
||||
{
|
||||
/* 'red-black tree' part */
|
||||
|
||||
struct rbltree_t *tree;
|
||||
|
||||
int color;
|
||||
|
||||
struct rbl_t *parent;
|
||||
struct rbl_t *left;
|
||||
struct rbl_t *right;
|
||||
|
||||
/* 'linked list' part */
|
||||
|
||||
struct rbl_t *prev;
|
||||
struct rbl_t *next;
|
||||
|
||||
/* payload */
|
||||
|
||||
void *data;
|
||||
|
||||
} rbl_t;
|
||||
|
||||
typedef int (*rbl_compare_t) (const void *, const void *);
|
||||
typedef void (*rbl_action_t) (const void *);
|
||||
typedef void (*rbl_action_rbl_t) (const struct rbl_t *);
|
||||
|
||||
typedef struct rbltree_t
|
||||
{
|
||||
/* callback functions */
|
||||
|
||||
rbl_compare_t compare;
|
||||
rbl_action_t delete;
|
||||
|
||||
/* tree part */
|
||||
|
||||
struct rbl_t *top;
|
||||
|
||||
/* linked list */
|
||||
|
||||
struct rbl_t *head;
|
||||
struct rbl_t *tail;
|
||||
|
||||
} rbltree_t;
|
||||
|
||||
enum color
|
||||
{
|
||||
RBL_RED,
|
||||
RBL_BLACK
|
||||
} color;
|
||||
|
||||
extern rbltree_t *new_rbltree(rbl_compare_t, rbl_action_t);
|
||||
extern void free_rbltree(rbltree_t *);
|
||||
extern rbl_t *new_rbl(void);
|
||||
extern void free_rbl(rbl_t *);
|
||||
|
||||
extern void *rbl_search(rbltree_t *, void *);
|
||||
extern void *rbl_search_closest(rbltree_t *, void *);
|
||||
extern void *rbl_search_closest_greater(rbltree_t *, void *);
|
||||
extern void *rbl_search_closest_smaller(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_search_rbl(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_search_closest_rbl(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_search_closest_greater_rbl(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_search_closest_smaller_rbl(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_insert(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_unlink(rbltree_t *, void *);
|
||||
extern void rbl_delete(rbltree_t *, void *);
|
||||
extern rbl_t *rbl_insert_rbl(rbltree_t *, rbl_t *);
|
||||
extern rbl_t *rbl_unlink_rbl(rbl_t *);
|
||||
extern void rbl_delete_rbl(rbl_t *);
|
||||
extern void rbl_unlink_rbltree(rbltree_t *);
|
||||
extern void rbl_delete_rbltree(rbltree_t *);
|
||||
|
||||
extern void rbl_foreach(rbltree_t *, rbl_action_t);
|
||||
extern void rbl_foreach_rbl(rbltree_t *, rbl_action_rbl_t);
|
||||
|
||||
#endif /* __RBL_H__ */
|
||||
399
lib/subnet.c
399
lib/subnet.c
|
|
@ -1,399 +0,0 @@
|
|||
/*
|
||||
subnet.c -- handle subnet lookups and lists
|
||||
Copyright (C) 2000-2002 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2000-2002 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: subnet.c,v 1.1 2002/04/28 12:46:26 zarq Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <hooks.h>
|
||||
#include <utils.h>
|
||||
#include <xalloc.h>
|
||||
#include <avl_tree.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "net.h"
|
||||
#include "node.h"
|
||||
#include "subnet.h"
|
||||
#include "netutl.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include "system.h"
|
||||
|
||||
/* lists type of subnet */
|
||||
|
||||
avl_tree_t *subnet_tree;
|
||||
|
||||
/* Subnet comparison */
|
||||
|
||||
int subnet_compare_mac(subnet_t *a, subnet_t *b)
|
||||
{
|
||||
cp
|
||||
return memcmp(&a->net.mac.address, &b->net.mac.address, sizeof(mac_t));
|
||||
}
|
||||
|
||||
int subnet_compare_ipv4(subnet_t *a, subnet_t *b)
|
||||
{
|
||||
int result;
|
||||
cp
|
||||
result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t));
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
return a->net.ipv4.prefixlength - b->net.ipv4.prefixlength;
|
||||
}
|
||||
|
||||
int subnet_compare_ipv6(subnet_t *a, subnet_t *b)
|
||||
{
|
||||
int result;
|
||||
cp
|
||||
result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t));
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
return a->net.ipv6.prefixlength - b->net.ipv6.prefixlength;
|
||||
}
|
||||
|
||||
int subnet_compare(subnet_t *a, subnet_t *b)
|
||||
{
|
||||
int result;
|
||||
cp
|
||||
result = a->type - b->type;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
switch(a->type)
|
||||
{
|
||||
case SUBNET_MAC:
|
||||
return subnet_compare_mac(a, b);
|
||||
case SUBNET_IPV4:
|
||||
return subnet_compare_ipv4(a, b);
|
||||
case SUBNET_IPV6:
|
||||
return subnet_compare_ipv6(a, b);
|
||||
default:
|
||||
syslog(LOG_ERR, _("subnet_compare() was called with unknown subnet type %d, exitting!"), a->type);
|
||||
cp_trace();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialising trees */
|
||||
|
||||
void init_subnets(void)
|
||||
{
|
||||
cp
|
||||
subnet_tree = avl_alloc_tree((avl_compare_t)subnet_compare, (avl_action_t)free_subnet);
|
||||
cp
|
||||
}
|
||||
|
||||
void exit_subnets(void)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(subnet_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
avl_tree_t *new_subnet_tree(void)
|
||||
{
|
||||
cp
|
||||
return avl_alloc_tree((avl_compare_t)subnet_compare, NULL);
|
||||
cp
|
||||
}
|
||||
|
||||
void free_subnet_tree(avl_tree_t *subnet_tree)
|
||||
{
|
||||
cp
|
||||
avl_delete_tree(subnet_tree);
|
||||
cp
|
||||
}
|
||||
|
||||
/* Allocating and freeing space for subnets */
|
||||
|
||||
subnet_t *new_subnet(void)
|
||||
{
|
||||
cp
|
||||
return (subnet_t *)xmalloc(sizeof(subnet_t));
|
||||
}
|
||||
|
||||
void free_subnet(subnet_t *subnet)
|
||||
{
|
||||
cp
|
||||
free(subnet);
|
||||
}
|
||||
|
||||
/* Adding and removing subnets */
|
||||
|
||||
void subnet_add(node_t *n, subnet_t *subnet)
|
||||
{
|
||||
cp
|
||||
subnet->owner = n;
|
||||
|
||||
avl_insert(subnet_tree, subnet);
|
||||
cp
|
||||
avl_insert(n->subnet_tree, subnet);
|
||||
|
||||
run_hooks("subnet-add", subnet);
|
||||
cp
|
||||
}
|
||||
|
||||
void subnet_del(node_t *n, subnet_t *subnet)
|
||||
{
|
||||
cp
|
||||
avl_delete(n->subnet_tree, subnet);
|
||||
cp
|
||||
avl_delete(subnet_tree, subnet);
|
||||
|
||||
run_hooks("subnet-del", subnet);
|
||||
cp
|
||||
}
|
||||
|
||||
/* Ascii representation of subnets */
|
||||
|
||||
subnet_t *str2net(char *subnetstr)
|
||||
{
|
||||
int i, l;
|
||||
subnet_t *subnet;
|
||||
unsigned short int x[8];
|
||||
cp
|
||||
subnet = new_subnet();
|
||||
cp
|
||||
if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d",
|
||||
&x[0], &x[1], &x[2], &x[3],
|
||||
&l) == 5)
|
||||
{
|
||||
subnet->type = SUBNET_IPV4;
|
||||
subnet->net.ipv4.prefixlength = l;
|
||||
for(i = 0; i < 4; i++)
|
||||
subnet->net.ipv4.address.x[i] = x[i];
|
||||
return subnet;
|
||||
}
|
||||
|
||||
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d",
|
||||
&x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
|
||||
&l) == 9)
|
||||
{
|
||||
subnet->type = SUBNET_IPV6;
|
||||
subnet->net.ipv6.prefixlength = l;
|
||||
for(i = 0; i < 8; i++)
|
||||
subnet->net.ipv6.address.x[i] = htons(x[i]);
|
||||
return subnet;
|
||||
}
|
||||
|
||||
if(sscanf(subnetstr, "%hu.%hu.%hu.%hu",
|
||||
&x[0], &x[1], &x[2], &x[3]) == 4)
|
||||
{
|
||||
subnet->type = SUBNET_IPV4;
|
||||
subnet->net.ipv4.prefixlength = 32;
|
||||
for(i = 0; i < 4; i++)
|
||||
subnet->net.ipv4.address.x[i] = x[i];
|
||||
return subnet;
|
||||
}
|
||||
|
||||
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
|
||||
&x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7]) == 8)
|
||||
{
|
||||
subnet->type = SUBNET_IPV6;
|
||||
subnet->net.ipv6.prefixlength = 128;
|
||||
for(i = 0; i < 8; i++)
|
||||
subnet->net.ipv6.address.x[i] = htons(x[i]);
|
||||
return subnet;
|
||||
}
|
||||
|
||||
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx",
|
||||
&x[0], &x[1], &x[2], &x[3], &x[4], &x[5]) == 6)
|
||||
{
|
||||
subnet->type = SUBNET_MAC;
|
||||
for(i = 0; i < 6; i++)
|
||||
subnet->net.mac.address.x[i] = x[i];
|
||||
return subnet;
|
||||
}
|
||||
|
||||
free(subnet);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *net2str(subnet_t *subnet)
|
||||
{
|
||||
char *netstr;
|
||||
cp
|
||||
switch(subnet->type)
|
||||
{
|
||||
case SUBNET_MAC:
|
||||
asprintf(&netstr, "%hx:%hx:%hx:%hx:%hx:%hx",
|
||||
subnet->net.mac.address.x[0],
|
||||
subnet->net.mac.address.x[1],
|
||||
subnet->net.mac.address.x[2],
|
||||
subnet->net.mac.address.x[3],
|
||||
subnet->net.mac.address.x[4],
|
||||
subnet->net.mac.address.x[5]);
|
||||
break;
|
||||
case SUBNET_IPV4:
|
||||
asprintf(&netstr, "%hu.%hu.%hu.%hu/%d",
|
||||
subnet->net.ipv4.address.x[0],
|
||||
subnet->net.ipv4.address.x[1],
|
||||
subnet->net.ipv4.address.x[2],
|
||||
subnet->net.ipv4.address.x[3],
|
||||
subnet->net.ipv4.prefixlength);
|
||||
break;
|
||||
case SUBNET_IPV6:
|
||||
asprintf(&netstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d",
|
||||
ntohs(subnet->net.ipv6.address.x[0]),
|
||||
ntohs(subnet->net.ipv6.address.x[1]),
|
||||
ntohs(subnet->net.ipv6.address.x[2]),
|
||||
ntohs(subnet->net.ipv6.address.x[3]),
|
||||
ntohs(subnet->net.ipv6.address.x[4]),
|
||||
ntohs(subnet->net.ipv6.address.x[5]),
|
||||
ntohs(subnet->net.ipv6.address.x[6]),
|
||||
ntohs(subnet->net.ipv6.address.x[7]),
|
||||
subnet->net.ipv6.prefixlength);
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_ERR, _("net2str() was called with unknown subnet type %d, exitting!"), subnet->type);
|
||||
cp_trace();
|
||||
exit(0);
|
||||
}
|
||||
cp
|
||||
return netstr;
|
||||
}
|
||||
|
||||
/* Subnet lookup routines */
|
||||
|
||||
subnet_t *lookup_subnet(node_t *owner, subnet_t *subnet)
|
||||
{
|
||||
cp
|
||||
return avl_search(owner->subnet_tree, subnet);
|
||||
}
|
||||
|
||||
subnet_t *lookup_subnet_mac(mac_t *address)
|
||||
{
|
||||
subnet_t subnet, *p;
|
||||
cp
|
||||
subnet.type = SUBNET_MAC;
|
||||
memcpy(&subnet.net.mac.address, address, sizeof(mac_t));
|
||||
|
||||
p = (subnet_t *)avl_search(subnet_tree, &subnet);
|
||||
cp
|
||||
return p;
|
||||
}
|
||||
|
||||
subnet_t *lookup_subnet_ipv4(ipv4_t *address)
|
||||
{
|
||||
subnet_t subnet, *p;
|
||||
cp
|
||||
subnet.type = SUBNET_IPV4;
|
||||
memcpy(&subnet.net.ipv4.address, address, sizeof(ipv4_t));
|
||||
subnet.net.ipv4.prefixlength = 32;
|
||||
|
||||
do
|
||||
{
|
||||
/* Go find subnet */
|
||||
|
||||
p = (subnet_t *)avl_search_closest_smaller(subnet_tree, &subnet);
|
||||
|
||||
/* Check if the found subnet REALLY matches */
|
||||
cp
|
||||
if(p)
|
||||
{
|
||||
if(p->type != SUBNET_IPV4)
|
||||
{
|
||||
p = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!maskcmp((char *)address, (char *)&p->net.ipv4.address, p->net.ipv4.prefixlength, sizeof(ipv4_t)))
|
||||
break;
|
||||
else
|
||||
{
|
||||
/* Otherwise, see if there is a bigger enclosing subnet */
|
||||
|
||||
subnet.net.ipv4.prefixlength = p->net.ipv4.prefixlength - 1;
|
||||
maskcpy((char *)&subnet.net.ipv4.address, (char *)&p->net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(ipv4_t));
|
||||
}
|
||||
}
|
||||
} while (p);
|
||||
cp
|
||||
return p;
|
||||
}
|
||||
|
||||
subnet_t *lookup_subnet_ipv6(ipv6_t *address)
|
||||
{
|
||||
subnet_t subnet, *p;
|
||||
cp
|
||||
subnet.type = SUBNET_IPV6;
|
||||
memcpy(&subnet.net.ipv6.address, address, sizeof(ipv6_t));
|
||||
subnet.net.ipv6.prefixlength = 128;
|
||||
|
||||
do
|
||||
{
|
||||
/* Go find subnet */
|
||||
|
||||
p = (subnet_t *)avl_search_closest_smaller(subnet_tree, &subnet);
|
||||
|
||||
/* Check if the found subnet REALLY matches */
|
||||
|
||||
cp
|
||||
if(p)
|
||||
{
|
||||
if(p->type != SUBNET_IPV6)
|
||||
return NULL;
|
||||
|
||||
if (!maskcmp((char *)address, (char *)&p->net.ipv6.address, p->net.ipv6.prefixlength, sizeof(ipv6_t)))
|
||||
break;
|
||||
else
|
||||
{
|
||||
/* Otherwise, see if there is a bigger enclosing subnet */
|
||||
|
||||
subnet.net.ipv6.prefixlength = p->net.ipv6.prefixlength - 1;
|
||||
maskcpy((char *)&subnet.net.ipv6.address, (char *)&p->net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(ipv6_t));
|
||||
}
|
||||
}
|
||||
} while (p);
|
||||
cp
|
||||
return p;
|
||||
}
|
||||
|
||||
void dump_subnets(void)
|
||||
{
|
||||
char *netstr;
|
||||
subnet_t *subnet;
|
||||
avl_node_t *node;
|
||||
cp
|
||||
syslog(LOG_DEBUG, _("Subnet list:"));
|
||||
for(node = subnet_tree->head; node; node = node->next)
|
||||
{
|
||||
subnet = (subnet_t *)node->data;
|
||||
netstr = net2str(subnet);
|
||||
syslog(LOG_DEBUG, _(" %s owner %s"), netstr, subnet->owner->name);
|
||||
free(netstr);
|
||||
}
|
||||
syslog(LOG_DEBUG, _("End of subnet list."));
|
||||
cp
|
||||
}
|
||||
90
lib/subnet.h
90
lib/subnet.h
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
subnet.h -- header for subnet.c
|
||||
Copyright (C) 2000,2001 Guus Sliepen <guus@sliepen.warande.net>,
|
||||
2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: subnet.h,v 1.1 2002/04/28 12:46:26 zarq Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_SUBNET_H__
|
||||
#define __TINC_SUBNET_H__
|
||||
|
||||
#include "net.h"
|
||||
|
||||
enum
|
||||
{
|
||||
SUBNET_MAC = 0,
|
||||
SUBNET_IPV4,
|
||||
SUBNET_IPV6,
|
||||
SUBNET_TYPES /* Guardian */
|
||||
};
|
||||
|
||||
typedef struct subnet_mac_t
|
||||
{
|
||||
mac_t address;
|
||||
time_t lastseen;
|
||||
} subnet_mac_t;
|
||||
|
||||
typedef struct subnet_ipv4_t
|
||||
{
|
||||
ipv4_t address;
|
||||
int prefixlength;
|
||||
} subnet_ipv4_t;
|
||||
|
||||
typedef struct subnet_ipv6_t
|
||||
{
|
||||
ipv6_t address;
|
||||
int prefixlength;
|
||||
} subnet_ipv6_t;
|
||||
|
||||
#include "node.h"
|
||||
|
||||
typedef struct subnet_t {
|
||||
struct node_t *owner; /* the owner of this subnet */
|
||||
struct node_t *uplink; /* the uplink which we should send packets to for this subnet */
|
||||
|
||||
int type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */
|
||||
|
||||
/* And now for the actual subnet: */
|
||||
|
||||
union net
|
||||
{
|
||||
subnet_mac_t mac;
|
||||
subnet_ipv4_t ipv4;
|
||||
subnet_ipv6_t ipv6;
|
||||
} net;
|
||||
|
||||
void *data; /* Interface details */
|
||||
} subnet_t;
|
||||
|
||||
extern subnet_t *new_subnet(void);
|
||||
extern void free_subnet(subnet_t *);
|
||||
extern void init_subnets(void);
|
||||
extern void exit_subnets(void);
|
||||
extern avl_tree_t *new_subnet_tree(void);
|
||||
extern void free_subnet_tree(avl_tree_t *);
|
||||
extern void subnet_add(struct node_t *, subnet_t *);
|
||||
extern void subnet_del(struct node_t *, subnet_t *);
|
||||
extern char *net2str(subnet_t *);
|
||||
extern subnet_t *str2net(char *);
|
||||
extern subnet_t *lookup_subnet(struct node_t *, subnet_t *);
|
||||
extern subnet_t *lookup_subnet_mac(mac_t *);
|
||||
extern subnet_t *lookup_subnet_ipv4(ipv4_t *);
|
||||
extern subnet_t *lookup_subnet_ipv6(ipv6_t *);
|
||||
extern void dump_subnets(void);
|
||||
|
||||
#endif /* __TINC_SUBNET_H__ */
|
||||
97
lib/utils.c
97
lib/utils.c
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
utils.c -- gathering of some stupid small functions
|
||||
Copyright (C) 1999-2001 Ivo Timmermans <zarq@iname.com>
|
||||
2000,2001 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 1999-2003 Ivo Timmermans <zarq@iname.com>
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -18,15 +18,10 @@
|
|||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "system.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <utils.h>
|
||||
#include <syslog.h>
|
||||
#include <xalloc.h>
|
||||
#include "../src/logger.h"
|
||||
#include "utils.h"
|
||||
|
||||
#ifdef ENABLE_TRACING
|
||||
volatile int (cp_line[]) = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
|
@ -38,50 +33,70 @@ char *hexadecimals = "0123456789ABCDEF";
|
|||
|
||||
int charhex2bin(char c)
|
||||
{
|
||||
if(isdigit(c))
|
||||
return c - '0';
|
||||
else
|
||||
return toupper(c) - 'A' + 10;
|
||||
if(isdigit(c))
|
||||
return c - '0';
|
||||
else
|
||||
return toupper(c) - 'A' + 10;
|
||||
}
|
||||
|
||||
|
||||
void hex2bin(char *src, char *dst, int length)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<length; i++)
|
||||
dst[i] = charhex2bin(src[i*2])*16 + charhex2bin(src[i*2+1]);
|
||||
int i;
|
||||
for(i = 0; i < length; i++)
|
||||
dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]);
|
||||
}
|
||||
|
||||
void bin2hex(char *src, char *dst, int length)
|
||||
{
|
||||
int i;
|
||||
for(i=length-1; i>=0; i--)
|
||||
{
|
||||
dst[i*2+1] = hexadecimals[(unsigned char)src[i] & 15];
|
||||
dst[i*2] = hexadecimals[(unsigned char)src[i]>>4];
|
||||
}
|
||||
int i;
|
||||
for(i = length - 1; i >= 0; i--) {
|
||||
dst[i * 2 + 1] = hexadecimals[(unsigned char) src[i] & 15];
|
||||
dst[i * 2] = hexadecimals[(unsigned char) src[i] >> 4];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_TRACING
|
||||
void cp_trace()
|
||||
{
|
||||
syslog(LOG_DEBUG, "Checkpoint trace: %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d...",
|
||||
cp_file[(cp_index+15)%16], cp_line[(cp_index+15)%16],
|
||||
cp_file[(cp_index+14)%16], cp_line[(cp_index+14)%16],
|
||||
cp_file[(cp_index+13)%16], cp_line[(cp_index+13)%16],
|
||||
cp_file[(cp_index+12)%16], cp_line[(cp_index+12)%16],
|
||||
cp_file[(cp_index+11)%16], cp_line[(cp_index+11)%16],
|
||||
cp_file[(cp_index+10)%16], cp_line[(cp_index+10)%16],
|
||||
cp_file[(cp_index+9)%16], cp_line[(cp_index+9)%16],
|
||||
cp_file[(cp_index+8)%16], cp_line[(cp_index+8)%16],
|
||||
cp_file[(cp_index+7)%16], cp_line[(cp_index+7)%16],
|
||||
cp_file[(cp_index+6)%16], cp_line[(cp_index+6)%16],
|
||||
cp_file[(cp_index+5)%16], cp_line[(cp_index+5)%16],
|
||||
cp_file[(cp_index+4)%16], cp_line[(cp_index+4)%16],
|
||||
cp_file[(cp_index+3)%16], cp_line[(cp_index+3)%16],
|
||||
cp_file[(cp_index+2)%16], cp_line[(cp_index+2)%16],
|
||||
cp_file[(cp_index+1)%16], cp_line[(cp_index+1)%16],
|
||||
cp_file[cp_index], cp_line[cp_index]
|
||||
);
|
||||
logger(LOG_DEBUG, "Checkpoint trace: %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d <- %s:%d...",
|
||||
cp_file[(cp_index + 15) % 16], cp_line[(cp_index + 15) % 16],
|
||||
cp_file[(cp_index + 14) % 16], cp_line[(cp_index + 14) % 16],
|
||||
cp_file[(cp_index + 13) % 16], cp_line[(cp_index + 13) % 16],
|
||||
cp_file[(cp_index + 12) % 16], cp_line[(cp_index + 12) % 16],
|
||||
cp_file[(cp_index + 11) % 16], cp_line[(cp_index + 11) % 16],
|
||||
cp_file[(cp_index + 10) % 16], cp_line[(cp_index + 10) % 16],
|
||||
cp_file[(cp_index + 9) % 16], cp_line[(cp_index + 9) % 16],
|
||||
cp_file[(cp_index + 8) % 16], cp_line[(cp_index + 8) % 16],
|
||||
cp_file[(cp_index + 7) % 16], cp_line[(cp_index + 7) % 16],
|
||||
cp_file[(cp_index + 6) % 16], cp_line[(cp_index + 6) % 16],
|
||||
cp_file[(cp_index + 5) % 16], cp_line[(cp_index + 5) % 16],
|
||||
cp_file[(cp_index + 4) % 16], cp_line[(cp_index + 4) % 16],
|
||||
cp_file[(cp_index + 3) % 16], cp_line[(cp_index + 3) % 16],
|
||||
cp_file[(cp_index + 2) % 16], cp_line[(cp_index + 2) % 16],
|
||||
cp_file[(cp_index + 1) % 16], cp_line[(cp_index + 1) % 16],
|
||||
cp_file[cp_index], cp_line[cp_index]
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MINGW) || defined(HAVE_CYGWIN)
|
||||
#ifdef HAVE_CYGWIN
|
||||
#include <w32api/windows.h>
|
||||
#endif
|
||||
|
||||
char *winerror(int err) {
|
||||
static char buf[1024], *newline;
|
||||
|
||||
if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, sizeof(buf), NULL)) {
|
||||
strncpy(buf, _("(unable to format errormessage)"), sizeof(buf));
|
||||
};
|
||||
|
||||
if((newline = strchr(buf, '\r')))
|
||||
*newline = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
25
lib/utils.h
25
lib/utils.h
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
utils.h -- header file for utils.c
|
||||
Copyright (C) 1999-2002 Ivo Timmermans <ivo@o2w.nl>
|
||||
2000-2002 Guus Sliepen <guus@sliepen.warande.net>
|
||||
Copyright (C) 1999-2003 Ivo Timmermans <zarq@iname.com>
|
||||
2000-2003 Guus Sliepen <guus@sliepen.eu.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -21,25 +21,26 @@
|
|||
#ifndef __TINC_UTILS_H__
|
||||
#define __TINC_UTILS_H__
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#define min(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
#ifdef ENABLE_TRACING
|
||||
extern volatile int cp_line[];
|
||||
extern volatile char *cp_file[];
|
||||
extern volatile int cp_index;
|
||||
extern void cp_trace(void);
|
||||
|
||||
#define cp { cp_line[cp_index] = __LINE__; cp_file[cp_index] = __FILE__; cp_index++; cp_index %= 16; }
|
||||
#define ecp { fprintf(stderr, "Explicit checkpoint in %s line %d\n", __FILE__, __LINE__); }
|
||||
#define cp() { cp_line[cp_index] = __LINE__; cp_file[cp_index] = __FILE__; cp_index++; cp_index %= 16; }
|
||||
#define ecp() { fprintf(stderr, "Explicit checkpoint in %s line %d\n", __FILE__, __LINE__); }
|
||||
#else
|
||||
#define cp
|
||||
#define ecp
|
||||
#define cp_trace()
|
||||
#define cp()
|
||||
#define ecp()
|
||||
#define cp_trace()
|
||||
#endif
|
||||
|
||||
extern void hex2bin(char *src, char *dst, int length);
|
||||
extern void bin2hex(char *src, char *dst, int length);
|
||||
|
||||
#endif /* __TINC_UTILS_H__ */
|
||||
#ifdef HAVE_MINGW
|
||||
extern char *winerror(int);
|
||||
#define strerror(x) ((x)>0?strerror(x):winerror(GetLastError()))
|
||||
#endif
|
||||
|
||||
#endif /* __TINC_UTILS_H__ */
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ extern char *const xalloc_msg_memory_exhausted;
|
|||
/* FIXME: describe */
|
||||
extern void (*xalloc_fail_func) ();
|
||||
|
||||
void *xmalloc PARAMS ((size_t n));
|
||||
void *xmalloc_and_zero PARAMS ((size_t n));
|
||||
void *xmalloc PARAMS ((size_t n)) __attribute__ ((__malloc__));
|
||||
void *xmalloc_and_zero PARAMS ((size_t n)) __attribute__ ((__malloc__));
|
||||
void *xcalloc PARAMS ((size_t n, size_t s));
|
||||
void *xrealloc PARAMS ((void *p, size_t n));
|
||||
void *xrealloc PARAMS ((void *p, size_t n)) __attribute__ ((__malloc__));
|
||||
|
||||
char *xstrdup PARAMS ((const char *s));
|
||||
char *xstrdup PARAMS ((const char *s)) __attribute__ ((__malloc__));
|
||||
|
|
|
|||
|
|
@ -32,15 +32,7 @@ void *realloc ();
|
|||
void free ();
|
||||
#endif
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
#else
|
||||
# define textdomain(Domain)
|
||||
# define _(Text) Text
|
||||
#endif
|
||||
#define N_(Text) Text
|
||||
|
||||
#include "gettext.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue