Switch to K&R style indentation.

This commit is contained in:
Guus Sliepen 2002-09-09 21:25:28 +00:00
parent 5fc1ed17f4
commit f75dcef72a
44 changed files with 6039 additions and 6132 deletions

View file

@ -19,7 +19,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: conf.c,v 1.9.4.58 2002/09/09 19:39:55 guus Exp $ $Id: conf.c,v 1.9.4.59 2002/09/09 21:24:25 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -53,7 +53,7 @@ int pingtimeout = 0; /* seconds before timeout */
char *confbase = NULL; /* directory in which all config files are */ char *confbase = NULL; /* directory in which all config files are */
char *netname = NULL; /* name of the vpn network */ char *netname = NULL; /* name of the vpn network */
int config_compare(config_t *a, config_t *b) int config_compare(config_t * a, config_t * b)
{ {
int result; int result;
@ -70,54 +70,57 @@ int config_compare(config_t *a, config_t *b)
return strcmp(a->file, b->file); return strcmp(a->file, b->file);
} }
void init_configuration(avl_tree_t **config_tree) void init_configuration(avl_tree_t ** config_tree)
{ {
cp(); cp();
*config_tree = avl_alloc_tree((avl_compare_t)config_compare, (avl_action_t)free_config);
cp(); *config_tree = avl_alloc_tree((avl_compare_t) config_compare, (avl_action_t) free_config);
} }
void exit_configuration(avl_tree_t **config_tree) void exit_configuration(avl_tree_t ** config_tree)
{ {
cp(); cp();
avl_delete_tree(*config_tree); avl_delete_tree(*config_tree);
*config_tree = NULL; *config_tree = NULL;
cp();
} }
config_t *new_config(void) config_t *new_config(void)
{ {
config_t *cfg;
cp(); cp();
cfg = (config_t *)xmalloc_and_zero(sizeof(*cfg));
return cfg; return (config_t *) xmalloc_and_zero(sizeof(config_t));
} }
void free_config(config_t *cfg) void free_config(config_t * cfg)
{ {
cp(); cp();
if(cfg->variable) if(cfg->variable)
free(cfg->variable); free(cfg->variable);
if(cfg->value) if(cfg->value)
free(cfg->value); free(cfg->value);
if(cfg->file) if(cfg->file)
free(cfg->file); free(cfg->file);
free(cfg); free(cfg);
cp();
} }
void config_add(avl_tree_t *config_tree, config_t *cfg) void config_add(avl_tree_t * config_tree, config_t * cfg)
{ {
cp(); cp();
avl_insert(config_tree, cfg); avl_insert(config_tree, cfg);
cp();
} }
config_t *lookup_config(avl_tree_t *config_tree, char *variable) config_t *lookup_config(avl_tree_t * config_tree, char *variable)
{ {
config_t cfg, *found; config_t cfg, *found;
cp(); cp();
cfg.variable = variable; cfg.variable = variable;
cfg.file = ""; cfg.file = "";
cfg.line = 0; cfg.line = 0;
@ -133,18 +136,19 @@ config_t *lookup_config(avl_tree_t *config_tree, char *variable)
return found; return found;
} }
config_t *lookup_config_next(avl_tree_t *config_tree, config_t *cfg) config_t *lookup_config_next(avl_tree_t * config_tree, config_t * cfg)
{ {
avl_node_t *node; avl_node_t *node;
config_t *found; config_t *found;
cp(); cp();
node = avl_search_node(config_tree, cfg); node = avl_search_node(config_tree, cfg);
if(node) if(node) {
{ if(node->next) {
if(node->next) found = (config_t *) node->next->data;
{
found = (config_t *)node->next->data;
if(!strcasecmp(found->variable, cfg->variable)) if(!strcasecmp(found->variable, cfg->variable))
return found; return found;
} }
@ -153,19 +157,17 @@ config_t *lookup_config_next(avl_tree_t *config_tree, config_t *cfg)
return NULL; return NULL;
} }
int get_config_bool(config_t *cfg, int *result) int get_config_bool(config_t * cfg, int *result)
{ {
cp(); cp();
if(!cfg) if(!cfg)
return 0; return 0;
if(!strcasecmp(cfg->value, "yes")) if(!strcasecmp(cfg->value, "yes")) {
{
*result = 1; *result = 1;
return 1; return 1;
} } else if(!strcasecmp(cfg->value, "no")) {
else if(!strcasecmp(cfg->value, "no"))
{
*result = 0; *result = 0;
return 1; return 1;
} }
@ -176,9 +178,10 @@ int get_config_bool(config_t *cfg, int *result)
return 0; return 0;
} }
int get_config_int(config_t *cfg, int *result) int get_config_int(config_t * cfg, int *result)
{ {
cp(); cp();
if(!cfg) if(!cfg)
return 0; return 0;
@ -187,67 +190,74 @@ int get_config_int(config_t *cfg, int *result)
syslog(LOG_ERR, _("Integer expected for configuration variable %s in %s line %d"), syslog(LOG_ERR, _("Integer expected for configuration variable %s in %s line %d"),
cfg->variable, cfg->file, cfg->line); cfg->variable, cfg->file, cfg->line);
return 0; return 0;
} }
int get_config_string(config_t *cfg, char **result) int get_config_string(config_t * cfg, char **result)
{ {
cp(); cp();
if(!cfg) if(!cfg)
return 0; return 0;
*result = xstrdup(cfg->value); *result = xstrdup(cfg->value);
return 1; return 1;
} }
int get_config_address(config_t *cfg, struct addrinfo **result) int get_config_address(config_t * cfg, struct addrinfo **result)
{ {
struct addrinfo *ai; struct addrinfo *ai;
cp(); cp();
if(!cfg) if(!cfg)
return 0; return 0;
ai = str2addrinfo(cfg->value, NULL, 0); ai = str2addrinfo(cfg->value, NULL, 0);
if(ai) if(ai) {
{
*result = ai; *result = ai;
return 1; return 1;
} }
syslog(LOG_ERR, _("Hostname or IP address expected for configuration variable %s in %s line %d"), syslog(LOG_ERR, _("Hostname or IP address expected for configuration variable %s in %s line %d"),
cfg->variable, cfg->file, cfg->line); cfg->variable, cfg->file, cfg->line);
return 0; return 0;
} }
int get_config_port(config_t *cfg, port_t *result) int get_config_port(config_t * cfg, port_t * result)
{ {
cp(); cp();
if(!cfg) if(!cfg)
return 0; return 0;
if(sscanf(cfg->value, "%hu", result) == 1) if(sscanf(cfg->value, "%hu", result) == 1) {
{
*result = htons(*result); *result = htons(*result);
return 1; return 1;
} }
syslog(LOG_ERR, _("Port number expected for configuration variable %s in %s line %d"), syslog(LOG_ERR, _("Port number expected for configuration variable %s in %s line %d"),
cfg->variable, cfg->file, cfg->line); cfg->variable, cfg->file, cfg->line);
return 0; return 0;
} }
int get_config_subnet(config_t *cfg, subnet_t **result) int get_config_subnet(config_t * cfg, subnet_t ** result)
{ {
subnet_t *subnet; subnet_t *subnet;
cp(); cp();
if(!cfg) if(!cfg)
return 0; return 0;
subnet = str2net(cfg->value); subnet = str2net(cfg->value);
if(!subnet) if(!subnet) {
{
syslog(LOG_ERR, _("Subnet expected for configuration variable %s in %s line %d"), syslog(LOG_ERR, _("Subnet expected for configuration variable %s in %s line %d"),
cfg->variable, cfg->file, cfg->line); cfg->variable, cfg->file, cfg->line);
return 0; return 0;
@ -255,10 +265,11 @@ int get_config_subnet(config_t *cfg, subnet_t **result)
/* Teach newbies what subnets are... */ /* Teach newbies what subnets are... */
if(((subnet->type == SUBNET_IPV4) && maskcheck(&subnet->net.ipv4.address, subnet->net.ipv4.prefixlength, sizeof(ipv4_t))) if(((subnet->type == SUBNET_IPV4)
|| ((subnet->type == SUBNET_IPV6) && maskcheck(&subnet->net.ipv6.address, subnet->net.ipv6.prefixlength, sizeof(ipv6_t)))) && maskcheck(&subnet->net.ipv4.address, subnet->net.ipv4.prefixlength, sizeof(ipv4_t)))
{ || ((subnet->type == SUBNET_IPV6)
syslog(LOG_ERR, _("Network address and prefix length do not match for configuration variable %s in %s line %d"), && maskcheck(&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); cfg->variable, cfg->file, cfg->line);
free(subnet); free(subnet);
return 0; return 0;
@ -279,29 +290,22 @@ int get_config_subnet(config_t *cfg, subnet_t **result)
given, and buf needs to be expanded, the var pointed to by buflen given, and buf needs to be expanded, the var pointed to by buflen
will be increased. will be increased.
*/ */
char *readline(FILE *fp, char **buf, size_t *buflen) char *readline(FILE * fp, char **buf, size_t * buflen)
{ {
char *newline = NULL; char *newline = NULL;
char *p; char *p;
char *line; /* The array that contains everything that has been read char *line; /* The array that contains everything that has been read so far */
so far */ char *idx; /* Read into this pointer, which points to an offset within line */
char *idx; /* Read into this pointer, which points to an offset size_t size, newsize; /* The size of the current array pointed to by line */
within line */ size_t maxlen; /* Maximum number of characters that may be read with fgets. This is newsize - oldsize. */
size_t size, newsize; /* The size of the current array pointed to by
line */
size_t maxlen; /* Maximum number of characters that may be read with
fgets. This is newsize - oldsize. */
if(feof(fp)) if(feof(fp))
return NULL; return NULL;
if(buf && buflen) if(buf && buflen) {
{
size = *buflen; size = *buflen;
line = *buf; line = *buf;
} } else {
else
{
size = 100; size = 100;
line = xmalloc(size); line = xmalloc(size);
} }
@ -309,43 +313,39 @@ char *readline(FILE *fp, char **buf, size_t *buflen)
maxlen = size; maxlen = size;
idx = line; idx = line;
*idx = 0; *idx = 0;
for(;;)
{ for(;;) {
errno = 0; errno = 0;
p = fgets(idx, maxlen, fp); p = fgets(idx, maxlen, fp);
if(!p) /* EOF or error */
{ if(!p) { /* EOF or error */
if(feof(fp)) if(feof(fp))
break; break;
/* otherwise: error; let the calling function print an error /* otherwise: error; let the calling function print an error message if applicable */
message if applicable */
free(line); free(line);
return NULL; return NULL;
} }
newline = strchr(p, '\n'); newline = strchr(p, '\n');
if(!newline)
/* We haven't yet read everything to the end of the line */ if(!newline) { /* We haven't yet read everything to the end of the line */
{
newsize = size << 1; newsize = size << 1;
line = xrealloc(line, newsize); line = xrealloc(line, newsize);
idx = &line[size - 1]; idx = &line[size - 1];
maxlen = newsize - size + 1; maxlen = newsize - size + 1;
size = newsize; size = newsize;
} } else {
else
{
*newline = '\0'; /* kill newline */ *newline = '\0'; /* kill newline */
break; /* yay */ break; /* yay */
} }
} }
if(buf && buflen) if(buf && buflen) {
{
*buflen = size; *buflen = size;
*buf = line; *buf = line;
} }
return line; return line;
} }
@ -353,7 +353,7 @@ char *readline(FILE *fp, char **buf, size_t *buflen)
Parse a configuration file and put the results in the configuration tree Parse a configuration file and put the results in the configuration tree
starting at *base. starting at *base.
*/ */
int read_config_file(avl_tree_t *config_tree, const char *fname) int read_config_file(avl_tree_t * config_tree, const char *fname)
{ {
int err = -2; /* Parse error */ int err = -2; /* Parse error */
FILE *fp; FILE *fp;
@ -364,29 +364,27 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
size_t bufsize; size_t bufsize;
cp(); cp();
fp = fopen (fname, "r");
if(!fp) fp = fopen(fname, "r");
{
syslog(LOG_ERR, _("Cannot open config file %s: %s"), fname, strerror(errno)); if(!fp) {
syslog(LOG_ERR, _("Cannot open config file %s: %s"), fname,
strerror(errno));
return -3; return -3;
} }
bufsize = 100; bufsize = 100;
buffer = xmalloc(bufsize); buffer = xmalloc(bufsize);
for(;;) for(;;) {
{
line = readline(fp, &buffer, &bufsize); line = readline(fp, &buffer, &bufsize);
if(!line) if(!line) {
{
err = -1; err = -1;
break; break;
} }
if(feof(fp)) if(feof(fp)) {
{
err = 0; err = 0;
break; break;
} }
@ -404,12 +402,10 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
if(!strcmp(variable, "-----BEGIN")) if(!strcmp(variable, "-----BEGIN"))
ignore = 1; ignore = 1;
if(!ignore) if(!ignore) {
{
value = strtok(NULL, "\t\n\r ="); value = strtok(NULL, "\t\n\r =");
if(!value || value[0] == '#') if(!value || value[0] == '#') {
{
syslog(LOG_ERR, _("No value for variable `%s' on line %d while reading config file %s"), syslog(LOG_ERR, _("No value for variable `%s' on line %d while reading config file %s"),
variable, lineno, fname); variable, lineno, fname);
break; break;
@ -429,8 +425,8 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
} }
free(buffer); free(buffer);
fclose (fp); fclose(fp);
cp();
return err; return err;
} }
@ -438,19 +434,22 @@ int read_server_config()
{ {
char *fname; char *fname;
int x; int x;
cp(); cp();
asprintf(&fname, "%s/tinc.conf", confbase); asprintf(&fname, "%s/tinc.conf", confbase);
x = read_config_file(config_tree, fname); x = read_config_file(config_tree, fname);
if(x == -1) /* System error: complain */
{ if(x == -1) { /* System error: complain */
syslog(LOG_ERR, _("Failed to read `%s': %s"), fname, strerror(errno)); syslog(LOG_ERR, _("Failed to read `%s': %s"), fname, strerror(errno));
} }
free(fname); free(fname);
cp();
return x; return x;
} }
int isadir(const char* f) int isadir(const char *f)
{ {
struct stat s; struct stat s;
@ -468,8 +467,7 @@ int is_safe_path(const char *file)
struct stat s; struct stat s;
char l[MAXBUFSIZE]; char l[MAXBUFSIZE];
if(*file != '/') if(*file != '/') {
{
syslog(LOG_ERR, _("`%s' is not an absolute path"), file); syslog(LOG_ERR, _("`%s' is not an absolute path"), file);
return 0; return 0;
} }
@ -483,28 +481,25 @@ int is_safe_path(const char *file)
*p = '\0'; *p = '\0';
f = file; f = file;
check1: check1:
if(lstat(f, &s) < 0) if(lstat(f, &s) < 0) {
{
syslog(LOG_ERR, _("Couldn't stat `%s': %s"), f, strerror(errno)); syslog(LOG_ERR, _("Couldn't stat `%s': %s"), f, strerror(errno));
return 0; return 0;
} }
if(s.st_uid != geteuid()) if(s.st_uid != geteuid()) {
{
syslog(LOG_ERR, _("`%s' is owned by UID %d instead of %d"), syslog(LOG_ERR, _("`%s' is owned by UID %d instead of %d"),
f, s.st_uid, geteuid()); f, s.st_uid, geteuid());
return 0; return 0;
} }
if(S_ISLNK(s.st_mode)) if(S_ISLNK(s.st_mode)) {
{ syslog(LOG_WARNING, _("Warning: `%s' is a symlink"), f);
syslog(LOG_WARNING, _("Warning: `%s' is a symlink"),
f);
if(readlink(f, l, MAXBUFSIZE) < 0) if(readlink(f, l, MAXBUFSIZE) < 0) {
{ syslog(LOG_ERR, _("Unable to read symbolic link `%s': %s"), f,
syslog(LOG_ERR, _("Unable to read symbolic link `%s': %s"), f, strerror(errno)); strerror(errno));
return 0; return 0;
} }
@ -516,8 +511,7 @@ check1:
f = file; f = file;
check2: check2:
if(lstat(f, &s) < 0 && errno != ENOENT) if(lstat(f, &s) < 0 && errno != ENOENT) {
{
syslog(LOG_ERR, _("Couldn't stat `%s': %s"), f, strerror(errno)); syslog(LOG_ERR, _("Couldn't stat `%s': %s"), f, strerror(errno));
return 0; return 0;
} }
@ -525,21 +519,18 @@ check2:
if(errno == ENOENT) if(errno == ENOENT)
return 1; return 1;
if(s.st_uid != geteuid()) if(s.st_uid != geteuid()) {
{
syslog(LOG_ERR, _("`%s' is owned by UID %d instead of %d"), syslog(LOG_ERR, _("`%s' is owned by UID %d instead of %d"),
f, s.st_uid, geteuid()); f, s.st_uid, geteuid());
return 0; return 0;
} }
if(S_ISLNK(s.st_mode)) if(S_ISLNK(s.st_mode)) {
{ syslog(LOG_WARNING, _("Warning: `%s' is a symlink"), f);
syslog(LOG_WARNING, _("Warning: `%s' is a symlink"),
f);
if(readlink(f, l, MAXBUFSIZE) < 0) if(readlink(f, l, MAXBUFSIZE) < 0) {
{ syslog(LOG_ERR, _("Unable to read symbolic link `%s': %s"), f,
syslog(LOG_ERR, _("Unable to read symbolic link `%s': %s"), f, strerror(errno)); strerror(errno));
return 0; return 0;
} }
@ -547,33 +538,29 @@ check2:
goto check2; goto check2;
} }
if(s.st_mode & 0007) if(s.st_mode & 0007) {
{
/* Accessible by others */ /* Accessible by others */
syslog(LOG_ERR, _("`%s' has unsecure permissions"), syslog(LOG_ERR, _("`%s' has unsecure permissions"), f);
f);
return 0; return 0;
} }
return 1; return 1;
} }
FILE *ask_and_safe_open(const char* filename, const char* what, const char* mode) FILE *ask_and_safe_open(const char *filename, const char *what,
const char *mode)
{ {
FILE *r; FILE *r;
char *directory; char *directory;
char *fn; char *fn;
/* Check stdin and stdout */ /* Check stdin and stdout */
if(!isatty(0) || !isatty(1)) if(!isatty(0) || !isatty(1)) {
{
/* Argh, they are running us from a script or something. Write /* Argh, they are running us from a script or something. Write
the files to the current directory and let them burn in hell the files to the current directory and let them burn in hell
for ever. */ for ever. */
fn = xstrdup(filename); fn = xstrdup(filename);
} } else {
else
{
/* Ask for a file and/or directory name. */ /* Ask for a file and/or directory name. */
fprintf(stdout, _("Please enter a file to save %s to [%s]: "), fprintf(stdout, _("Please enter a file to save %s to [%s]: "),
what, filename); what, filename);
@ -581,9 +568,9 @@ FILE *ask_and_safe_open(const char* filename, const char* what, const char* mode
fn = readline(stdin, NULL, NULL); fn = readline(stdin, NULL, NULL);
if(!fn) if(!fn) {
{ fprintf(stderr, _("Error while reading stdin: %s\n"),
fprintf(stderr, _("Error while reading stdin: %s\n"), strerror(errno)); strerror(errno));
return NULL; return NULL;
} }
@ -592,8 +579,7 @@ FILE *ask_and_safe_open(const char* filename, const char* what, const char* mode
fn = xstrdup(filename); fn = xstrdup(filename);
} }
if(!strchr(fn, '/') || fn[0] != '/') if(!strchr(fn, '/') || fn[0] != '/') {
{
/* The directory is a relative path or a filename. */ /* The directory is a relative path or a filename. */
char *p; char *p;
@ -610,8 +596,7 @@ FILE *ask_and_safe_open(const char* filename, const char* what, const char* mode
r = fopen(fn, mode); r = fopen(fn, mode);
if(!r) if(!r) {
{
fprintf(stderr, _("Error opening file `%s': %s\n"), fprintf(stderr, _("Error opening file `%s': %s\n"),
fn, strerror(errno)); fn, strerror(errno));
free(fn); free(fn);
@ -619,12 +604,9 @@ FILE *ask_and_safe_open(const char* filename, const char* what, const char* mode
} }
/* Then check the file for nasty attacks */ /* Then check the file for nasty attacks */
if(!is_safe_path(fn)) /* Do not permit any directories that are if(!is_safe_path(fn)) { /* Do not permit any directories that are readable or writeable by other users. */
readable or writeable by other users. */
{
fprintf(stderr, _("The file `%s' (or any of the leading directories) has unsafe permissions.\n" fprintf(stderr, _("The file `%s' (or any of the leading directories) has unsafe permissions.\n"
"I will not create or overwrite this file.\n"), "I will not create or overwrite this file.\n"), fn);
fn);
fclose(r); fclose(r);
free(fn); free(fn);
return NULL; return NULL;

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: conf.h,v 1.6.4.33 2002/06/21 10:11:12 guus Exp $ $Id: conf.h,v 1.6.4.34 2002/09/09 21:24:31 guus Exp $
*/ */
#ifndef __TINC_CONF_H__ #ifndef __TINC_CONF_H__
@ -64,7 +64,7 @@ extern int get_config_subnet(config_t *, struct subnet_t **);
extern int read_config_file(avl_tree_t *, const char *); extern int read_config_file(avl_tree_t *, const char *);
extern int read_server_config(void); extern int read_server_config(void);
extern FILE *ask_and_safe_open(const char*, const char*, const char *); extern FILE *ask_and_safe_open(const char *, const char *, const char *);
extern int is_safe_path(const char *); extern int is_safe_path(const char *);
#endif /* __TINC_CONF_H__ */ #endif /* __TINC_CONF_H__ */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: connection.c,v 1.1.2.32 2002/09/09 19:39:58 guus Exp $ $Id: connection.c,v 1.1.2.33 2002/09/09 21:24:31 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -43,7 +43,7 @@
avl_tree_t *connection_tree; /* Meta connections */ avl_tree_t *connection_tree; /* Meta connections */
connection_t *broadcast; connection_t *broadcast;
int connection_compare(connection_t *a, connection_t *b) int connection_compare(connection_t * a, connection_t * b)
{ {
return a - b; return a - b;
} }
@ -51,94 +51,101 @@ int connection_compare(connection_t *a, connection_t *b)
void init_connections(void) void init_connections(void)
{ {
cp(); cp();
connection_tree = avl_alloc_tree((avl_compare_t)connection_compare, NULL);
cp(); connection_tree = avl_alloc_tree((avl_compare_t) connection_compare, NULL);
broadcast = new_connection(); broadcast = new_connection();
broadcast->name = xstrdup(_("everyone")); broadcast->name = xstrdup(_("everyone"));
broadcast->hostname = xstrdup(_("BROADCAST")); broadcast->hostname = xstrdup(_("BROADCAST"));
cp();
} }
void exit_connections(void) void exit_connections(void)
{ {
cp(); cp();
avl_delete_tree(connection_tree); avl_delete_tree(connection_tree);
cp();
free_connection(broadcast); free_connection(broadcast);
cp();
} }
connection_t *new_connection(void) connection_t *new_connection(void)
{ {
connection_t *c; connection_t *c;
cp(); cp();
c = (connection_t *)xmalloc_and_zero(sizeof(connection_t));
c = (connection_t *) xmalloc_and_zero(sizeof(connection_t));
if(!c) if(!c)
return NULL; return NULL;
gettimeofday(&c->start, NULL); gettimeofday(&c->start, NULL);
cp();
return c; return c;
} }
void free_connection(connection_t *c) void free_connection(connection_t * c)
{ {
cp(); cp();
if(c->hostname) if(c->hostname)
free(c->hostname); free(c->hostname);
if(c->inkey) if(c->inkey)
free(c->inkey); free(c->inkey);
if(c->outkey) if(c->outkey)
free(c->outkey); free(c->outkey);
if(c->mychallenge) if(c->mychallenge)
free(c->mychallenge); free(c->mychallenge);
if(c->hischallenge) if(c->hischallenge)
free(c->hischallenge); free(c->hischallenge);
free(c); free(c);
cp();
} }
void connection_add(connection_t *c) void connection_add(connection_t * c)
{ {
cp(); cp();
avl_insert(connection_tree, c); avl_insert(connection_tree, c);
cp();
} }
void connection_del(connection_t *c) void connection_del(connection_t * c)
{ {
cp(); cp();
avl_delete(connection_tree, c); avl_delete(connection_tree, c);
cp();
} }
void dump_connections(void) void dump_connections(void)
{ {
avl_node_t *node; avl_node_t *node;
connection_t *c; connection_t *c;
cp(); cp();
syslog(LOG_DEBUG, _("Connections:")); syslog(LOG_DEBUG, _("Connections:"));
for(node = connection_tree->head; node; node = node->next) for(node = connection_tree->head; node; node = node->next) {
{ c = (connection_t *) node->data;
c = (connection_t *)node->data;
syslog(LOG_DEBUG, _(" %s at %s options %lx socket %d status %04x"), syslog(LOG_DEBUG, _(" %s at %s options %lx socket %d status %04x"),
c->name, c->hostname, c->options, c->socket, c->status); c->name, c->hostname, c->options, c->socket, c->status);
} }
syslog(LOG_DEBUG, _("End of connections.")); syslog(LOG_DEBUG, _("End of connections."));
cp();
} }
int read_connection_config(connection_t *c) int read_connection_config(connection_t * c)
{ {
char *fname; char *fname;
int x; int x;
cp(); cp();
asprintf(&fname, "%s/hosts/%s", confbase, c->name); asprintf(&fname, "%s/hosts/%s", confbase, c->name);
x = read_config_file(c->config_tree, fname); x = read_config_file(c->config_tree, fname);
free(fname); free(fname);
cp();
return x; return x;
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: connection.h,v 1.1.2.30 2002/09/04 16:26:44 guus Exp $ $Id: connection.h,v 1.1.2.31 2002/09/09 21:24:31 guus Exp $
*/ */
#ifndef __TINC_CONNECTION_H__ #ifndef __TINC_CONNECTION_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.1.2.1 2002/07/11 12:57:06 guus Exp $ $Id: device.c,v 1.1.2.2 2002/09/09 21:25:18 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -53,21 +53,17 @@ int setup_device(void)
{ {
struct ifreq ifr; struct ifreq ifr;
cp cp if(!get_config_string(lookup_config(config_tree, "Device"), &device))
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
device = DEFAULT_DEVICE; device = DEFAULT_DEVICE;
if(!get_config_string(lookup_config(config_tree, "Interface"), &interface)) if(!get_config_string(lookup_config(config_tree, "Interface"), &interface))
interface = rindex(device, '/')?rindex(device, '/')+1:device; interface = rindex(device, '/') ? rindex(device, '/') + 1 : device;
cp cp if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0)
{
syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno));
return -1; return -1;
} }
cp cp
/* Set default MAC address for ethertap devices */ /* Set default MAC address for ethertap devices */
mymac.type = SUBNET_MAC; mymac.type = SUBNET_MAC;
mymac.net.mac.address.x[0] = 0xfe; mymac.net.mac.address.x[0] = 0xfe;
mymac.net.mac.address.x[1] = 0xfd; mymac.net.mac.address.x[1] = 0xfd;
@ -79,23 +75,20 @@ cp
device_info = _("Stub device for Cygwin environment"); device_info = _("Stub device for Cygwin environment");
syslog(LOG_INFO, _("%s is a %s"), device, device_info); syslog(LOG_INFO, _("%s is a %s"), device, device_info);
cp cp return 0;
return 0;
} }
void close_device(void) void close_device(void)
{ {
cp cp close(device_fd);
close(device_fd);
} }
int read_packet(vpn_packet_t *packet) int read_packet(vpn_packet_t * packet)
{ {
int lenin; int lenin;
cp cp if((lenin = read(device_fd, packet->data, MTU)) <= 0) {
if((lenin = read(device_fd, packet->data, MTU)) <= 0) syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
{ device, strerror(errno));
syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno));
return -1; return -1;
} }
@ -103,38 +96,33 @@ cp
device_total_in += packet->len; device_total_in += packet->len;
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC) {
{ syslog(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len,
syslog(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); device_info);
} }
return 0; return 0;
cp cp}
}
int write_packet(vpn_packet_t *packet) int write_packet(vpn_packet_t * packet)
{ {
cp cp if(debug_lvl >= DEBUG_TRAFFIC)
if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"), syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"),
packet->len, device_info); packet->len, device_info);
if(write(device_fd, packet->data, packet->len) < 0) if(write(device_fd, packet->data, packet->len) < 0) {
{ syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device,
syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); strerror(errno));
return -1; return -1;
} }
device_total_out += packet->len; device_total_out += packet->len;
cp cp return 0;
return 0;
} }
void dump_device_stats(void) void dump_device_stats(void)
{ {
cp cp syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in);
syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out);
cp cp}
}

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.1.2.2 2002/06/21 10:11:34 guus Exp $ $Id: device.c,v 1.1.2.3 2002/09/09 21:25:19 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -58,22 +58,17 @@ extern subnet_t mymac;
*/ */
int setup_device(void) int setup_device(void)
{ {
cp cp if(!get_config_string(lookup_config(config_tree, "Device"), &device))
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
device = DEFAULT_DEVICE; device = DEFAULT_DEVICE;
if(!get_config_string(lookup_config(config_tree, "Interface"), &interface)) if(!get_config_string(lookup_config(config_tree, "Interface"), &interface))
interface = rindex(device, '/')?rindex(device, '/')+1:device; interface = rindex(device, '/') ? rindex(device, '/') + 1 : device;
cp cp if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0)
{
syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno));
return -1; return -1;
} }
cp cp
/* Set default MAC address for ethertap devices */ /* Set default MAC address for ethertap devices */
mymac.type = SUBNET_MAC; mymac.type = SUBNET_MAC;
mymac.net.mac.address.x[0] = 0xfe; mymac.net.mac.address.x[0] = 0xfe;
mymac.net.mac.address.x[1] = 0xfd; mymac.net.mac.address.x[1] = 0xfd;
@ -85,27 +80,24 @@ cp
device_info = _("MacOS/X tun device"); device_info = _("MacOS/X tun device");
syslog(LOG_INFO, _("%s is a %s"), device, device_info); syslog(LOG_INFO, _("%s is a %s"), device, device_info);
cp cp return 0;
return 0;
} }
void close_device(void) void close_device(void)
{ {
cp cp close(device_fd);
close(device_fd);
} }
/* /*
read, encrypt and send data that is read, encrypt and send data that is
available through the ethertap device available through the ethertap device
*/ */
int read_packet(vpn_packet_t *packet) int read_packet(vpn_packet_t * packet)
{ {
int lenin; int lenin;
cp cp if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) {
if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
{ device, strerror(errno));
syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno));
return -1; return -1;
} }
@ -123,31 +115,26 @@ cp
packet->len, device_info); packet->len, device_info);
return 0; return 0;
cp cp}
}
int write_packet(vpn_packet_t *packet) int write_packet(vpn_packet_t * packet)
{ {
cp cp if(debug_lvl >= DEBUG_TRAFFIC)
if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"), syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"),
packet->len, device_info); packet->len, device_info);
if(write(device_fd, packet->data + 14, packet->len - 14) < 0) if(write(device_fd, packet->data + 14, packet->len - 14) < 0) {
{ syslog(LOG_ERR, _("Error while writing to %s %s: %s"), device_info,
syslog(LOG_ERR, _("Error while writing to %s %s: %s"), device_info, device, strerror(errno)); device, strerror(errno));
return -1; return -1;
} }
device_total_out += packet->len; device_total_out += packet->len;
cp cp}
}
void dump_device_stats(void) void dump_device_stats(void)
{ {
cp cp syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in);
syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out);
cp cp}
}

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.h,v 1.1.2.6 2002/06/21 10:11:12 guus Exp $ $Id: device.h,v 1.1.2.7 2002/09/09 21:24:31 guus Exp $
*/ */
#ifndef __TINC_DEVICE_H__ #ifndef __TINC_DEVICE_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: edge.c,v 1.1.2.15 2002/09/09 19:39:58 guus Exp $ $Id: edge.c,v 1.1.2.16 2002/09/09 21:24:31 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -43,12 +43,12 @@
avl_tree_t *edge_weight_tree; /* Tree with all edges, sorted on weight */ avl_tree_t *edge_weight_tree; /* Tree with all edges, sorted on weight */
int edge_compare(edge_t *a, edge_t *b) int edge_compare(edge_t * a, edge_t * b)
{ {
return strcmp(a->to->name, b->to->name); return strcmp(a->to->name, b->to->name);
} }
int edge_weight_compare(edge_t *a, edge_t *b) int edge_weight_compare(edge_t * a, edge_t * b)
{ {
int result; int result;
@ -68,76 +68,78 @@ int edge_weight_compare(edge_t *a, edge_t *b)
void init_edges(void) void init_edges(void)
{ {
cp(); cp();
edge_weight_tree = avl_alloc_tree((avl_compare_t)edge_weight_compare, NULL);
cp(); edge_weight_tree =
avl_alloc_tree((avl_compare_t) edge_weight_compare, NULL);
} }
avl_tree_t *new_edge_tree(void) avl_tree_t *new_edge_tree(void)
{ {
cp(); cp();
return avl_alloc_tree((avl_compare_t)edge_compare, NULL);
cp(); return avl_alloc_tree((avl_compare_t) edge_compare, NULL);
} }
void free_edge_tree(avl_tree_t *edge_tree) void free_edge_tree(avl_tree_t * edge_tree)
{ {
cp(); cp();
avl_delete_tree(edge_tree); avl_delete_tree(edge_tree);
cp();
} }
void exit_edges(void) void exit_edges(void)
{ {
cp(); cp();
avl_delete_tree(edge_weight_tree); avl_delete_tree(edge_weight_tree);
cp();
} }
/* Creation and deletion of connection elements */ /* Creation and deletion of connection elements */
edge_t *new_edge(void) edge_t *new_edge(void)
{ {
edge_t *e;
cp(); cp();
e = (edge_t *)xmalloc_and_zero(sizeof(*e));
cp(); return (edge_t *) xmalloc_and_zero(sizeof(edge_t));
return e;
} }
void free_edge(edge_t *e) void free_edge(edge_t * e)
{ {
cp(); cp();
free(e); free(e);
cp();
} }
void edge_add(edge_t *e) void edge_add(edge_t * e)
{ {
cp(); cp();
avl_insert(edge_weight_tree, e); avl_insert(edge_weight_tree, e);
avl_insert(e->from->edge_tree, e); avl_insert(e->from->edge_tree, e);
cp();
e->reverse = lookup_edge(e->to, e->from); e->reverse = lookup_edge(e->to, e->from);
if(e->reverse) if(e->reverse)
e->reverse->reverse = e; e->reverse->reverse = e;
cp();
} }
void edge_del(edge_t *e) void edge_del(edge_t * e)
{ {
cp(); cp();
if(e->reverse) if(e->reverse)
e->reverse->reverse = NULL; e->reverse->reverse = NULL;
cp();
avl_delete(edge_weight_tree, e);
avl_delete(e->from->edge_tree, e); avl_delete(e->from->edge_tree, e);
cp(); avl_delete(edge_weight_tree, e);
} }
edge_t *lookup_edge(node_t *from, node_t *to) edge_t *lookup_edge(node_t * from, node_t * to)
{ {
edge_t v; edge_t v;
cp(); cp();
v.from = from; v.from = from;
v.to = to; v.to = to;
@ -150,23 +152,21 @@ void dump_edges(void)
node_t *n; node_t *n;
edge_t *e; edge_t *e;
char *address; char *address;
cp(); cp();
syslog(LOG_DEBUG, _("Edges:")); syslog(LOG_DEBUG, _("Edges:"));
for(node = node_tree->head; node; node = node->next) for(node = node_tree->head; node; node = node->next) {
{ n = (node_t *) node->data;
n = (node_t *)node->data; for(node2 = n->edge_tree->head; node2; node2 = node2->next) {
for(node2 = n->edge_tree->head; node2; node2 = node2->next) e = (edge_t *) node2->data;
{
e = (edge_t *)node2->data;
address = sockaddr2hostname(&e->address); address = sockaddr2hostname(&e->address);
syslog(LOG_DEBUG, _(" %s to %s at %s options %lx weight %d"), syslog(LOG_DEBUG, _(" %s to %s at %s options %lx weight %d"),
e->from->name, e->to->name, address, e->from->name, e->to->name, address, e->options, e->weight);
e->options, e->weight);
free(address); free(address);
} }
} }
syslog(LOG_DEBUG, _("End of edges.")); syslog(LOG_DEBUG, _("End of edges."));
cp();
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: edge.h,v 1.1.2.10 2002/09/06 10:23:52 guus Exp $ $Id: edge.h,v 1.1.2.11 2002/09/09 21:24:31 guus Exp $
*/ */
#ifndef __TINC_EDGE_H__ #ifndef __TINC_EDGE_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: event.c,v 1.1.4.4 2002/09/09 19:39:58 guus Exp $ $Id: event.c,v 1.1.4.5 2002/09/09 21:24:31 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -38,73 +38,74 @@ extern time_t now;
int id; int id;
int event_compare(event_t *a, event_t *b) int event_compare(event_t * a, event_t * b)
{ {
if(a->time > b->time) if(a->time > b->time)
return 1; return 1;
if(a->time < b->time) if(a->time < b->time)
return -1; return -1;
return a->id - b->id; return a->id - b->id;
} }
void init_events(void) void init_events(void)
{ {
cp(); cp();
event_tree = avl_alloc_tree((avl_compare_t)event_compare, NULL);
cp(); event_tree = avl_alloc_tree((avl_compare_t) event_compare, NULL);
} }
void exit_events(void) void exit_events(void)
{ {
cp(); cp();
avl_delete_tree(event_tree); avl_delete_tree(event_tree);
cp();
} }
event_t *new_event(void) event_t *new_event(void)
{ {
event_t *event;
cp(); cp();
event = (event_t *)xmalloc_and_zero(sizeof(*event));
cp(); return (event_t *) xmalloc_and_zero(sizeof(event_t));
return event;
} }
void free_event(event_t *event) void free_event(event_t * event)
{ {
cp(); cp();
free(event); free(event);
cp();
} }
void event_add(event_t *event) void event_add(event_t * event)
{ {
cp(); cp();
event->id = ++id; event->id = ++id;
avl_insert(event_tree, event); avl_insert(event_tree, event);
cp();
} }
void event_del(event_t *event) void event_del(event_t * event)
{ {
cp(); cp();
avl_delete(event_tree, event); avl_delete(event_tree, event);
cp();
} }
event_t *get_expired_event(void) event_t *get_expired_event(void)
{ {
event_t *event; event_t *event;
cp(); cp();
if(event_tree->head)
{ if(event_tree->head) {
event = (event_t *)event_tree->head->data; event = (event_t *) event_tree->head->data;
if(event->time < now)
{ if(event->time < now) {
avl_delete(event_tree, event); avl_delete(event_tree, event);
return event; return event;
} }
} }
cp();
return NULL; return NULL;
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: event.h,v 1.1.4.2 2002/06/21 10:11:12 guus Exp $ $Id: event.h,v 1.1.4.3 2002/09/09 21:24:34 guus Exp $
*/ */
#ifndef __TINC_EVENT_H__ #ifndef __TINC_EVENT_H__
@ -28,7 +28,7 @@
avl_tree_t *event_tree; avl_tree_t *event_tree;
typedef void (*event_handler_t)(void *); typedef void (*event_handler_t) (void *);
typedef struct { typedef struct {
time_t time; time_t time;

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.1.2.5 2002/06/21 10:11:35 guus Exp $ $Id: device.c,v 1.1.2.6 2002/09/09 21:25:19 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -58,22 +58,17 @@ extern subnet_t mymac;
*/ */
int setup_device(void) int setup_device(void)
{ {
cp cp if(!get_config_string(lookup_config(config_tree, "Device"), &device))
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
device = DEFAULT_DEVICE; device = DEFAULT_DEVICE;
if(!get_config_string(lookup_config(config_tree, "Interface"), &interface)) if(!get_config_string(lookup_config(config_tree, "Interface"), &interface))
interface = rindex(device, '/')?rindex(device, '/')+1:device; interface = rindex(device, '/') ? rindex(device, '/') + 1 : device;
cp cp if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0)
{
syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno));
return -1; return -1;
} }
cp cp
/* Set default MAC address for ethertap devices */ /* Set default MAC address for ethertap devices */
mymac.type = SUBNET_MAC; mymac.type = SUBNET_MAC;
mymac.net.mac.address.x[0] = 0xfe; mymac.net.mac.address.x[0] = 0xfe;
mymac.net.mac.address.x[1] = 0xfd; mymac.net.mac.address.x[1] = 0xfd;
@ -85,27 +80,24 @@ cp
device_info = _("FreeBSD tap device"); device_info = _("FreeBSD tap device");
syslog(LOG_INFO, _("%s is a %s"), device, device_info); syslog(LOG_INFO, _("%s is a %s"), device, device_info);
cp cp return 0;
return 0;
} }
void close_device(void) void close_device(void)
{ {
cp cp close(device_fd);
close(device_fd);
} }
/* /*
read, encrypt and send data that is read, encrypt and send data that is
available through the ethertap device available through the ethertap device
*/ */
int read_packet(vpn_packet_t *packet) int read_packet(vpn_packet_t * packet)
{ {
int lenin; int lenin;
cp cp if((lenin = read(device_fd, packet->data, MTU)) <= 0) {
if((lenin = read(device_fd, packet->data, MTU)) <= 0) syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
{ device, strerror(errno));
syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno));
return -1; return -1;
} }
@ -118,31 +110,26 @@ cp
packet->len, device_info); packet->len, device_info);
return 0; return 0;
cp cp}
}
int write_packet(vpn_packet_t *packet) int write_packet(vpn_packet_t * packet)
{ {
cp cp if(debug_lvl >= DEBUG_TRAFFIC)
if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"), syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"),
packet->len, device_info); packet->len, device_info);
if(write(device_fd, packet->data, packet->len) < 0) if(write(device_fd, packet->data, packet->len) < 0) {
{ syslog(LOG_ERR, _("Error while writing to %s %s: %s"), device_info,
syslog(LOG_ERR, _("Error while writing to %s %s: %s"), device_info, device, strerror(errno)); device, strerror(errno));
return -1; return -1;
} }
device_total_out += packet->len; device_total_out += packet->len;
cp cp}
}
void dump_device_stats(void) void dump_device_stats(void)
{ {
cp cp syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in);
syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out);
cp cp}
}

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: graph.c,v 1.1.2.18 2002/09/09 19:39:58 guus Exp $ $Id: graph.c,v 1.1.2.19 2002/09/09 21:24:34 guus Exp $
*/ */
/* We need to generate two trees from the graph: /* We need to generate two trees from the graph:
@ -51,7 +51,7 @@
#include "config.h" #include "config.h"
#include <string.h> #include <string.h>
#ifdef HAVE_SYS_PARAM_H #ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> #include <sys/param.h>
#endif #endif
#include <netinet/in.h> #include <netinet/in.h>
@ -82,11 +82,12 @@ void mst_kruskal(void)
int safe_edges = 0; int safe_edges = 0;
int skipped; int skipped;
cp();
/* Clear MST status on connections */ /* Clear MST status on connections */
for(node = connection_tree->head; node; node = node->next) for(node = connection_tree->head; node; node = node->next) {
{ c = (connection_t *) node->data;
c = (connection_t *)node->data;
c->status.mst = 0; c->status.mst = 0;
} }
@ -100,44 +101,43 @@ void mst_kruskal(void)
/* Clear visited status on nodes */ /* Clear visited status on nodes */
for(node = node_tree->head; node; node = node->next) for(node = node_tree->head; node; node = node->next) {
{ n = (node_t *) node->data;
n = (node_t *)node->data;
n->status.visited = 0; n->status.visited = 0;
nodes++; nodes++;
} }
/* Starting point */ /* Starting point */
((edge_t *)edge_weight_tree->head->data)->from->status.visited = 1; ((edge_t *) edge_weight_tree->head->data)->from->status.visited = 1;
/* Add safe edges */ /* Add safe edges */
for(skipped = 0, node = edge_weight_tree->head; node; node = next) for(skipped = 0, node = edge_weight_tree->head; node; node = next) {
{
next = node->next; next = node->next;
e = (edge_t *)node->data; e = (edge_t *) node->data;
if(!e->reverse || e->from->status.visited == e->to->status.visited) if(!e->reverse || e->from->status.visited == e->to->status.visited) {
{
skipped = 1; skipped = 1;
continue; continue;
} }
e->from->status.visited = 1; e->from->status.visited = 1;
e->to->status.visited = 1; e->to->status.visited = 1;
if(e->connection) if(e->connection)
e->connection->status.mst = 1; e->connection->status.mst = 1;
if(e->reverse->connection) if(e->reverse->connection)
e->reverse->connection->status.mst = 1; e->reverse->connection->status.mst = 1;
safe_edges++; safe_edges++;
if(debug_lvl >= DEBUG_SCARY_THINGS) if(debug_lvl >= DEBUG_SCARY_THINGS)
syslog(LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name, e->to->name, e->weight); syslog(LOG_DEBUG, " Adding edge %s - %s weight %d", e->from->name,
e->to->name, e->weight);
if(skipped) if(skipped) {
{
skipped = 0; skipped = 0;
next = edge_weight_tree->head; next = edge_weight_tree->head;
continue; continue;
@ -145,7 +145,8 @@ void mst_kruskal(void)
} }
if(debug_lvl >= DEBUG_SCARY_THINGS) if(debug_lvl >= DEBUG_SCARY_THINGS)
syslog(LOG_DEBUG, "Done, counted %d nodes and %d safe edges.", nodes, safe_edges); syslog(LOG_DEBUG, "Done, counted %d nodes and %d safe edges.", nodes,
safe_edges);
} }
/* Implementation of a simple breadth-first search algorithm. /* Implementation of a simple breadth-first search algorithm.
@ -164,13 +165,14 @@ void sssp_bfs(void)
char *envp[7]; char *envp[7];
int i; int i;
cp();
todo_tree = avl_alloc_tree(NULL, NULL); todo_tree = avl_alloc_tree(NULL, NULL);
/* Clear visited status on nodes */ /* Clear visited status on nodes */
for(node = node_tree->head; node; node = node->next) for(node = node_tree->head; node; node = node->next) {
{ n = (node_t *) node->data;
n = (node_t *)node->data;
n->status.visited = 0; n->status.visited = 0;
n->status.indirect = 1; n->status.indirect = 1;
} }
@ -187,16 +189,13 @@ void sssp_bfs(void)
/* Loop while todo_tree is filled */ /* Loop while todo_tree is filled */
while(todo_tree->head) while(todo_tree->head) {
{ for(from = todo_tree->head; from; from = next) { /* "from" is the node from which we start */
for(from = todo_tree->head; from; from = next) /* "from" is the node from which we start */
{
next = from->next; next = from->next;
n = (node_t *)from->data; n = (node_t *) from->data;
for(to = n->edge_tree->head; to; to = to->next) /* "to" is the edge connected to "from" */ for(to = n->edge_tree->head; to; to = to->next) { /* "to" is the edge connected to "from" */
{ e = (edge_t *) to->data;
e = (edge_t *)to->data;
if(!e->reverse) if(!e->reverse)
continue; continue;
@ -220,9 +219,12 @@ void sssp_bfs(void)
of nodes behind it. of nodes behind it.
*/ */
indirect = n->status.indirect || e->options & OPTION_INDIRECT || ((n != myself) && sockaddrcmp(&n->address, &e->reverse->address)); indirect = n->status.indirect || e->options & OPTION_INDIRECT
|| ((n != myself)
&& sockaddrcmp(&n->address, &e->reverse->address));
if(e->to->status.visited && (!e->to->status.indirect || indirect)) if(e->to->status.visited
&& (!e->to->status.indirect || indirect))
continue; continue;
e->to->status.visited = 1; e->to->status.visited = 1;
@ -230,15 +232,18 @@ void sssp_bfs(void)
e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop; e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop;
e->to->via = indirect ? n->via : e->to; e->to->via = indirect ? n->via : e->to;
e->to->options = e->options; e->to->options = e->options;
if(sockaddrcmp(&e->to->address, &e->address))
{ if(sockaddrcmp(&e->to->address, &e->address)) {
node = avl_unlink(node_udp_tree, e->to); node = avl_unlink(node_udp_tree, e->to);
e->to->address = e->address; e->to->address = e->address;
if(e->to->hostname) if(e->to->hostname)
free(e->to->hostname); free(e->to->hostname);
e->to->hostname = sockaddr2hostname(&e->to->address); e->to->hostname = sockaddr2hostname(&e->to->address);
avl_insert_node(node_udp_tree, node); avl_insert_node(node_udp_tree, node);
} }
node = avl_alloc_node(); node = avl_alloc_node();
node->data = e->to; node->data = e->to;
avl_insert_before(todo_tree, from, node); avl_insert_before(todo_tree, from, node);
@ -252,34 +257,38 @@ void sssp_bfs(void)
/* Check reachability status. */ /* Check reachability status. */
for(node = node_tree->head; node; node = next) for(node = node_tree->head; node; node = next) {
{
next = node->next; next = node->next;
n = (node_t *)node->data; n = (node_t *) node->data;
if(n->status.visited != n->status.reachable) if(n->status.visited != n->status.reachable) {
{
n->status.reachable = !n->status.reachable; n->status.reachable = !n->status.reachable;
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
if(n->status.reachable) if(n->status.reachable)
syslog(LOG_DEBUG, _("Node %s (%s) became reachable"), n->name, n->hostname); syslog(LOG_DEBUG, _("Node %s (%s) became reachable"),
n->name, n->hostname);
else else
syslog(LOG_DEBUG, _("Node %s (%s) became unreachable"), n->name, n->hostname); syslog(LOG_DEBUG, _("Node %s (%s) became unreachable"),
n->name, n->hostname);
n->status.validkey = 0; n->status.validkey = 0;
n->status.waitingforkey = 0; n->status.waitingforkey = 0;
asprintf(&envp[0], "NETNAME=%s", netname?:""); asprintf(&envp[0], "NETNAME=%s", netname ? : "");
asprintf(&envp[1], "DEVICE=%s", device?:""); asprintf(&envp[1], "DEVICE=%s", device ? : "");
asprintf(&envp[2], "INTERFACE=%s", interface?:""); asprintf(&envp[2], "INTERFACE=%s", interface ? : "");
asprintf(&envp[3], "NODE=%s", n->name); asprintf(&envp[3], "NODE=%s", n->name);
sockaddr2str(&n->address, &address, &port); sockaddr2str(&n->address, &address, &port);
asprintf(&envp[4], "REMOTEADDRESS=%s", address); asprintf(&envp[4], "REMOTEADDRESS=%s", address);
asprintf(&envp[5], "REMOTEPORT=%s", port); asprintf(&envp[5], "REMOTEPORT=%s", port);
envp[6] = NULL; envp[6] = NULL;
asprintf(&name, n->status.reachable?"hosts/%s-up":"hosts/%s-down", n->name); asprintf(&name,
n->status.reachable ? "hosts/%s-up" : "hosts/%s-down",
n->name);
execute_script(name, envp); execute_script(name, envp);
free(name); free(name);
free(address); free(address);
free(port); free(port);

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.1.2.10 2002/09/09 19:40:12 guus Exp $ $Id: device.c,v 1.1.2.11 2002/09/09 21:25:23 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -34,14 +34,14 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#ifdef HAVE_TUNTAP #ifdef HAVE_TUNTAP
#ifdef LINUX_IF_TUN_H #ifdef LINUX_IF_TUN_H
#include LINUX_IF_TUN_H #include LINUX_IF_TUN_H
#else
#include <linux/if_tun.h>
#endif
#define DEFAULT_DEVICE "/dev/misc/net/tun"
#else #else
#define DEFAULT_DEVICE "/dev/tap0" #include <linux/if_tun.h>
#endif
#define DEFAULT_DEVICE "/dev/misc/net/tun"
#else
#define DEFAULT_DEVICE "/dev/tap0"
#endif #endif
#include <utils.h> #include <utils.h>
@ -73,27 +73,23 @@ int setup_device(void)
{ {
struct ifreq ifr; struct ifreq ifr;
cp cp if(!get_config_string(lookup_config(config_tree, "Device"), &device))
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
device = DEFAULT_DEVICE; device = DEFAULT_DEVICE;
if(!get_config_string(lookup_config(config_tree, "Interface"), &interface)) if(!get_config_string(lookup_config(config_tree, "Interface"), &interface))
#ifdef HAVE_TUNTAP #ifdef HAVE_TUNTAP
interface = netname; interface = netname;
#else #else
interface = rindex(device, '/')?rindex(device, '/')+1:device; interface = rindex(device, '/') ? rindex(device, '/') + 1 : device;
#endif #endif
cp cp device_fd = open(device, O_RDWR | O_NONBLOCK);
device_fd = open(device, O_RDWR | O_NONBLOCK);
if(device_fd < 0) if(device_fd < 0) {
{
syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno));
return -1; return -1;
} }
cp cp
/* Set default MAC address for ethertap devices */ /* Set default MAC address for ethertap devices */
mymac.type = SUBNET_MAC; mymac.type = SUBNET_MAC;
mymac.net.mac.address.x[0] = 0xfe; mymac.net.mac.address.x[0] = 0xfe;
mymac.net.mac.address.x[1] = 0xfd; mymac.net.mac.address.x[1] = 0xfd;
@ -106,73 +102,61 @@ cp
/* Ok now check if this is an old ethertap or a new tun/tap thingie */ /* Ok now check if this is an old ethertap or a new tun/tap thingie */
memset(&ifr, 0, sizeof(ifr)); memset(&ifr, 0, sizeof(ifr));
cp cp ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
ifr.ifr_flags = IFF_TAP | IFF_NO_PI; if(interface)
if (interface)
strncpy(ifr.ifr_name, interface, IFNAMSIZ); strncpy(ifr.ifr_name, interface, IFNAMSIZ);
cp cp if(!ioctl(device_fd, TUNSETIFF, (void *) &ifr)) {
if (!ioctl(device_fd, TUNSETIFF, (void *) &ifr))
{
device_info = _("Linux tun/tap device"); device_info = _("Linux tun/tap device");
device_type = DEVICE_TYPE_TUNTAP; device_type = DEVICE_TYPE_TUNTAP;
strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
interface = ifrname; interface = ifrname;
} } else if(!ioctl(device_fd, (('T' << 8) | 202), (void *) &ifr)) {
else
if (!ioctl(device_fd, (('T'<< 8) | 202), (void *) &ifr))
{
syslog(LOG_WARNING, _("Old ioctl() request was needed for %s"), device); syslog(LOG_WARNING, _("Old ioctl() request was needed for %s"), device);
device_type = DEVICE_TYPE_TUNTAP; device_type = DEVICE_TYPE_TUNTAP;
device_info = _("Linux tun/tap device"); device_info = _("Linux tun/tap device");
strncpy(ifrname, ifr.ifr_name, IFNAMSIZ); strncpy(ifrname, ifr.ifr_name, IFNAMSIZ);
interface = ifrname; interface = ifrname;
} } else
else
#endif #endif
{ {
device_info = _("Linux ethertap device"); device_info = _("Linux ethertap device");
device_type = DEVICE_TYPE_ETHERTAP; device_type = DEVICE_TYPE_ETHERTAP;
interface = rindex(device, '/')?rindex(device, '/')+1:device; interface = rindex(device, '/') ? rindex(device, '/') + 1 : device;
} }
syslog(LOG_INFO, _("%s is a %s"), device, device_info); syslog(LOG_INFO, _("%s is a %s"), device, device_info);
cp cp return 0;
return 0;
} }
void close_device(void) void close_device(void)
{ {
cp cp close(device_fd);
close(device_fd);
} }
/* /*
read, encrypt and send data that is read, encrypt and send data that is
available through the ethertap device available through the ethertap device
*/ */
int read_packet(vpn_packet_t *packet) int read_packet(vpn_packet_t * packet)
{ {
int lenin; int lenin;
cp cp if(device_type == DEVICE_TYPE_TUNTAP) {
if(device_type == DEVICE_TYPE_TUNTAP)
{
lenin = read(device_fd, packet->data, MTU); lenin = read(device_fd, packet->data, MTU);
if(lenin <= 0) if(lenin <= 0) {
{ syslog(LOG_ERR, _("Error while reading from %s %s: %s"),
syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); device_info, device, strerror(errno));
return -1; return -1;
} }
packet->len = lenin; packet->len = lenin;
} } else { /* ethertap */
else /* ethertap */
{
lenin = read(device_fd, packet->data - 2, MTU + 2); lenin = read(device_fd, packet->data - 2, MTU + 2);
if(lenin <= 0) if(lenin <= 0) {
{ syslog(LOG_ERR, _("Error while reading from %s %s: %s"),
syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); device_info, device, strerror(errno));
return -1; return -1;
} }
@ -181,50 +165,43 @@ cp
device_total_in += packet->len; device_total_in += packet->len;
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC) {
{ syslog(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len,
syslog(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); device_info);
} }
return 0; return 0;
cp cp}
}
int write_packet(vpn_packet_t *packet) int write_packet(vpn_packet_t * packet)
{ {
cp cp if(debug_lvl >= DEBUG_TRAFFIC)
if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"), syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"),
packet->len, device_info); packet->len, device_info);
if(device_type == DEVICE_TYPE_TUNTAP) if(device_type == DEVICE_TYPE_TUNTAP) {
{ if(write(device_fd, packet->data, packet->len) < 0) {
if(write(device_fd, packet->data, packet->len) < 0) syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device,
{ strerror(errno));
syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno));
return -1; return -1;
} }
} } else { /* ethertap */
else/* ethertap */
{ *(short int *) (packet->data - 2) = packet->len;
*(short int *)(packet->data - 2) = packet->len; if(write(device_fd, packet->data - 2, packet->len + 2) < 0) {
if(write(device_fd, packet->data - 2, packet->len + 2) < 0) syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device,
{ strerror(errno));
syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno));
return -1; return -1;
} }
} }
device_total_out += packet->len; device_total_out += packet->len;
cp cp return 0;
return 0;
} }
void dump_device_stats(void) void dump_device_stats(void)
{ {
cp cp syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in);
syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out);
cp cp}
}

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: meta.c,v 1.1.2.28 2002/09/09 19:39:58 guus Exp $ $Id: meta.c,v 1.1.2.29 2002/09/09 21:24:34 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -39,64 +39,66 @@
#include "system.h" #include "system.h"
#include "protocol.h" #include "protocol.h"
int send_meta(connection_t *c, char *buffer, int length) int send_meta(connection_t * c, char *buffer, int length)
{ {
char *bufp; char *bufp;
int outlen; int outlen;
char outbuf[MAXBUFSIZE]; char outbuf[MAXBUFSIZE];
cp(); cp();
if(debug_lvl >= DEBUG_META) if(debug_lvl >= DEBUG_META)
syslog(LOG_DEBUG, _("Sending %d bytes of metadata to %s (%s)"), length, syslog(LOG_DEBUG, _("Sending %d bytes of metadata to %s (%s)"), length,
c->name, c->hostname); c->name, c->hostname);
if(c->status.encryptout) if(c->status.encryptout) {
{
EVP_EncryptUpdate(c->outctx, outbuf, &outlen, buffer, length); EVP_EncryptUpdate(c->outctx, outbuf, &outlen, buffer, length);
bufp = outbuf; bufp = outbuf;
length = outlen; length = outlen;
} } else
else
bufp = buffer; bufp = buffer;
if(write(c->socket, bufp, length) < 0) if(write(c->socket, bufp, length) < 0) {
{ syslog(LOG_ERR, _("Sending meta data to %s (%s) failed: %s"), c->name,
syslog(LOG_ERR, _("Sending meta data to %s (%s) failed: %s"), c->name, c->hostname, strerror(errno)); c->hostname, strerror(errno));
return -1; return -1;
} }
cp();
return 0; return 0;
} }
void broadcast_meta(connection_t *from, char *buffer, int length) void broadcast_meta(connection_t * from, char *buffer, int length)
{ {
avl_node_t *node; avl_node_t *node;
connection_t *c; connection_t *c;
cp(); cp();
for(node = connection_tree->head; node; node = node->next)
{ for(node = connection_tree->head; node; node = node->next) {
c = (connection_t *)node->data; c = (connection_t *) node->data;
if(c != from && c->status.active) if(c != from && c->status.active)
send_meta(c, buffer, length); send_meta(c, buffer, length);
} }
cp();
} }
int receive_meta(connection_t *c) int receive_meta(connection_t * c)
{ {
int x, l = sizeof(x); int x, l = sizeof(x);
int oldlen, i; int oldlen, i;
int lenin, reqlen; int lenin, reqlen;
int decrypted = 0; int decrypted = 0;
char inbuf[MAXBUFSIZE]; char inbuf[MAXBUFSIZE];
cp(); cp();
if(getsockopt(c->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
{ if(getsockopt(c->socket, SOL_SOCKET, SO_ERROR, &x, &l) < 0) {
syslog(LOG_ERR, _("This is a bug: %s:%d: %d:%s %s (%s)"), __FILE__, __LINE__, c->socket, strerror(errno), syslog(LOG_ERR, _("This is a bug: %s:%d: %d:%s %s (%s)"), __FILE__,
c->name, c->hostname); __LINE__, c->socket, strerror(errno), c->name, c->hostname);
return -1; return -1;
} }
if(x)
{ if(x) {
syslog(LOG_ERR, _("Metadata socket error for %s (%s): %s"), syslog(LOG_ERR, _("Metadata socket error for %s (%s): %s"),
c->name, c->hostname, strerror(x)); c->name, c->hostname, strerror(x));
return -1; return -1;
@ -113,16 +115,12 @@ int receive_meta(connection_t *c)
lenin = read(c->socket, c->buffer + c->buflen, MAXBUFSIZE - c->buflen); lenin = read(c->socket, c->buffer + c->buflen, MAXBUFSIZE - c->buflen);
if(lenin<=0) if(lenin <= 0) {
{ if(lenin == 0) {
if(lenin==0)
{
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_NOTICE, _("Connection closed by %s (%s)"), syslog(LOG_NOTICE, _("Connection closed by %s (%s)"),
c->name, c->hostname); c->name, c->hostname);
} } else if(errno == EINTR)
else
if(errno==EINTR)
return 0; return 0;
else else
syslog(LOG_ERR, _("Metadata socket read error for %s (%s): %s"), syslog(LOG_ERR, _("Metadata socket read error for %s (%s): %s"),
@ -134,23 +132,20 @@ int receive_meta(connection_t *c)
oldlen = c->buflen; oldlen = c->buflen;
c->buflen += lenin; c->buflen += lenin;
while(lenin) while(lenin) {
{
/* Decrypt */ /* Decrypt */
if(c->status.decryptin && !decrypted) if(c->status.decryptin && !decrypted) {
{ EVP_DecryptUpdate(c->inctx, inbuf, &lenin, c->buffer + oldlen,
EVP_DecryptUpdate(c->inctx, inbuf, &lenin, c->buffer + oldlen, lenin); lenin);
memcpy(c->buffer + oldlen, inbuf, lenin); memcpy(c->buffer + oldlen, inbuf, lenin);
decrypted = 1; decrypted = 1;
} }
/* Are we receiving a TCPpacket? */ /* Are we receiving a TCPpacket? */
if(c->tcplen) if(c->tcplen) {
{ if(c->tcplen <= c->buflen) {
if(c->tcplen <= c->buflen)
{
receive_tcppacket(c, c->buffer, c->tcplen); receive_tcppacket(c, c->buffer, c->tcplen);
c->buflen -= c->tcplen; c->buflen -= c->tcplen;
@ -159,9 +154,7 @@ int receive_meta(connection_t *c)
oldlen = 0; oldlen = 0;
c->tcplen = 0; c->tcplen = 0;
continue; continue;
} } else {
else
{
break; break;
} }
} }
@ -170,18 +163,15 @@ int receive_meta(connection_t *c)
reqlen = 0; reqlen = 0;
for(i = oldlen; i < c->buflen; i++) for(i = oldlen; i < c->buflen; i++) {
{ if(c->buffer[i] == '\n') {
if(c->buffer[i] == '\n')
{
c->buffer[i] = '\0'; /* replace end-of-line by end-of-string so we can use sscanf */ c->buffer[i] = '\0'; /* replace end-of-line by end-of-string so we can use sscanf */
reqlen = i + 1; reqlen = i + 1;
break; break;
} }
} }
if(reqlen) if(reqlen) {
{
c->reqlen = reqlen; c->reqlen = reqlen;
if(receive_request(c)) if(receive_request(c))
return -1; return -1;
@ -191,21 +181,18 @@ int receive_meta(connection_t *c)
memmove(c->buffer, c->buffer + reqlen, c->buflen); memmove(c->buffer, c->buffer + reqlen, c->buflen);
oldlen = 0; oldlen = 0;
continue; continue;
} } else {
else
{
break; break;
} }
} }
if(c->buflen >= MAXBUFSIZE) if(c->buflen >= MAXBUFSIZE) {
{
syslog(LOG_ERR, _("Metadata read buffer overflow for %s (%s)"), syslog(LOG_ERR, _("Metadata read buffer overflow for %s (%s)"),
c->name, c->hostname); c->name, c->hostname);
return -1; return -1;
} }
c->last_ping_time = now; c->last_ping_time = now;
cp();
return 0; return 0;
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: meta.h,v 1.1.2.7 2002/06/21 10:11:12 guus Exp $ $Id: meta.h,v 1.1.2.8 2002/09/09 21:24:34 guus Exp $
*/ */
#ifndef __TINC_META_H__ #ifndef __TINC_META_H__

177
src/net.c
View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: net.c,v 1.35.4.179 2002/09/09 19:39:58 guus Exp $ $Id: net.c,v 1.35.4.180 2002/09/09 21:24:34 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -27,13 +27,13 @@
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
#ifdef HAVE_NETINET_IN_SYSTM_H #ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
#endif #endif
#ifdef HAVE_NETINET_IP_H #ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h> #include <netinet/ip.h>
#endif #endif
#ifdef HAVE_NETINET_TCP_H #ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -91,32 +91,31 @@ void purge(void)
node_t *n; node_t *n;
edge_t *e; edge_t *e;
subnet_t *s; subnet_t *s;
cp(); cp();
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_DEBUG, _("Purging unreachable nodes")); syslog(LOG_DEBUG, _("Purging unreachable nodes"));
for(nnode = node_tree->head; nnode; nnode = nnext) for(nnode = node_tree->head; nnode; nnode = nnext) {
{
nnext = nnode->next; nnext = nnode->next;
n = (node_t *)nnode->data; n = (node_t *) nnode->data;
if(!n->status.reachable) if(!n->status.reachable) {
{
if(debug_lvl >= DEBUG_SCARY_THINGS) if(debug_lvl >= DEBUG_SCARY_THINGS)
syslog(LOG_DEBUG, _("Purging node %s (%s)"), n->name, n->hostname); syslog(LOG_DEBUG, _("Purging node %s (%s)"), n->name,
n->hostname);
for(snode = n->subnet_tree->head; snode; snode = snext) for(snode = n->subnet_tree->head; snode; snode = snext) {
{
snext = snode->next; snext = snode->next;
s = (subnet_t *)snode->data; s = (subnet_t *) snode->data;
send_del_subnet(broadcast, s); send_del_subnet(broadcast, s);
subnet_del(n, s); subnet_del(n, s);
} }
for(enode = n->edge_tree->head; enode; enode = enext) for(enode = n->edge_tree->head; enode; enode = enext) {
{
enext = enode->next; enext = enode->next;
e = (edge_t *)enode->data; e = (edge_t *) enode->data;
send_del_edge(broadcast, e); send_del_edge(broadcast, e);
edge_del(e); edge_del(e);
} }
@ -124,44 +123,40 @@ void purge(void)
node_del(n); node_del(n);
} }
} }
cp();
} }
/* /*
put all file descriptors in an fd_set array put all file descriptors in an fd_set array
While we're at it, purge stuff that needs to be removed. While we're at it, purge stuff that needs to be removed.
*/ */
void build_fdset(fd_set *fs) void build_fdset(fd_set * fs)
{ {
avl_node_t *node, *next; avl_node_t *node, *next;
connection_t *c; connection_t *c;
int i; int i;
cp(); cp();
FD_ZERO(fs); FD_ZERO(fs);
for(node = connection_tree->head; node; node = next) for(node = connection_tree->head; node; node = next) {
{
next = node->next; next = node->next;
c = (connection_t *)node->data; c = (connection_t *) node->data;
if(c->status.remove) if(c->status.remove) {
{
connection_del(c); connection_del(c);
if(!connection_tree->head) if(!connection_tree->head)
purge(); purge();
} } else
else
FD_SET(c->socket, fs); FD_SET(c->socket, fs);
} }
for(i = 0; i < listen_sockets; i++) for(i = 0; i < listen_sockets; i++) {
{
FD_SET(listen_socket[i].tcp, fs); FD_SET(listen_socket[i].tcp, fs);
FD_SET(listen_socket[i].udp, fs); FD_SET(listen_socket[i].udp, fs);
} }
FD_SET(device_fd, fs); FD_SET(device_fd, fs);
cp();
} }
/* /*
@ -171,9 +166,10 @@ void build_fdset(fd_set *fs)
- Check if we need to retry making an outgoing connection - Check if we need to retry making an outgoing connection
- Deactivate the host - Deactivate the host
*/ */
void terminate_connection(connection_t *c, int report) void terminate_connection(connection_t * c, int report)
{ {
cp(); cp();
if(c->status.remove) if(c->status.remove)
return; return;
@ -190,8 +186,7 @@ void terminate_connection(connection_t *c, int report)
if(c->socket) if(c->socket)
close(c->socket); close(c->socket);
if(c->edge) if(c->edge) {
{
if(report) if(report)
send_del_edge(broadcast, c->edge); send_del_edge(broadcast, c->edge);
@ -204,12 +199,10 @@ void terminate_connection(connection_t *c, int report)
/* Check if this was our outgoing connection */ /* Check if this was our outgoing connection */
if(c->outgoing) if(c->outgoing) {
{
retry_outgoing(c->outgoing); retry_outgoing(c->outgoing);
c->outgoing = NULL; c->outgoing = NULL;
} }
cp();
} }
/* /*
@ -224,33 +217,28 @@ void check_dead_connections(void)
{ {
avl_node_t *node, *next; avl_node_t *node, *next;
connection_t *c; connection_t *c;
cp(); cp();
for(node = connection_tree->head; node; node = next)
{ for(node = connection_tree->head; node; node = next) {
next = node->next; next = node->next;
c = (connection_t *)node->data; c = (connection_t *) node->data;
if(c->last_ping_time + pingtimeout < now)
{ if(c->last_ping_time + pingtimeout < now) {
if(c->status.active) if(c->status.active) {
{ if(c->status.pinged) {
if(c->status.pinged)
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_INFO, _("%s (%s) didn't respond to PING"), syslog(LOG_INFO, _("%s (%s) didn't respond to PING"),
c->name, c->hostname); c->name, c->hostname);
c->status.timeout = 1; c->status.timeout = 1;
terminate_connection(c, 1); terminate_connection(c, 1);
} } else {
else
{
send_ping(c); send_ping(c);
} }
} } else {
else if(c->status.remove) {
{ syslog(LOG_WARNING, _("Old connection_t for %s (%s) status %04x still lingering, deleting..."),
if(c->status.remove) c->name, c->hostname, c->status);
{
syslog(LOG_WARNING, _("Old connection_t for %s (%s) status %04x still lingering, deleting..."), c->name, c->hostname, c->status);
connection_del(c); connection_del(c);
continue; continue;
} }
@ -261,67 +249,65 @@ void check_dead_connections(void)
} }
} }
} }
cp();
} }
/* /*
check all connections to see if anything check all connections to see if anything
happened on their sockets happened on their sockets
*/ */
void check_network_activity(fd_set *f) void check_network_activity(fd_set * f)
{ {
connection_t *c; connection_t *c;
avl_node_t *node; avl_node_t *node;
int result, i; int result, i;
int len = sizeof(result); int len = sizeof(result);
vpn_packet_t packet; vpn_packet_t packet;
cp(); cp();
if(FD_ISSET(device_fd, f))
{ if(FD_ISSET(device_fd, f)) {
if(!read_packet(&packet)) if(!read_packet(&packet))
route_outgoing(&packet); route_outgoing(&packet);
} }
for(node = connection_tree->head; node; node = node->next) for(node = connection_tree->head; node; node = node->next) {
{ c = (connection_t *) node->data;
c = (connection_t *)node->data;
if(c->status.remove) if(c->status.remove)
continue; continue;
if(FD_ISSET(c->socket, f)) if(FD_ISSET(c->socket, f)) {
{ if(c->status.connecting) {
if(c->status.connecting)
{
c->status.connecting = 0; c->status.connecting = 0;
getsockopt(c->socket, SOL_SOCKET, SO_ERROR, &result, &len); getsockopt(c->socket, SOL_SOCKET, SO_ERROR, &result, &len);
if(!result) if(!result)
finish_connecting(c); finish_connecting(c);
else else {
{
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_DEBUG, _("Error while connecting to %s (%s): %s"), c->name, c->hostname, strerror(result)); syslog(LOG_DEBUG,
_("Error while connecting to %s (%s): %s"),
c->name, c->hostname, strerror(result));
close(c->socket); close(c->socket);
do_outgoing_connection(c); do_outgoing_connection(c);
continue; continue;
} }
} }
if(receive_meta(c) < 0)
{ if(receive_meta(c) < 0) {
terminate_connection(c, c->status.active); terminate_connection(c, c->status.active);
continue; continue;
} }
} }
} }
for(i = 0; i < listen_sockets; i++) for(i = 0; i < listen_sockets; i++) {
{
if(FD_ISSET(listen_socket[i].udp, f)) if(FD_ISSET(listen_socket[i].udp, f))
handle_incoming_vpn_data(listen_socket[i].udp); handle_incoming_vpn_data(listen_socket[i].udp);
if(FD_ISSET(listen_socket[i].tcp, f)) if(FD_ISSET(listen_socket[i].tcp, f))
handle_new_meta_connection(listen_socket[i].tcp); handle_new_meta_connection(listen_socket[i].tcp);
} }
cp();
} }
/* /*
@ -334,13 +320,13 @@ void main_loop(void)
int r; int r;
time_t last_ping_check; time_t last_ping_check;
event_t *event; event_t *event;
cp();
last_ping_check = now;
cp();
last_ping_check = now;
srand(now); srand(now);
for(;;) for(;;) {
{
now = time(NULL); now = time(NULL);
tv.tv_sec = 1 + (rand() & 7); /* Approx. 5 seconds, randomized to prevent global synchronisation effects */ tv.tv_sec = 1 + (rand() & 7); /* Approx. 5 seconds, randomized to prevent global synchronisation effects */
@ -350,11 +336,10 @@ void main_loop(void)
r = select(FD_SETSIZE, &fset, NULL, NULL, &tv); r = select(FD_SETSIZE, &fset, NULL, NULL, &tv);
if(r < 0) if(r < 0) {
{ if(errno != EINTR && errno != EAGAIN) {
if(errno != EINTR && errno != EAGAIN) syslog(LOG_ERR, _("Error while waiting for input: %s"),
{ strerror(errno));
syslog(LOG_ERR, _("Error while waiting for input: %s"), strerror(errno));
cp_trace(); cp_trace();
dump_connections(); dump_connections();
return; return;
@ -365,28 +350,25 @@ void main_loop(void)
check_network_activity(&fset); check_network_activity(&fset);
if(do_purge) if(do_purge) {
{
purge(); purge();
do_purge = 0; do_purge = 0;
} }
/* Let's check if everybody is still alive */ /* Let's check if everybody is still alive */
if(last_ping_check + pingtimeout < now) if(last_ping_check + pingtimeout < now) {
{
check_dead_connections(); check_dead_connections();
last_ping_check = now; last_ping_check = now;
if(routing_mode== RMODE_SWITCH) if(routing_mode == RMODE_SWITCH)
age_mac(); age_mac();
age_past_requests(); age_past_requests();
/* Should we regenerate our key? */ /* Should we regenerate our key? */
if(keyexpires < now) if(keyexpires < now) {
{
if(debug_lvl >= DEBUG_STATUS) if(debug_lvl >= DEBUG_STATUS)
syslog(LOG_INFO, _("Regenerating symmetric key")); syslog(LOG_INFO, _("Regenerating symmetric key"));
@ -397,27 +379,23 @@ void main_loop(void)
} }
while((event = get_expired_event())) while((event = get_expired_event())) {
{
event->handler(event->data); event->handler(event->data);
free(event); free(event);
} }
if(sigalrm) if(sigalrm) {
{
syslog(LOG_INFO, _("Flushing event queue")); syslog(LOG_INFO, _("Flushing event queue"));
while(event_tree->head) while(event_tree->head) {
{ event = (event_t *) event_tree->head->data;
event = (event_t *)event_tree->head->data;
event->handler(event->data); event->handler(event->data);
event_del(event); event_del(event);
} }
sigalrm = 0; sigalrm = 0;
} }
if(sighup) if(sighup) {
{
sighup = 0; sighup = 0;
close_network_connections(); close_network_connections();
exit_configuration(&config_tree); exit_configuration(&config_tree);
@ -427,9 +405,9 @@ void main_loop(void)
init_configuration(&config_tree); init_configuration(&config_tree);
if(read_server_config()) if(read_server_config()) {
{ syslog(LOG_ERR,
syslog(LOG_ERR, _("Unable to reread configuration file, exitting.")); _("Unable to reread configuration file, exitting."));
exit(1); exit(1);
} }
@ -439,5 +417,4 @@ void main_loop(void)
continue; continue;
} }
} }
cp();
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: net.h,v 1.9.4.52 2002/06/21 10:11:12 guus Exp $ $Id: net.h,v 1.9.4.53 2002/09/09 21:24:36 guus Exp $
*/ */
#ifndef __TINC_NET_H__ #ifndef __TINC_NET_H__
@ -29,32 +29,30 @@
#include <sys/time.h> #include <sys/time.h>
#ifdef HAVE_INTTYPES_H #ifdef HAVE_INTTYPES_H
#include <inttypes.h> #include <inttypes.h>
#endif #endif
#include "config.h" #include "config.h"
#ifdef ENABLE_JUMBOGRAMS #ifdef ENABLE_JUMBOGRAMS
#define MTU 9014 /* 9000 bytes payload + 14 bytes ethernet header */ #define MTU 9014 /* 9000 bytes payload + 14 bytes ethernet header */
#define MAXSIZE 9100 /* MTU + header (seqno) and trailer (CBC padding and HMAC) */ #define MAXSIZE 9100 /* MTU + header (seqno) and trailer (CBC padding and HMAC) */
#define MAXBUFSIZE 9100 /* Must support TCP packets of length 9000. */ #define MAXBUFSIZE 9100 /* Must support TCP packets of length 9000. */
#else #else
#define MTU 1514 /* 1500 bytes payload + 14 bytes ethernet header */ #define MTU 1514 /* 1500 bytes payload + 14 bytes ethernet header */
#define MAXSIZE 1600 /* MTU + header (seqno) and trailer (CBC padding and HMAC) */ #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. */ #define MAXBUFSIZE 2100 /* Quite large but needed for support of keys up to 8192 bits. */
#endif #endif
#define MAXSOCKETS 128 /* Overkill... */ #define MAXSOCKETS 128 /* Overkill... */
#define MAXQUEUELENGTH 8 /* Maximum number of packats in a single queue */ #define MAXQUEUELENGTH 8 /* Maximum number of packats in a single queue */
typedef struct mac_t typedef struct mac_t {
{
uint8_t x[6]; uint8_t x[6];
} mac_t; } mac_t;
typedef struct ipv4_t typedef struct ipv4_t {
{
uint8_t x[4]; uint8_t x[4];
} ipv4_t; } ipv4_t;
@ -63,8 +61,7 @@ typedef struct ip_mask_t {
ipv4_t mask; ipv4_t mask;
} ip_mask_t; } ip_mask_t;
typedef struct ipv6_t typedef struct ipv6_t {
{
uint16_t x[8]; uint16_t x[8];
} ipv6_t; } ipv6_t;

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: net_packet.c,v 1.1.2.21 2002/09/09 19:39:58 guus Exp $ $Id: net_packet.c,v 1.1.2.22 2002/09/09 21:24:41 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -27,13 +27,13 @@
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
#ifdef HAVE_NETINET_IN_SYSTM_H #ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
#endif #endif
#ifdef HAVE_NETINET_IP_H #ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h> #include <netinet/ip.h>
#endif #endif
#ifdef HAVE_NETINET_TCP_H #ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -85,40 +85,44 @@ int keyexpires = 0;
/* VPN packet I/O */ /* VPN packet I/O */
void receive_udppacket(node_t *n, vpn_packet_t *inpkt) void receive_udppacket(node_t * n, vpn_packet_t * inpkt)
{ {
vpn_packet_t pkt1, pkt2; vpn_packet_t pkt1, pkt2;
vpn_packet_t *pkt[] = {&pkt1, &pkt2, &pkt1, &pkt2}; vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
int nextpkt = 0; int nextpkt = 0;
vpn_packet_t *outpkt = pkt[0]; vpn_packet_t *outpkt = pkt[0];
int outlen, outpad; int outlen, outpad;
long int complen = MTU + 12; long int complen = MTU + 12;
EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX ctx;
char hmac[EVP_MAX_MD_SIZE]; char hmac[EVP_MAX_MD_SIZE];
cp(); cp();
/* Check the message authentication code */ /* Check the message authentication code */
if(myself->digest && myself->maclength) if(myself->digest && myself->maclength) {
{
inpkt->len -= myself->maclength; inpkt->len -= myself->maclength;
HMAC(myself->digest, myself->key, myself->keylength, (char *)&inpkt->seqno, inpkt->len, hmac, NULL); HMAC(myself->digest, myself->key, myself->keylength,
if(memcmp(hmac, (char *)&inpkt->seqno + inpkt->len, myself->maclength)) (char *) &inpkt->seqno, inpkt->len, hmac, NULL);
{
if(memcmp(hmac, (char *) &inpkt->seqno + inpkt->len, myself->maclength)) {
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Got unauthenticated packet from %s (%s)"), n->name, n->hostname); syslog(LOG_DEBUG, _("Got unauthenticated packet from %s (%s)"),
n->name, n->hostname);
return; return;
} }
} }
/* Decrypt the packet */ /* Decrypt the packet */
if(myself->cipher) if(myself->cipher) {
{
outpkt = pkt[nextpkt++]; outpkt = pkt[nextpkt++];
EVP_DecryptInit(&ctx, myself->cipher, myself->key, myself->key + myself->cipher->key_len); EVP_DecryptInit(&ctx, myself->cipher, myself->key,
EVP_DecryptUpdate(&ctx, (char *)&outpkt->seqno, &outlen, (char *)&inpkt->seqno, inpkt->len); myself->key + myself->cipher->key_len);
EVP_DecryptFinal(&ctx, (char *)&outpkt->seqno + outlen, &outpad); EVP_DecryptUpdate(&ctx, (char *) &outpkt->seqno, &outlen,
(char *) &inpkt->seqno, inpkt->len);
EVP_DecryptFinal(&ctx, (char *) &outpkt->seqno + outlen, &outpad);
outpkt->len = outlen + outpad; outpkt->len = outlen + outpad;
inpkt = outpkt; inpkt = outpkt;
@ -129,10 +133,11 @@ void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
inpkt->len -= sizeof(inpkt->seqno); inpkt->len -= sizeof(inpkt->seqno);
inpkt->seqno = ntohl(inpkt->seqno); inpkt->seqno = ntohl(inpkt->seqno);
if(inpkt->seqno <= n->received_seqno) if(inpkt->seqno <= n->received_seqno) {
{
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Got late or replayed packet from %s (%s), seqno %d"), n->name, n->hostname, inpkt->seqno); syslog(LOG_DEBUG,
_("Got late or replayed packet from %s (%s), seqno %d"),
n->name, n->hostname, inpkt->seqno);
return; return;
} }
@ -143,13 +148,12 @@ void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
/* Decompress the packet */ /* Decompress the packet */
if(myself->compression) if(myself->compression) {
{
outpkt = pkt[nextpkt++]; outpkt = pkt[nextpkt++];
if(uncompress(outpkt->data, &complen, inpkt->data, inpkt->len) != Z_OK) if(uncompress(outpkt->data, &complen, inpkt->data, inpkt->len) != Z_OK) {
{ syslog(LOG_ERR, _("Error while uncompressing packet from %s (%s)"),
syslog(LOG_ERR, _("Error while uncompressing packet from %s (%s)"), n->name, n->hostname); n->name, n->hostname);
return; return;
} }
@ -158,34 +162,35 @@ void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
} }
receive_packet(n, inpkt); receive_packet(n, inpkt);
cp();
} }
void receive_tcppacket(connection_t *c, char *buffer, int len) void receive_tcppacket(connection_t * c, char *buffer, int len)
{ {
vpn_packet_t outpkt; vpn_packet_t outpkt;
cp(); cp();
outpkt.len = len; outpkt.len = len;
memcpy(outpkt.data, buffer, len); memcpy(outpkt.data, buffer, len);
receive_packet(c->node, &outpkt); receive_packet(c->node, &outpkt);
cp();
} }
void receive_packet(node_t *n, vpn_packet_t *packet) void receive_packet(node_t * n, vpn_packet_t * packet)
{ {
cp(); cp();
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Received packet of %d bytes from %s (%s)"), packet->len, n->name, n->hostname); syslog(LOG_DEBUG, _("Received packet of %d bytes from %s (%s)"),
packet->len, n->name, n->hostname);
route_incoming(n, packet); route_incoming(n, packet);
cp();
} }
void send_udppacket(node_t *n, vpn_packet_t *inpkt) void send_udppacket(node_t * n, vpn_packet_t * inpkt)
{ {
vpn_packet_t pkt1, pkt2; vpn_packet_t pkt1, pkt2;
vpn_packet_t *pkt[] = {&pkt1, &pkt2, &pkt1, &pkt2}; vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
int nextpkt = 0; int nextpkt = 0;
vpn_packet_t *outpkt; vpn_packet_t *outpkt;
int origlen; int origlen;
@ -196,17 +201,18 @@ void send_udppacket(node_t *n, vpn_packet_t *inpkt)
static int priority = 0; static int priority = 0;
int origpriority; int origpriority;
int sock; int sock;
cp(); cp();
/* Make sure we have a valid key */ /* Make sure we have a valid key */
if(!n->status.validkey) if(!n->status.validkey) {
{
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_INFO, _("No valid key known yet for %s (%s), queueing packet"), syslog(LOG_INFO,
_("No valid key known yet for %s (%s), queueing packet"),
n->name, n->hostname); n->name, n->hostname);
/* Since packet is on the stack of handle_tap_input(), /* Since packet is on the stack of handle_tap_input(), we have to make a copy of it first. */
we have to make a copy of it first. */
copy = xmalloc(sizeof(vpn_packet_t)); copy = xmalloc(sizeof(vpn_packet_t));
memcpy(copy, inpkt, sizeof(vpn_packet_t)); memcpy(copy, inpkt, sizeof(vpn_packet_t));
@ -229,13 +235,14 @@ void send_udppacket(node_t *n, vpn_packet_t *inpkt)
/* Compress the packet */ /* Compress the packet */
if(n->compression) if(n->compression) {
{
outpkt = pkt[nextpkt++]; outpkt = pkt[nextpkt++];
if(compress2(outpkt->data, &complen, inpkt->data, inpkt->len, n->compression) != Z_OK) if(compress2
{ (outpkt->data, &complen, inpkt->data, inpkt->len,
syslog(LOG_ERR, _("Error while compressing packet to %s (%s)"), n->name, n->hostname); n->compression) != Z_OK) {
syslog(LOG_ERR, _("Error while compressing packet to %s (%s)"),
n->name, n->hostname);
return; return;
} }
@ -250,13 +257,13 @@ void send_udppacket(node_t *n, vpn_packet_t *inpkt)
/* Encrypt the packet */ /* Encrypt the packet */
if(n->cipher) if(n->cipher) {
{
outpkt = pkt[nextpkt++]; outpkt = pkt[nextpkt++];
EVP_EncryptInit(&ctx, n->cipher, n->key, n->key + n->cipher->key_len); EVP_EncryptInit(&ctx, n->cipher, n->key, n->key + n->cipher->key_len);
EVP_EncryptUpdate(&ctx, (char *)&outpkt->seqno, &outlen, (char *)&inpkt->seqno, inpkt->len); EVP_EncryptUpdate(&ctx, (char *) &outpkt->seqno, &outlen,
EVP_EncryptFinal(&ctx, (char *)&outpkt->seqno + outlen, &outpad); (char *) &inpkt->seqno, inpkt->len);
EVP_EncryptFinal(&ctx, (char *) &outpkt->seqno + outlen, &outpad);
outpkt->len = outlen + outpad; outpkt->len = outlen + outpad;
inpkt = outpkt; inpkt = outpkt;
@ -264,9 +271,9 @@ void send_udppacket(node_t *n, vpn_packet_t *inpkt)
/* Add the message authentication code */ /* Add the message authentication code */
if(n->digest && n->maclength) if(n->digest && n->maclength) {
{ HMAC(n->digest, n->key, n->keylength, (char *) &inpkt->seqno,
HMAC(n->digest, n->key, n->keylength, (char *)&inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len, &outlen); inpkt->len, (char *) &inpkt->seqno + inpkt->len, &outlen);
inpkt->len += n->maclength; inpkt->len += n->maclength;
} }
@ -282,105 +289,103 @@ void send_udppacket(node_t *n, vpn_packet_t *inpkt)
/* Send the packet */ /* Send the packet */
#if defined(SOL_IP) && defined(IP_TOS) #if defined(SOL_IP) && defined(IP_TOS)
if(priorityinheritance && origpriority != priority && listen_socket[sock].sa.sa.sa_family == AF_INET) if(priorityinheritance && origpriority != priority
{ && listen_socket[sock].sa.sa.sa_family == AF_INET) {
priority = origpriority; priority = origpriority;
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Setting outgoing packet priority to %d"), priority); syslog(LOG_DEBUG, _("Setting outgoing packet priority to %d"),
priority);
if(setsockopt(sock, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */ if(setsockopt(sock, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */
syslog(LOG_ERR, _("System call `%s' failed: %s"), "setsockopt", strerror(errno)); syslog(LOG_ERR, _("System call `%s' failed: %s"), "setsockopt",
strerror(errno));
} }
#endif #endif
if((sendto(listen_socket[sock].udp, (char *)&inpkt->seqno, inpkt->len, 0, &(n->address.sa), SALEN(n->address.sa))) < 0) if((sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &(n->address.sa), SALEN(n->address.sa))) < 0) {
{ syslog(LOG_ERR, _("Error sending packet to %s (%s): %s"), n->name,
syslog(LOG_ERR, _("Error sending packet to %s (%s): %s"), n->hostname, strerror(errno));
n->name, n->hostname, strerror(errno));
return; return;
} }
inpkt->len = origlen; inpkt->len = origlen;
cp();
} }
/* /*
send a packet to the given vpn ip. send a packet to the given vpn ip.
*/ */
void send_packet(node_t *n, vpn_packet_t *packet) void send_packet(node_t * n, vpn_packet_t * packet)
{ {
node_t *via; node_t *via;
cp(); cp();
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_ERR, _("Sending packet of %d bytes to %s (%s)"), syslog(LOG_ERR, _("Sending packet of %d bytes to %s (%s)"),
packet->len, n->name, n->hostname); packet->len, n->name, n->hostname);
if(n == myself) if(n == myself) {
{
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
{
syslog(LOG_NOTICE, _("Packet is looping back to us!")); syslog(LOG_NOTICE, _("Packet is looping back to us!"));
}
return; return;
} }
if(!n->status.reachable) if(!n->status.reachable) {
{
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_INFO, _("Node %s (%s) is not reachable"), syslog(LOG_INFO, _("Node %s (%s) is not reachable"),
n->name, n->hostname); n->name, n->hostname);
return; return;
} }
via = (n->via == myself)?n->nexthop:n->via; via = (n->via == myself) ? n->nexthop : n->via;
if(via != n && debug_lvl >= DEBUG_TRAFFIC) if(via != n && debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_ERR, _("Sending packet to %s via %s (%s)"), syslog(LOG_ERR, _("Sending packet to %s via %s (%s)"),
n->name, via->name, n->via->hostname); n->name, via->name, n->via->hostname);
if((myself->options | via->options) & OPTION_TCPONLY) if((myself->options | via->options) & OPTION_TCPONLY) {
{
if(send_tcppacket(via->connection, packet)) if(send_tcppacket(via->connection, packet))
terminate_connection(via->connection, 1); terminate_connection(via->connection, 1);
} } else
else
send_udppacket(via, packet); send_udppacket(via, packet);
} }
/* Broadcast a packet using the minimum spanning tree */ /* Broadcast a packet using the minimum spanning tree */
void broadcast_packet(node_t *from, vpn_packet_t *packet) void broadcast_packet(node_t * from, vpn_packet_t * packet)
{ {
avl_node_t *node; avl_node_t *node;
connection_t *c; connection_t *c;
cp(); cp();
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_INFO, _("Broadcasting packet of %d bytes from %s (%s)"), syslog(LOG_INFO, _("Broadcasting packet of %d bytes from %s (%s)"),
packet->len, from->name, from->hostname); packet->len, from->name, from->hostname);
for(node = connection_tree->head; node; node = node->next) for(node = connection_tree->head; node; node = node->next) {
{ c = (connection_t *) node->data;
c = (connection_t *)node->data;
if(c->status.active && c->status.mst && c != from->nexthop->connection) if(c->status.active && c->status.mst && c != from->nexthop->connection)
send_packet(c->node, packet); send_packet(c->node, packet);
} }
cp();
} }
void flush_queue(node_t *n) void flush_queue(node_t * n)
{ {
list_node_t *node, *next; list_node_t *node, *next;
cp(); cp();
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_INFO, _("Flushing queue for %s (%s)"), n->name, n->hostname); syslog(LOG_INFO, _("Flushing queue for %s (%s)"), n->name, n->hostname);
for(node = n->queue->head; node; node = next) for(node = n->queue->head; node; node = next) {
{
next = node->next; next = node->next;
send_udppacket(n, (vpn_packet_t *)node->data); send_udppacket(n, (vpn_packet_t *) node->data);
list_delete_node(n->queue, node); list_delete_node(n->queue, node);
} }
cp();
} }
void handle_incoming_vpn_data(int sock) void handle_incoming_vpn_data(int sock)
@ -391,24 +396,24 @@ void handle_incoming_vpn_data(int sock)
sockaddr_t from; sockaddr_t from;
socklen_t fromlen = sizeof(from); socklen_t fromlen = sizeof(from);
node_t *n; node_t *n;
cp(); cp();
if(getsockopt(sock, SOL_SOCKET, SO_ERROR, &x, &l) < 0)
{ if(getsockopt(sock, SOL_SOCKET, SO_ERROR, &x, &l) < 0) {
syslog(LOG_ERR, _("This is a bug: %s:%d: %d:%s"), syslog(LOG_ERR, _("This is a bug: %s:%d: %d:%s"),
__FILE__, __LINE__, sock, strerror(errno)); __FILE__, __LINE__, sock, strerror(errno));
cp_trace(); cp_trace();
exit(1); exit(1);
} }
if(x)
{ if(x) {
syslog(LOG_ERR, _("Incoming data socket error: %s"), strerror(x)); syslog(LOG_ERR, _("Incoming data socket error: %s"), strerror(x));
return; return;
} }
pkt.len = recvfrom(sock, (char *)&pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen); pkt.len = recvfrom(sock, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
if(pkt.len <= 0) if(pkt.len <= 0) {
{
syslog(LOG_ERR, _("Receiving packet failed: %s"), strerror(errno)); syslog(LOG_ERR, _("Receiving packet failed: %s"), strerror(errno));
return; return;
} }
@ -417,10 +422,10 @@ void handle_incoming_vpn_data(int sock)
n = lookup_node_udp(&from); n = lookup_node_udp(&from);
if(!n) if(!n) {
{
hostname = sockaddr2hostname(&from); hostname = sockaddr2hostname(&from);
syslog(LOG_WARNING, _("Received UDP packet from unknown source %s"), hostname); syslog(LOG_WARNING, _("Received UDP packet from unknown source %s"),
hostname);
free(hostname); free(hostname);
return; return;
} }
@ -429,5 +434,4 @@ void handle_incoming_vpn_data(int sock)
n->connection->last_ping_time = now; n->connection->last_ping_time = now;
receive_udppacket(n, &pkt); receive_udppacket(n, &pkt);
cp();
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: net_setup.c,v 1.1.2.24 2002/09/09 19:39:58 guus Exp $ $Id: net_setup.c,v 1.1.2.25 2002/09/09 21:24:41 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -27,13 +27,13 @@
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
#ifdef HAVE_NETINET_IN_SYSTM_H #ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
#endif #endif
#ifdef HAVE_NETINET_IP_H #ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h> #include <netinet/ip.h>
#endif #endif
#ifdef HAVE_NETINET_TCP_H #ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -77,19 +77,20 @@
char *myport; char *myport;
int read_rsa_public_key(connection_t *c) int read_rsa_public_key(connection_t * c)
{ {
FILE *fp; FILE *fp;
char *fname; char *fname;
char *key; char *key;
cp(); cp();
if(!c->rsa_key) if(!c->rsa_key)
c->rsa_key = RSA_new(); c->rsa_key = RSA_new();
/* First, check for simple PublicKey statement */ /* First, check for simple PublicKey statement */
if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &key)) if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &key)) {
{
BN_hex2bn(&c->rsa_key->n, key); BN_hex2bn(&c->rsa_key->n, key);
BN_hex2bn(&c->rsa_key->e, "FFFF"); BN_hex2bn(&c->rsa_key->e, "FFFF");
free(key); free(key);
@ -98,45 +99,46 @@ int read_rsa_public_key(connection_t *c)
/* Else, check for PublicKeyFile statement and read it */ /* Else, check for PublicKeyFile statement and read it */
if(get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &fname)) if(get_config_string
{ (lookup_config(c->config_tree, "PublicKeyFile"), &fname)) {
if(is_safe_path(fname)) if(is_safe_path(fname)) {
{
fp = fopen(fname, "r"); fp = fopen(fname, "r");
if(!fp)
{ if(!fp) {
syslog(LOG_ERR, _("Error reading RSA public key file `%s': %s"), syslog(LOG_ERR, _("Error reading RSA public key file `%s': %s"),
fname, strerror(errno)); fname, strerror(errno));
free(fname); free(fname);
return -1; return -1;
} }
free(fname); free(fname);
c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL); c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL);
fclose(fp); fclose(fp);
if(c->rsa_key) if(c->rsa_key)
return 0; /* Woohoo. */ return 0; /* Woohoo. */
/* If it fails, try PEM_read_RSA_PUBKEY. */ /* If it fails, try PEM_read_RSA_PUBKEY. */
fp = fopen(fname, "r"); fp = fopen(fname, "r");
if(!fp)
{ if(!fp) {
syslog(LOG_ERR, _("Error reading RSA public key file `%s': %s"), syslog(LOG_ERR, _("Error reading RSA public key file `%s': %s"),
fname, strerror(errno)); fname, strerror(errno));
free(fname); free(fname);
return -1; return -1;
} }
free(fname); free(fname);
c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL); c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL);
fclose(fp); fclose(fp);
if(c->rsa_key) if(c->rsa_key)
return 0; return 0;
syslog(LOG_ERR, _("Reading RSA public key file `%s' failed: %s"), syslog(LOG_ERR, _("Reading RSA public key file `%s' failed: %s"),
fname, strerror(errno)); fname, strerror(errno));
return -1; return -1;
} } else {
else
{
free(fname); free(fname);
return -1; return -1;
} }
@ -147,8 +149,7 @@ int read_rsa_public_key(connection_t *c)
asprintf(&fname, "%s/hosts/%s", confbase, c->name); asprintf(&fname, "%s/hosts/%s", confbase, c->name);
fp = fopen(fname, "r"); fp = fopen(fname, "r");
if(fp) if(fp) {
{
c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL); c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL);
fclose(fp); fclose(fp);
} }
@ -163,8 +164,7 @@ int read_rsa_public_key(connection_t *c)
asprintf(&fname, "%s/hosts/%s", confbase, c->name); asprintf(&fname, "%s/hosts/%s", confbase, c->name);
fp = fopen(fname, "r"); fp = fopen(fname, "r");
if(fp) if(fp) {
{
c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL); c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL);
fclose(fp); fclose(fp);
} }
@ -175,6 +175,7 @@ int read_rsa_public_key(connection_t *c)
return 0; return 0;
syslog(LOG_ERR, _("No public key for %s specified!"), c->name); syslog(LOG_ERR, _("No public key for %s specified!"), c->name);
return -1; return -1;
} }
@ -182,9 +183,10 @@ int read_rsa_private_key(void)
{ {
FILE *fp; FILE *fp;
char *fname, *key; char *fname, *key;
cp(); cp();
if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key))
{ if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) {
myself->connection->rsa_key = RSA_new(); myself->connection->rsa_key = RSA_new();
BN_hex2bn(&myself->connection->rsa_key->d, key); BN_hex2bn(&myself->connection->rsa_key->d, key);
BN_hex2bn(&myself->connection->rsa_key->e, "FFFF"); BN_hex2bn(&myself->connection->rsa_key->e, "FFFF");
@ -195,25 +197,27 @@ int read_rsa_private_key(void)
if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname)) if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname))
asprintf(&fname, "%s/rsa_key.priv", confbase); asprintf(&fname, "%s/rsa_key.priv", confbase);
if(is_safe_path(fname)) if(is_safe_path(fname)) {
{
fp = fopen(fname, "r"); fp = fopen(fname, "r");
if(!fp)
{ if(!fp) {
syslog(LOG_ERR, _("Error reading RSA private key file `%s': %s"), syslog(LOG_ERR, _("Error reading RSA private key file `%s': %s"),
fname, strerror(errno)); fname, strerror(errno));
free(fname); free(fname);
return -1; return -1;
} }
free(fname); free(fname);
myself->connection->rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); myself->connection->rsa_key =
PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
fclose(fp); fclose(fp);
if(!myself->connection->rsa_key)
{ if(!myself->connection->rsa_key) {
syslog(LOG_ERR, _("Reading RSA private key file `%s' failed: %s"), syslog(LOG_ERR, _("Reading RSA private key file `%s' failed: %s"),
fname, strerror(errno)); fname, strerror(errno));
return -1; return -1;
} }
return 0; return 0;
} }
@ -232,7 +236,9 @@ int setup_myself(void)
char *address = NULL; char *address = NULL;
struct addrinfo hint, *ai, *aip; struct addrinfo hint, *ai, *aip;
int choice, err; int choice, err;
cp(); cp();
myself = new_node(); myself = new_node();
myself->connection = new_connection(); myself->connection = new_connection();
init_configuration(&myself->connection->config_tree); init_configuration(&myself->connection->config_tree);
@ -243,14 +249,12 @@ int setup_myself(void)
myself->connection->options = 0; myself->connection->options = 0;
myself->connection->protocol_version = PROT_CURRENT; myself->connection->protocol_version = PROT_CURRENT;
if(!get_config_string(lookup_config(config_tree, "Name"), &name)) /* Not acceptable */ if(!get_config_string(lookup_config(config_tree, "Name"), &name)) { /* Not acceptable */
{
syslog(LOG_ERR, _("Name for tinc daemon required!")); syslog(LOG_ERR, _("Name for tinc daemon required!"));
return -1; return -1;
} }
if(check_id(name)) if(check_id(name)) {
{
syslog(LOG_ERR, _("Invalid name for myself!")); syslog(LOG_ERR, _("Invalid name for myself!"));
free(name); free(name);
return -1; return -1;
@ -259,29 +263,26 @@ int setup_myself(void)
myself->name = name; myself->name = name;
myself->connection->name = xstrdup(name); myself->connection->name = xstrdup(name);
cp();
if(read_rsa_private_key()) if(read_rsa_private_key())
return -1; return -1;
if(read_connection_config(myself->connection)) if(read_connection_config(myself->connection)) {
{
syslog(LOG_ERR, _("Cannot open host configuration file for myself!")); syslog(LOG_ERR, _("Cannot open host configuration file for myself!"));
return -1; return -1;
} }
if(read_rsa_public_key(myself->connection)) if(read_rsa_public_key(myself->connection))
return -1; return -1;
cp();
if(!get_config_string(lookup_config(myself->connection->config_tree, "Port"), &myport)) if(!get_config_string
(lookup_config(myself->connection->config_tree, "Port"), &myport))
asprintf(&myport, "655"); asprintf(&myport, "655");
/* Read in all the subnets specified in the host configuration file */ /* Read in all the subnets specified in the host configuration file */
cfg = lookup_config(myself->connection->config_tree, "Subnet"); cfg = lookup_config(myself->connection->config_tree, "Subnet");
while(cfg) while(cfg) {
{
if(!get_config_subnet(cfg, &subnet)) if(!get_config_subnet(cfg, &subnet))
return -1; return -1;
@ -290,7 +291,6 @@ int setup_myself(void)
cfg = lookup_config_next(myself->connection->config_tree, cfg); cfg = lookup_config_next(myself->connection->config_tree, cfg);
} }
cp();
/* Check some options */ /* Check some options */
if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice)) if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice))
@ -301,95 +301,87 @@ int setup_myself(void)
if(choice) if(choice)
myself->options |= OPTION_TCPONLY; myself->options |= OPTION_TCPONLY;
if(get_config_bool(lookup_config(myself->connection->config_tree, "IndirectData"), &choice)) if(get_config_bool
(lookup_config(myself->connection->config_tree, "IndirectData"),
&choice))
if(choice) if(choice)
myself->options |= OPTION_INDIRECT; myself->options |= OPTION_INDIRECT;
if(get_config_bool(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice)) if(get_config_bool
(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice))
if(choice) if(choice)
myself->options |= OPTION_TCPONLY; myself->options |= OPTION_TCPONLY;
if(myself->options & OPTION_TCPONLY) if(myself->options & OPTION_TCPONLY)
myself->options |= OPTION_INDIRECT; myself->options |= OPTION_INDIRECT;
if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) {
{
if(!strcasecmp(mode, "router")) if(!strcasecmp(mode, "router"))
routing_mode = RMODE_ROUTER; routing_mode = RMODE_ROUTER;
else if (!strcasecmp(mode, "switch")) else if(!strcasecmp(mode, "switch"))
routing_mode = RMODE_SWITCH; routing_mode = RMODE_SWITCH;
else if (!strcasecmp(mode, "hub")) else if(!strcasecmp(mode, "hub"))
routing_mode = RMODE_HUB; routing_mode = RMODE_HUB;
else else {
{
syslog(LOG_ERR, _("Invalid routing mode!")); syslog(LOG_ERR, _("Invalid routing mode!"));
return -1; return -1;
} }
free(mode); free(mode);
} } else
else
routing_mode = RMODE_ROUTER; routing_mode = RMODE_ROUTER;
get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance); get_config_bool(lookup_config(config_tree, "PriorityInheritance"),
&priorityinheritance);
#if !defined(SOL_IP) || !defined(IP_TOS) #if !defined(SOL_IP) || !defined(IP_TOS)
if(priorityinheritance) if(priorityinheritance)
syslog(LOG_WARNING, _("PriorityInheritance not supported on this platform")); syslog(LOG_WARNING, _("PriorityInheritance not supported on this platform"));
#endif #endif
if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire)) if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire))
macexpire= 600; macexpire = 600;
if(get_config_int(lookup_config(myself->connection->config_tree, "MaxTimeout"), &maxtimeout)) if(get_config_int
{ (lookup_config(myself->connection->config_tree, "MaxTimeout"),
if(maxtimeout <= 0) &maxtimeout)) {
{ if(maxtimeout <= 0) {
syslog(LOG_ERR, _("Bogus maximum timeout!")); syslog(LOG_ERR, _("Bogus maximum timeout!"));
return -1; return -1;
} }
} } else
else
maxtimeout = 900; maxtimeout = 900;
if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) {
{
if(!strcasecmp(afname, "IPv4")) if(!strcasecmp(afname, "IPv4"))
addressfamily = AF_INET; addressfamily = AF_INET;
else if (!strcasecmp(afname, "IPv6")) else if(!strcasecmp(afname, "IPv6"))
addressfamily = AF_INET6; addressfamily = AF_INET6;
else if (!strcasecmp(afname, "any")) else if(!strcasecmp(afname, "any"))
addressfamily = AF_UNSPEC; addressfamily = AF_UNSPEC;
else else {
{
syslog(LOG_ERR, _("Invalid address family!")); syslog(LOG_ERR, _("Invalid address family!"));
return -1; return -1;
} }
free(afname); free(afname);
} } else
else
addressfamily = AF_INET; addressfamily = AF_INET;
get_config_bool(lookup_config(config_tree, "Hostnames"), &hostnames); get_config_bool(lookup_config(config_tree, "Hostnames"), &hostnames);
cp();
/* Generate packet encryption key */ /* Generate packet encryption key */
if(get_config_string(lookup_config(myself->connection->config_tree, "Cipher"), &cipher)) if(get_config_string
{ (lookup_config(myself->connection->config_tree, "Cipher"), &cipher)) {
if(!strcasecmp(cipher, "none")) if(!strcasecmp(cipher, "none")) {
{
myself->cipher = NULL; myself->cipher = NULL;
} } else {
else
{
myself->cipher = EVP_get_cipherbyname(cipher); myself->cipher = EVP_get_cipherbyname(cipher);
if(!myself->cipher) if(!myself->cipher) {
{
syslog(LOG_ERR, _("Unrecognized cipher type!")); syslog(LOG_ERR, _("Unrecognized cipher type!"));
return -1; return -1;
} }
} }
} } else
else
myself->cipher = EVP_bf_cbc(); myself->cipher = EVP_bf_cbc();
if(myself->cipher) if(myself->cipher)
@ -399,7 +391,7 @@ int setup_myself(void)
myself->connection->outcipher = EVP_bf_ofb(); myself->connection->outcipher = EVP_bf_ofb();
myself->key = (char *)xmalloc(myself->keylength); myself->key = (char *) xmalloc(myself->keylength);
RAND_pseudo_bytes(myself->key, myself->keylength); RAND_pseudo_bytes(myself->key, myself->keylength);
if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
@ -409,64 +401,54 @@ int setup_myself(void)
/* Check if we want to use message authentication codes... */ /* Check if we want to use message authentication codes... */
if(get_config_string(lookup_config(myself->connection->config_tree, "Digest"), &digest)) if(get_config_string
{ (lookup_config(myself->connection->config_tree, "Digest"), &digest)) {
if(!strcasecmp(digest, "none")) if(!strcasecmp(digest, "none")) {
{
myself->digest = NULL; myself->digest = NULL;
} } else {
else
{
myself->digest = EVP_get_digestbyname(digest); myself->digest = EVP_get_digestbyname(digest);
if(!myself->digest) if(!myself->digest) {
{
syslog(LOG_ERR, _("Unrecognized digest type!")); syslog(LOG_ERR, _("Unrecognized digest type!"));
return -1; return -1;
} }
} }
} } else
else
myself->digest = EVP_sha1(); myself->digest = EVP_sha1();
myself->connection->outdigest = EVP_sha1(); myself->connection->outdigest = EVP_sha1();
if(get_config_int(lookup_config(myself->connection->config_tree, "MACLength"), &myself->maclength)) if(get_config_int
{ (lookup_config(myself->connection->config_tree, "MACLength"),
if(myself->digest) &myself->maclength)) {
{ if(myself->digest) {
if(myself->maclength > myself->digest->md_size) if(myself->maclength > myself->digest->md_size) {
{
syslog(LOG_ERR, _("MAC length exceeds size of digest!")); syslog(LOG_ERR, _("MAC length exceeds size of digest!"));
return -1; return -1;
} } else if(myself->maclength < 0) {
else if (myself->maclength < 0)
{
syslog(LOG_ERR, _("Bogus MAC length!")); syslog(LOG_ERR, _("Bogus MAC length!"));
return -1; return -1;
} }
} }
} } else
else
myself->maclength = 4; myself->maclength = 4;
myself->connection->outmaclength = 0; myself->connection->outmaclength = 0;
/* Compression */ /* Compression */
if(get_config_int(lookup_config(myself->connection->config_tree, "Compression"), &myself->compression)) if(get_config_int
{ (lookup_config(myself->connection->config_tree, "Compression"),
if(myself->compression < 0 || myself->compression > 9) &myself->compression)) {
{ if(myself->compression < 0 || myself->compression > 9) {
syslog(LOG_ERR, _("Bogus compression level!")); syslog(LOG_ERR, _("Bogus compression level!"));
return -1; return -1;
} }
} } else
else
myself->compression = 0; myself->compression = 0;
myself->connection->outcompression = 0; myself->connection->outcompression = 0;
cp();
/* Done */ /* Done */
myself->nexthop = myself; myself->nexthop = myself;
@ -477,7 +459,6 @@ int setup_myself(void)
graph(); graph();
cp();
/* Open sockets */ /* Open sockets */
memset(&hint, 0, sizeof(hint)); memset(&hint, 0, sizeof(hint));
@ -491,29 +472,29 @@ int setup_myself(void)
err = getaddrinfo(address, myport, &hint, &ai); err = getaddrinfo(address, myport, &hint, &ai);
if(err || !ai) if(err || !ai) {
{ syslog(LOG_ERR, _("System call `%s' failed: %s"), "getaddrinfo",
syslog(LOG_ERR, _("System call `%s' failed: %s"), "getaddrinfo", gai_strerror(err)); gai_strerror(err));
return -1; return -1;
} }
listen_sockets = 0; listen_sockets = 0;
for(aip = ai; aip; aip = aip->ai_next) for(aip = ai; aip; aip = aip->ai_next) {
{ listen_socket[listen_sockets].tcp =
listen_socket[listen_sockets].tcp = setup_listen_socket((sockaddr_t *)aip->ai_addr); setup_listen_socket((sockaddr_t *) aip->ai_addr);
if(listen_socket[listen_sockets].tcp < 0) if(listen_socket[listen_sockets].tcp < 0)
continue; continue;
listen_socket[listen_sockets].udp = setup_vpn_in_socket((sockaddr_t *)aip->ai_addr); listen_socket[listen_sockets].udp =
setup_vpn_in_socket((sockaddr_t *) aip->ai_addr);
if(listen_socket[listen_sockets].udp < 0) if(listen_socket[listen_sockets].udp < 0)
continue; continue;
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS) {
{ hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr);
hostname = sockaddr2hostname((sockaddr_t *)aip->ai_addr);
syslog(LOG_NOTICE, _("Listening on %s"), hostname); syslog(LOG_NOTICE, _("Listening on %s"), hostname);
free(hostname); free(hostname);
} }
@ -526,12 +507,11 @@ int setup_myself(void)
if(listen_sockets) if(listen_sockets)
syslog(LOG_NOTICE, _("Ready")); syslog(LOG_NOTICE, _("Ready"));
else else {
{
syslog(LOG_ERR, _("Unable to create any listening socket!")); syslog(LOG_ERR, _("Unable to create any listening socket!"));
return -1; return -1;
} }
cp();
return 0; return 0;
} }
@ -542,7 +522,9 @@ int setup_network_connections(void)
{ {
char *envp[4]; char *envp[4];
int i; int i;
cp(); cp();
now = time(NULL); now = time(NULL);
init_connections(); init_connections();
@ -552,23 +534,20 @@ int setup_network_connections(void)
init_events(); init_events();
init_requests(); init_requests();
if(get_config_int(lookup_config(config_tree, "PingTimeout"), &pingtimeout)) if(get_config_int(lookup_config(config_tree, "PingTimeout"), &pingtimeout)) {
{ if(pingtimeout < 1) {
if(pingtimeout < 1)
{
pingtimeout = 86400; pingtimeout = 86400;
} }
} } else
else
pingtimeout = 60; pingtimeout = 60;
if(setup_device() < 0) if(setup_device() < 0)
return -1; return -1;
/* Run tinc-up script to further initialize the tap interface */ /* Run tinc-up script to further initialize the tap interface */
asprintf(&envp[0], "NETNAME=%s", netname?:""); asprintf(&envp[0], "NETNAME=%s", netname ? : "");
asprintf(&envp[1], "DEVICE=%s", device?:""); asprintf(&envp[1], "DEVICE=%s", device ? : "");
asprintf(&envp[2], "INTERFACE=%s", interface?:""); asprintf(&envp[2], "INTERFACE=%s", interface ? : "");
envp[3] = NULL; envp[3] = NULL;
execute_script("tinc-up", envp); execute_script("tinc-up", envp);
@ -580,7 +559,7 @@ int setup_network_connections(void)
return -1; return -1;
try_outgoing_connections(); try_outgoing_connections();
cp();
return 0; return 0;
} }
@ -593,11 +572,13 @@ void close_network_connections(void)
connection_t *c; connection_t *c;
char *envp[4]; char *envp[4];
int i; int i;
cp(); cp();
for(node = connection_tree->head; node; node = next)
{ for(node = connection_tree->head; node; node = next) {
next = node->next; next = node->next;
c = (connection_t *)node->data; c = (connection_t *) node->data;
if(c->outgoing) if(c->outgoing)
free(c->outgoing->name), free(c->outgoing), c->outgoing = NULL; free(c->outgoing->name), free(c->outgoing), c->outgoing = NULL;
terminate_connection(c, 0); terminate_connection(c, 0);
@ -606,8 +587,7 @@ void close_network_connections(void)
if(myself && myself->connection) if(myself && myself->connection)
terminate_connection(myself->connection, 0); terminate_connection(myself->connection, 0);
for(i = 0; i < listen_sockets; i++) for(i = 0; i < listen_sockets; i++) {
{
close(listen_socket[i].tcp); close(listen_socket[i].tcp);
close(listen_socket[i].udp); close(listen_socket[i].udp);
} }
@ -619,9 +599,9 @@ void close_network_connections(void)
exit_nodes(); exit_nodes();
exit_connections(); exit_connections();
asprintf(&envp[0], "NETNAME=%s", netname?:""); asprintf(&envp[0], "NETNAME=%s", netname ? : "");
asprintf(&envp[1], "DEVICE=%s", device?:""); asprintf(&envp[1], "DEVICE=%s", device ? : "");
asprintf(&envp[2], "INTERFACE=%s", interface?:""); asprintf(&envp[2], "INTERFACE=%s", interface ? : "");
envp[3] = NULL; envp[3] = NULL;
execute_script("tinc-down", envp); execute_script("tinc-down", envp);
@ -630,6 +610,6 @@ void close_network_connections(void)
free(envp[i]); free(envp[i]);
close_device(); close_device();
cp();
return; return;
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: net_socket.c,v 1.1.2.19 2002/09/09 19:39:59 guus Exp $ $Id: net_socket.c,v 1.1.2.20 2002/09/09 21:24:41 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -27,13 +27,13 @@
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
#ifdef HAVE_NETINET_IN_SYSTM_H #ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
#endif #endif
#ifdef HAVE_NETINET_IP_H #ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h> #include <netinet/ip.h>
#endif #endif
#ifdef HAVE_NETINET_TCP_H #ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -84,7 +84,7 @@ int listen_sockets;
/* Setup sockets */ /* Setup sockets */
int setup_listen_socket(sockaddr_t *sa) int setup_listen_socket(sockaddr_t * sa)
{ {
int nfd, flags; int nfd, flags;
char *addrstr; char *addrstr;
@ -93,20 +93,22 @@ int setup_listen_socket(sockaddr_t *sa)
char *interface; char *interface;
struct ifreq ifr; struct ifreq ifr;
#endif #endif
cp(); cp();
nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP); nfd = socket(sa->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
if(nfd < 0) if(nfd < 0) {
{
syslog(LOG_ERR, _("Creating metasocket failed: %s"), strerror(errno)); syslog(LOG_ERR, _("Creating metasocket failed: %s"), strerror(errno));
return -1; return -1;
} }
flags = fcntl(nfd, F_GETFL); flags = fcntl(nfd, F_GETFL);
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0)
{ if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
close(nfd); close(nfd);
syslog(LOG_ERR, _("System call `%s' failed: %s"), "fcntl", strerror(errno)); syslog(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
strerror(errno));
return -1; return -1;
} }
@ -124,15 +126,16 @@ int setup_listen_socket(sockaddr_t *sa)
setsockopt(nfd, SOL_IP, IP_TOS, &option, sizeof(option)); setsockopt(nfd, SOL_IP, IP_TOS, &option, sizeof(option));
#endif #endif
if(get_config_string(lookup_config(config_tree, "BindToInterface"), &interface)) if(get_config_string
{ (lookup_config(config_tree, "BindToInterface"), &interface)) {
#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
memset(&ifr, 0, sizeof(ifr)); memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, interface, IFNAMSIZ); strncpy(ifr.ifr_ifrn.ifrn_name, interface, IFNAMSIZ);
if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)))
{ if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr))) {
close(nfd); close(nfd);
syslog(LOG_ERR, _("Can't bind to interface %s: %s"), interface, strerror(errno)); syslog(LOG_ERR, _("Can't bind to interface %s: %s"), interface,
strerror(errno));
return -1; return -1;
} }
#else #else
@ -140,26 +143,26 @@ int setup_listen_socket(sockaddr_t *sa)
#endif #endif
} }
if(bind(nfd, &sa->sa, SALEN(sa->sa))) if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
{
close(nfd); close(nfd);
addrstr = sockaddr2hostname(sa); addrstr = sockaddr2hostname(sa);
syslog(LOG_ERR, _("Can't bind to %s/tcp: %s"), addrstr, strerror(errno)); syslog(LOG_ERR, _("Can't bind to %s/tcp: %s"), addrstr,
strerror(errno));
free(addrstr); free(addrstr);
return -1; return -1;
} }
if(listen(nfd, 3)) if(listen(nfd, 3)) {
{
close(nfd); close(nfd);
syslog(LOG_ERR, _("System call `%s' failed: %s"), "listen", strerror(errno)); syslog(LOG_ERR, _("System call `%s' failed: %s"), "listen",
strerror(errno));
return -1; return -1;
} }
cp();
return nfd; return nfd;
} }
int setup_vpn_in_socket(sockaddr_t *sa) int setup_vpn_in_socket(sockaddr_t * sa)
{ {
int nfd, flags; int nfd, flags;
char *addrstr; char *addrstr;
@ -168,20 +171,21 @@ int setup_vpn_in_socket(sockaddr_t *sa)
char *interface; char *interface;
struct ifreq ifr; struct ifreq ifr;
#endif #endif
cp(); cp();
nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP); nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
if(nfd < 0) if(nfd < 0) {
{
syslog(LOG_ERR, _("Creating UDP socket failed: %s"), strerror(errno)); syslog(LOG_ERR, _("Creating UDP socket failed: %s"), strerror(errno));
return -1; return -1;
} }
flags = fcntl(nfd, F_GETFL); flags = fcntl(nfd, F_GETFL);
if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
{
close(nfd); close(nfd);
syslog(LOG_ERR, _("System call `%s' failed: %s"), "fcntl", strerror(errno)); syslog(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
strerror(errno));
return -1; return -1;
} }
@ -189,62 +193,70 @@ int setup_vpn_in_socket(sockaddr_t *sa)
setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) #if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
if(get_config_string(lookup_config(config_tree, "BindToInterface"), &interface)) if(get_config_string
{ (lookup_config(config_tree, "BindToInterface"), &interface)) {
memset(&ifr, 0, sizeof(ifr)); memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, interface, IFNAMSIZ); strncpy(ifr.ifr_ifrn.ifrn_name, interface, IFNAMSIZ);
if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)))
{ if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr))) {
close(nfd); close(nfd);
syslog(LOG_ERR, _("Can't bind to interface %s: %s"), interface, strerror(errno)); syslog(LOG_ERR, _("Can't bind to interface %s: %s"), interface,
strerror(errno));
return -1; return -1;
} }
} }
#endif #endif
if(bind(nfd, &sa->sa, SALEN(sa->sa))) if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
{
close(nfd); close(nfd);
addrstr = sockaddr2hostname(sa); addrstr = sockaddr2hostname(sa);
syslog(LOG_ERR, _("Can't bind to %s/udp: %s"), addrstr, strerror(errno)); syslog(LOG_ERR, _("Can't bind to %s/udp: %s"), addrstr,
strerror(errno));
free(addrstr); free(addrstr);
return -1; return -1;
} }
cp();
return nfd; return nfd;
} }
void retry_outgoing(outgoing_t *outgoing) void retry_outgoing(outgoing_t * outgoing)
{ {
event_t *event; event_t *event;
cp(); cp();
outgoing->timeout += 5; outgoing->timeout += 5;
if(outgoing->timeout > maxtimeout) if(outgoing->timeout > maxtimeout)
outgoing->timeout = maxtimeout; outgoing->timeout = maxtimeout;
event = new_event(); event = new_event();
event->handler = (event_handler_t)setup_outgoing_connection; event->handler = (event_handler_t) setup_outgoing_connection;
event->time = now + outgoing->timeout; event->time = now + outgoing->timeout;
event->data = outgoing; event->data = outgoing;
event_add(event); event_add(event);
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_NOTICE, _("Trying to re-establish outgoing connection in %d seconds"), outgoing->timeout); syslog(LOG_NOTICE,
cp(); _("Trying to re-establish outgoing connection in %d seconds"),
outgoing->timeout);
} }
int setup_outgoing_socket(connection_t *c) int setup_outgoing_socket(connection_t * c)
{ {
int option; int option;
cp(); cp();
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_INFO, _("Trying to connect to %s (%s)"), c->name, c->hostname); syslog(LOG_INFO, _("Trying to connect to %s (%s)"), c->name,
c->hostname);
c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
if(c->socket == -1) if(c->socket == -1) {
{ syslog(LOG_ERR, _("Creating socket for %s failed: %s"), c->hostname,
syslog(LOG_ERR, _("Creating socket for %s failed: %s"), c->hostname, strerror(errno)); strerror(errno));
return -1; return -1;
} }
@ -262,44 +274,45 @@ int setup_outgoing_socket(connection_t *c)
/* Connect */ /* Connect */
if(connect(c->socket, &c->address.sa, SALEN(c->address.sa)) == -1) if(connect(c->socket, &c->address.sa, SALEN(c->address.sa)) == -1) {
{
close(c->socket); close(c->socket);
syslog(LOG_ERR, _("Error while connecting to %s (%s): %s"), c->name, c->hostname, strerror(errno)); syslog(LOG_ERR, _("Error while connecting to %s (%s): %s"), c->name,
c->hostname, strerror(errno));
return -1; return -1;
} }
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_INFO, _("Connected to %s (%s)"), c->name, c->hostname); syslog(LOG_INFO, _("Connected to %s (%s)"), c->name, c->hostname);
cp();
return 0; return 0;
} }
void finish_connecting(connection_t *c) void finish_connecting(connection_t * c)
{ {
cp(); cp();
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_INFO, _("Connected to %s (%s)"), c->name, c->hostname); syslog(LOG_INFO, _("Connected to %s (%s)"), c->name, c->hostname);
c->last_ping_time = now; c->last_ping_time = now;
send_id(c); send_id(c);
cp();
} }
void do_outgoing_connection(connection_t *c) void do_outgoing_connection(connection_t * c)
{ {
char *address, *port; char *address, *port;
int option, result, flags; int option, result, flags;
cp(); cp();
begin: begin:
if(!c->outgoing->ai) if(!c->outgoing->ai) {
{ if(!c->outgoing->cfg) {
if(!c->outgoing->cfg)
{
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_ERR, _("Could not set up a meta connection to %s"), c->name); syslog(LOG_ERR, _("Could not set up a meta connection to %s"),
c->name);
c->status.remove = 1; c->status.remove = 1;
retry_outgoing(c->outgoing); retry_outgoing(c->outgoing);
return; return;
@ -318,14 +331,14 @@ begin:
c->outgoing->cfg = lookup_config_next(c->config_tree, c->outgoing->cfg); c->outgoing->cfg = lookup_config_next(c->config_tree, c->outgoing->cfg);
} }
if(!c->outgoing->aip) if(!c->outgoing->aip) {
{
freeaddrinfo(c->outgoing->ai); freeaddrinfo(c->outgoing->ai);
c->outgoing->ai = NULL; c->outgoing->ai = NULL;
goto begin; goto begin;
} }
memcpy(&c->address, c->outgoing->aip->ai_addr, c->outgoing->aip->ai_addrlen); memcpy(&c->address, c->outgoing->aip->ai_addr,
c->outgoing->aip->ai_addrlen);
c->outgoing->aip = c->outgoing->aip->ai_next; c->outgoing->aip = c->outgoing->aip->ai_next;
if(c->hostname) if(c->hostname)
@ -334,14 +347,15 @@ begin:
c->hostname = sockaddr2hostname(&c->address); c->hostname = sockaddr2hostname(&c->address);
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_INFO, _("Trying to connect to %s (%s)"), c->name, c->hostname); syslog(LOG_INFO, _("Trying to connect to %s (%s)"), c->name,
c->hostname);
c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
if(c->socket == -1) if(c->socket == -1) {
{
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_ERR, _("Creating socket for %s failed: %s"), c->hostname, strerror(errno)); syslog(LOG_ERR, _("Creating socket for %s failed: %s"), c->hostname,
strerror(errno));
goto begin; goto begin;
} }
@ -362,8 +376,7 @@ begin:
flags = fcntl(c->socket, F_GETFL); flags = fcntl(c->socket, F_GETFL);
if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) if(fcntl(c->socket, F_SETFL, flags | O_NONBLOCK) < 0) {
{
syslog(LOG_ERR, _("fcntl for %s: %s"), c->hostname, strerror(errno)); syslog(LOG_ERR, _("fcntl for %s: %s"), c->hostname, strerror(errno));
} }
@ -371,10 +384,8 @@ begin:
result = connect(c->socket, &c->address.sa, SALEN(c->address.sa)); result = connect(c->socket, &c->address.sa, SALEN(c->address.sa));
if(result == -1) if(result == -1) {
{ if(errno == EINPROGRESS) {
if(errno == EINPROGRESS)
{
c->status.connecting = 1; c->status.connecting = 1;
return; return;
} }
@ -388,22 +399,24 @@ begin:
} }
finish_connecting(c); finish_connecting(c);
return; return;
cp();
} }
void setup_outgoing_connection(outgoing_t *outgoing) void setup_outgoing_connection(outgoing_t * outgoing)
{ {
connection_t *c; connection_t *c;
node_t *n; node_t *n;
cp(); cp();
n = lookup_node(outgoing->name); n = lookup_node(outgoing->name);
if(n) if(n)
if(n->connection) if(n->connection) {
{
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_INFO, _("Already connected to %s"), outgoing->name); syslog(LOG_INFO, _("Already connected to %s"), outgoing->name);
n->connection->outgoing = outgoing; n->connection->outgoing = outgoing;
return; return;
} }
@ -420,8 +433,7 @@ void setup_outgoing_connection(outgoing_t *outgoing)
outgoing->cfg = lookup_config(c->config_tree, "Address"); outgoing->cfg = lookup_config(c->config_tree, "Address");
if(!outgoing->cfg) if(!outgoing->cfg) {
{
syslog(LOG_ERR, _("No address specified for %s"), c->name); syslog(LOG_ERR, _("No address specified for %s"), c->name);
free_connection(c); free_connection(c);
free(outgoing->name); free(outgoing->name);
@ -446,12 +458,14 @@ int handle_new_meta_connection(int sock)
connection_t *c; connection_t *c;
sockaddr_t sa; sockaddr_t sa;
int fd, len = sizeof(sa); int fd, len = sizeof(sa);
cp(); cp();
fd = accept(sock, &sa.sa, &len); fd = accept(sock, &sa.sa, &len);
if(fd < 0) if(fd < 0) {
{ syslog(LOG_ERR, _("Accepting a new connection failed: %s"),
syslog(LOG_ERR, _("Accepting a new connection failed: %s"), strerror(errno)); strerror(errno));
return -1; return -1;
} }
@ -475,7 +489,7 @@ int handle_new_meta_connection(int sock)
c->allow_request = ID; c->allow_request = ID;
send_id(c); send_id(c);
cp();
return 0; return 0;
} }
@ -484,14 +498,17 @@ void try_outgoing_connections(void)
static config_t *cfg = NULL; static config_t *cfg = NULL;
char *name; char *name;
outgoing_t *outgoing; outgoing_t *outgoing;
cp(); cp();
for(cfg = lookup_config(config_tree, "ConnectTo"); cfg; cfg = lookup_config_next(config_tree, cfg))
{ for(cfg = lookup_config(config_tree, "ConnectTo"); cfg;
cfg = lookup_config_next(config_tree, cfg)) {
get_config_string(cfg, &name); get_config_string(cfg, &name);
if(check_id(name)) if(check_id(name)) {
{ syslog(LOG_ERR,
syslog(LOG_ERR, _("Invalid name for outgoing connection in %s line %d"), cfg->file, cfg->line); _("Invalid name for outgoing connection in %s line %d"),
cfg->file, cfg->line);
free(name); free(name);
continue; continue;
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.1.2.4 2002/06/21 10:11:36 guus Exp $ $Id: device.c,v 1.1.2.5 2002/09/09 21:25:23 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -67,16 +67,13 @@ int setup_device(void)
device = DEFAULT_DEVICE; device = DEFAULT_DEVICE;
if(!get_config_string(lookup_config(config_tree, "Interface"), &interface)) if(!get_config_string(lookup_config(config_tree, "Interface"), &interface))
interface = rindex(device, '/')?rindex(device, '/')+1:device; interface = rindex(device, '/') ? rindex(device, '/') + 1 : device;
cp cp if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0)
{
syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno));
return -1; return -1;
} }
cp cp
/* Set default MAC address for ethertap devices */ /* Set default MAC address for ethertap devices */
mymac.type = SUBNET_MAC; mymac.type = SUBNET_MAC;
mymac.net.mac.address.x[0] = 0xfe; mymac.net.mac.address.x[0] = 0xfe;
mymac.net.mac.address.x[1] = 0xfd; mymac.net.mac.address.x[1] = 0xfd;
@ -88,25 +85,20 @@ cp
device_info = _("NetBSD tun device"); device_info = _("NetBSD tun device");
syslog(LOG_INFO, _("%s is a %s"), device, device_info); syslog(LOG_INFO, _("%s is a %s"), device, device_info);
cp cp return 0;
return 0;
} }
void close_device(void) void close_device(void)
{ {
cp cp close(device_fd);
close(device_fd); cp}
cp
}
int read_packet(vpn_packet_t *packet) int read_packet(vpn_packet_t * packet)
{ {
int lenin; int lenin;
cp cp if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) {
syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) device, strerror(errno));
{
syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno));
return -1; return -1;
} }
@ -119,37 +111,32 @@ cp
device_total_in += packet->len; device_total_in += packet->len;
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC) {
{ syslog(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len,
syslog(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); device_info);
} }
return 0; return 0;
cp cp}
}
int write_packet(vpn_packet_t *packet) int write_packet(vpn_packet_t * packet)
{ {
cp cp if(debug_lvl >= DEBUG_TRAFFIC)
if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"), syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"),
packet->len, device_info); packet->len, device_info);
if(write(device_fd, packet->data + 14, packet->len - 14) < 0) if(write(device_fd, packet->data + 14, packet->len - 14) < 0) {
{ syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device,
syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); strerror(errno));
return -1; return -1;
} }
device_total_out += packet->len; device_total_out += packet->len;
cp cp}
}
void dump_device_stats(void) void dump_device_stats(void)
{ {
cp cp syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in);
syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out);
cp cp}
}

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: netutl.c,v 1.12.4.42 2002/09/09 19:39:59 guus Exp $ $Id: netutl.c,v 1.12.4.43 2002/09/09 21:24:41 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -28,7 +28,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef HAVE_INTTYPES_H #ifdef HAVE_INTTYPES_H
#include <inttypes.h> #include <inttypes.h>
#endif #endif
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
@ -56,7 +56,9 @@ struct addrinfo *str2addrinfo(char *address, char *service, int socktype)
{ {
struct addrinfo hint, *ai; struct addrinfo hint, *ai;
int err; int err;
cp(); cp();
memset(&hint, 0, sizeof(hint)); memset(&hint, 0, sizeof(hint));
hint.ai_family = addressfamily; hint.ai_family = addressfamily;
@ -64,15 +66,14 @@ struct addrinfo *str2addrinfo(char *address, char *service, int socktype)
err = getaddrinfo(address, service, &hint, &ai); err = getaddrinfo(address, service, &hint, &ai);
if(err) if(err) {
{
if(debug_lvl >= DEBUG_ERROR) if(debug_lvl >= DEBUG_ERROR)
syslog(LOG_WARNING, _("Error looking up %s port %s: %s\n"), address, service, gai_strerror(err)); syslog(LOG_WARNING, _("Error looking up %s port %s: %s\n"), address,
service, gai_strerror(err));
cp_trace(); cp_trace();
return NULL; return NULL;
} }
cp();
return ai; return ai;
} }
@ -81,7 +82,9 @@ sockaddr_t str2sockaddr(char *address, char *port)
struct addrinfo hint, *ai; struct addrinfo hint, *ai;
sockaddr_t result; sockaddr_t result;
int err; int err;
cp(); cp();
memset(&hint, 0, sizeof(hint)); memset(&hint, 0, sizeof(hint));
hint.ai_family = AF_UNSPEC; hint.ai_family = AF_UNSPEC;
@ -90,32 +93,34 @@ sockaddr_t str2sockaddr(char *address, char *port)
err = getaddrinfo(address, port, &hint, &ai); err = getaddrinfo(address, port, &hint, &ai);
if(err || !ai) if(err || !ai) {
{ syslog(LOG_ERR, _("Error looking up %s port %s: %s\n"), address, port,
syslog(LOG_ERR, _("Error looking up %s port %s: %s\n"), address, port, gai_strerror(err)); gai_strerror(err));
cp_trace(); cp_trace();
raise(SIGFPE); raise(SIGFPE);
exit(0); exit(0);
} }
result = *(sockaddr_t *)ai->ai_addr; result = *(sockaddr_t *) ai->ai_addr;
freeaddrinfo(ai); freeaddrinfo(ai);
cp();
return result; return result;
} }
void sockaddr2str(sockaddr_t *sa, char **addrstr, char **portstr) void sockaddr2str(sockaddr_t * sa, char **addrstr, char **portstr)
{ {
char address[NI_MAXHOST]; char address[NI_MAXHOST];
char port[NI_MAXSERV]; char port[NI_MAXSERV];
char *scopeid; char *scopeid;
int err; int err;
cp();
err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV);
if(err) cp();
{
syslog(LOG_ERR, _("Error while translating addresses: %s"), gai_strerror(err)); err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
if(err) {
syslog(LOG_ERR, _("Error while translating addresses: %s"),
gai_strerror(err));
cp_trace(); cp_trace();
raise(SIGFPE); raise(SIGFPE);
exit(0); exit(0);
@ -128,64 +133,73 @@ void sockaddr2str(sockaddr_t *sa, char **addrstr, char **portstr)
*addrstr = xstrdup(address); *addrstr = xstrdup(address);
*portstr = xstrdup(port); *portstr = xstrdup(port);
cp();
} }
char *sockaddr2hostname(sockaddr_t *sa) char *sockaddr2hostname(sockaddr_t * sa)
{ {
char *str; char *str;
char address[NI_MAXHOST] = "unknown"; char address[NI_MAXHOST] = "unknown";
char port[NI_MAXSERV] = "unknown"; char port[NI_MAXSERV] = "unknown";
int err; int err;
cp(); cp();
err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), hostnames?0:(NI_NUMERICHOST|NI_NUMERICSERV));
if(err) 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)); if(err) {
syslog(LOG_ERR, _("Error while looking up hostname: %s"),
gai_strerror(err));
} }
asprintf(&str, _("%s port %s"), address, port); asprintf(&str, _("%s port %s"), address, port);
cp();
return str; return str;
} }
int sockaddrcmp(sockaddr_t *a, sockaddr_t *b) int sockaddrcmp(sockaddr_t * a, sockaddr_t * b)
{ {
int result; int result;
cp(); cp();
result = a->sa.sa_family - b->sa.sa_family; result = a->sa.sa_family - b->sa.sa_family;
if(result) if(result)
return result; return result;
switch(a->sa.sa_family) switch (a->sa.sa_family) {
{
case AF_UNSPEC: case AF_UNSPEC:
return 0; return 0;
case AF_INET: case AF_INET:
result = memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr)); result = memcmp(&a->in.sin_addr, &b->in.sin_addr, sizeof(a->in.sin_addr));
if(result) if(result)
return result; return result;
return memcmp(&a->in.sin_port, &b->in.sin_port, sizeof(a->in.sin_port)); return memcmp(&a->in.sin_port, &b->in.sin_port, sizeof(a->in.sin_port));
case AF_INET6: case AF_INET6:
result = memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)); result = memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr));
if(result) if(result)
return result; return result;
return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof(a->in6.sin6_port)); return memcmp(&a->in6.sin6_port, &b->in6.sin6_port, sizeof(a->in6.sin6_port));
default: default:
syslog(LOG_ERR, _("sockaddrcmp() was called with unknown address family %d, exitting!"), a->sa.sa_family); syslog(LOG_ERR, _("sockaddrcmp() was called with unknown address family %d, exitting!"),
a->sa.sa_family);
cp_trace(); cp_trace();
raise(SIGFPE); raise(SIGFPE);
exit(0); exit(0);
} }
cp();
} }
void sockaddrunmap(sockaddr_t *sa) void sockaddrunmap(sockaddr_t * sa)
{ {
if(sa->sa.sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sa->in6.sin6_addr)) 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_addr.s_addr = ((uint32_t *)&sa->in6.sin6_addr)[3];
sa->in.sin_family = AF_INET; sa->in.sin_family = AF_INET;
} }
} }
@ -197,16 +211,18 @@ int maskcmp(void *va, void *vb, int masklen, int len)
int i, m, result; int i, m, result;
char *a = va; char *a = va;
char *b = vb; char *b = vb;
cp(); cp();
for(m = masklen, i = 0; m >= 8; m -= 8, i++)
{ for(m = masklen, i = 0; m >= 8; m -= 8, i++) {
result = a[i] - b[i]; result = a[i] - b[i];
if(result) if(result)
return result; return result;
} }
if(m) if(m)
return (a[i] & (0x100 - (1 << (8 - m)))) - (b[i] & (0x100 - (1 << (8 - m)))); return (a[i] & (0x100 - (1 << (8 - m)))) -
(b[i] & (0x100 - (1 << (8 - m))));
return 0; return 0;
} }
@ -215,7 +231,9 @@ void mask(void *va, int masklen, int len)
{ {
int i; int i;
char *a = va; char *a = va;
cp(); cp();
i = masklen / 8; i = masklen / 8;
masklen %= 8; masklen %= 8;
@ -231,12 +249,13 @@ void maskcpy(void *va, void *vb, int masklen, int len)
int i, m; int i, m;
char *a = va; char *a = va;
char *b = vb; char *b = vb;
cp(); cp();
for(m = masklen, i = 0; m >= 8; m -= 8, i++) for(m = masklen, i = 0; m >= 8; m -= 8, i++)
a[i] = b[i]; a[i] = b[i];
if(m) if(m) {
{
a[i] = b[i] & (0x100 - (1 << m)); a[i] = b[i] & (0x100 - (1 << m));
i++; i++;
} }
@ -249,7 +268,9 @@ int maskcheck(void *va, int masklen, int len)
{ {
int i; int i;
char *a = va; char *a = va;
cp(); cp();
i = masklen / 8; i = masklen / 8;
masklen %= 8; masklen %= 8;

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: netutl.h,v 1.2.4.13 2002/06/21 10:11:13 guus Exp $ $Id: netutl.h,v 1.2.4.14 2002/09/09 21:24:41 guus Exp $
*/ */
#ifndef __TINC_NETUTL_H__ #ifndef __TINC_NETUTL_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: node.c,v 1.1.2.16 2002/09/09 19:39:59 guus Exp $ $Id: node.c,v 1.1.2.17 2002/09/09 21:24:41 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -39,100 +39,109 @@ avl_tree_t *node_udp_tree; /* Known nodes, sorted by address and port */
node_t *myself; node_t *myself;
int node_compare(node_t *a, node_t *b) int node_compare(node_t * a, node_t * b)
{ {
return strcmp(a->name, b->name); return strcmp(a->name, b->name);
} }
int node_udp_compare(node_t *a, node_t *b) int node_udp_compare(node_t * a, node_t * b)
{ {
int result; int result;
cp(); cp();
result = sockaddrcmp(&a->address, &b->address); result = sockaddrcmp(&a->address, &b->address);
if(result) if(result)
return result; return result;
return (a->name && b->name)?strcmp(a->name, b->name):0; return (a->name && b->name) ? strcmp(a->name, b->name) : 0;
} }
void init_nodes(void) void init_nodes(void)
{ {
cp(); 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); node_tree = avl_alloc_tree((avl_compare_t) node_compare, NULL);
cp(); node_udp_tree = avl_alloc_tree((avl_compare_t) node_udp_compare, NULL);
} }
void exit_nodes(void) void exit_nodes(void)
{ {
cp(); cp();
avl_delete_tree(node_tree); avl_delete_tree(node_tree);
avl_delete_tree(node_udp_tree); avl_delete_tree(node_udp_tree);
cp();
} }
node_t *new_node(void) node_t *new_node(void)
{ {
node_t *n = (node_t *)xmalloc_and_zero(sizeof(*n)); node_t *n = (node_t *) xmalloc_and_zero(sizeof(*n));
cp(); cp();
n->subnet_tree = new_subnet_tree(); n->subnet_tree = new_subnet_tree();
n->edge_tree = new_edge_tree(); n->edge_tree = new_edge_tree();
n->queue = list_alloc((list_action_t)free); n->queue = list_alloc((list_action_t) free);
cp();
return n; return n;
} }
void free_node(node_t *n) void free_node(node_t * n)
{ {
cp(); cp();
if(n->queue) if(n->queue)
list_delete_list(n->queue); list_delete_list(n->queue);
if(n->name) if(n->name)
free(n->name); free(n->name);
if(n->hostname) if(n->hostname)
free(n->hostname); free(n->hostname);
if(n->key) if(n->key)
free(n->key); free(n->key);
if(n->subnet_tree) if(n->subnet_tree)
free_subnet_tree(n->subnet_tree); free_subnet_tree(n->subnet_tree);
if(n->edge_tree) if(n->edge_tree)
free_edge_tree(n->edge_tree); free_edge_tree(n->edge_tree);
free(n); free(n);
cp();
} }
void node_add(node_t *n) void node_add(node_t * n)
{ {
cp(); cp();
avl_insert(node_tree, n); avl_insert(node_tree, n);
avl_insert(node_udp_tree, n); avl_insert(node_udp_tree, n);
cp();
} }
void node_del(node_t *n) void node_del(node_t * n)
{ {
avl_node_t *node, *next; avl_node_t *node, *next;
edge_t *e; edge_t *e;
subnet_t *s; subnet_t *s;
cp(); cp();
for(node = n->subnet_tree->head; node; node = next)
{ for(node = n->subnet_tree->head; node; node = next) {
next = node->next; next = node->next;
s = (subnet_t *)node->data; s = (subnet_t *) node->data;
subnet_del(n, s); subnet_del(n, s);
} }
for(node = n->edge_tree->head; node; node = next) for(node = n->edge_tree->head; node; node = next) {
{
next = node->next; next = node->next;
e = (edge_t *)node->data; e = (edge_t *) node->data;
edge_del(e); edge_del(e);
} }
cp();
avl_delete(node_tree, n); avl_delete(node_tree, n);
avl_delete(node_udp_tree, n); avl_delete(node_udp_tree, n);
cp();
} }
node_t *lookup_node(char *name) node_t *lookup_node(char *name)
@ -143,7 +152,7 @@ node_t *lookup_node(char *name)
return avl_search(node_tree, &n); return avl_search(node_tree, &n);
} }
node_t *lookup_node_udp(sockaddr_t *sa) node_t *lookup_node_udp(sockaddr_t * sa)
{ {
node_t n; node_t n;
cp(); cp();
@ -157,17 +166,19 @@ void dump_nodes(void)
{ {
avl_node_t *node; avl_node_t *node;
node_t *n; node_t *n;
cp(); cp();
syslog(LOG_DEBUG, _("Nodes:")); syslog(LOG_DEBUG, _("Nodes:"));
for(node = node_tree->head; node; node = node->next) for(node = node_tree->head; node; node = node->next) {
{ n = (node_t *) node->data;
n = (node_t *)node->data;
syslog(LOG_DEBUG, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s"), 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->name, n->hostname, n->cipher ? n->cipher->nid : 0,
n->status, n->nexthop?n->nexthop->name:"-", n->via?n->via->name:"-"); n->digest ? n->digest->type : 0, n->maclength, n->compression,
n->options, n->status, n->nexthop ? n->nexthop->name : "-",
n->via ? n->via->name : "-");
} }
syslog(LOG_DEBUG, _("End of nodes.")); syslog(LOG_DEBUG, _("End of nodes."));
cp();
} }

View file

@ -17,14 +17,14 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: node.h,v 1.1.2.19 2002/09/04 13:48:52 guus Exp $ $Id: node.h,v 1.1.2.20 2002/09/09 21:24:41 guus Exp $
*/ */
#ifndef __TINC_NODE_H__ #ifndef __TINC_NODE_H__
#define __TINC_NODE_H__ #define __TINC_NODE_H__
#ifdef HAVE_INTTYPES_H #ifdef HAVE_INTTYPES_H
#include <inttypes.h> #include <inttypes.h>
#endif #endif
#include <avl_tree.h> #include <avl_tree.h>
@ -53,7 +53,7 @@ typedef struct node_t {
const EVP_CIPHER *cipher; /* Cipher type for UDP packets */ const EVP_CIPHER *cipher; /* Cipher type for UDP packets */
char *key; /* Cipher key and iv */ char *key; /* Cipher key and iv */
int keylength; /* Cipher key and iv length*/ int keylength; /* Cipher key and iv length */
const EVP_MD *digest; /* Digest type for MAC */ const EVP_MD *digest; /* Digest type for MAC */
int maclength; /* Length of MAC */ int maclength; /* Length of MAC */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.1.2.9 2002/06/21 10:11:36 guus Exp $ $Id: device.c,v 1.1.2.10 2002/09/09 21:25:26 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -67,16 +67,13 @@ int setup_device(void)
device = DEFAULT_DEVICE; device = DEFAULT_DEVICE;
if(!get_config_string(lookup_config(config_tree, "Interface"), &interface)) if(!get_config_string(lookup_config(config_tree, "Interface"), &interface))
interface = rindex(device, '/')?rindex(device, '/')+1:device; interface = rindex(device, '/') ? rindex(device, '/') + 1 : device;
cp cp if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0)
{
syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno));
return -1; return -1;
} }
cp cp
/* Set default MAC address for ethertap devices */ /* Set default MAC address for ethertap devices */
mymac.type = SUBNET_MAC; mymac.type = SUBNET_MAC;
mymac.net.mac.address.x[0] = 0xfe; mymac.net.mac.address.x[0] = 0xfe;
mymac.net.mac.address.x[1] = 0xfd; mymac.net.mac.address.x[1] = 0xfd;
@ -88,35 +85,31 @@ cp
device_info = _("OpenBSD tun device"); device_info = _("OpenBSD tun device");
syslog(LOG_INFO, _("%s is a %s"), device, device_info); syslog(LOG_INFO, _("%s is a %s"), device, device_info);
cp cp return 0;
return 0;
} }
void close_device(void) void close_device(void)
{ {
cp cp close(device_fd);
close(device_fd); cp}
cp
}
int read_packet(vpn_packet_t *packet) int read_packet(vpn_packet_t * packet)
{ {
int lenin; int lenin;
u_int32_t type; u_int32_t type;
struct iovec vector[2] = {{&type, sizeof(type)}, {packet->data + 14, MTU - 14}}; struct iovec vector[2] = { {&type, sizeof(type)}
cp , {packet->data + 14, MTU - 14}
};
if((lenin = readv(device_fd, vector, 2)) <= 0) cp if((lenin = readv(device_fd, vector, 2)) <= 0) {
{ syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno)); device, strerror(errno));
return -1; return -1;
} }
memcpy(packet->data, mymac.net.mac.address.x, 6); memcpy(packet->data, mymac.net.mac.address.x, 6);
memcpy(packet->data + 6, mymac.net.mac.address.x, 6); memcpy(packet->data + 6, mymac.net.mac.address.x, 6);
switch(ntohl(type)) switch (ntohl(type)) {
{
case AF_INET: case AF_INET:
packet->data[12] = 0x8; packet->data[12] = 0x8;
packet->data[13] = 0x0; packet->data[13] = 0x0;
@ -127,7 +120,10 @@ cp
break; break;
default: default:
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_ERR, _("Unknown address family %d while reading packet from %s %s"), ntohl(type), device_info, device); syslog(LOG_ERR,
_
("Unknown address family %d while reading packet from %s %s"),
ntohl(type), device_info, device);
return -1; return -1;
} }
@ -135,29 +131,26 @@ cp
device_total_in += packet->len; device_total_in += packet->len;
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC) {
{ syslog(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len,
syslog(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); device_info);
} }
return 0; return 0;
cp cp}
}
int write_packet(vpn_packet_t *packet) int write_packet(vpn_packet_t * packet)
{ {
u_int32_t type; u_int32_t type;
struct iovec vector[2]; struct iovec vector[2];
int af; int af;
cp cp if(debug_lvl >= DEBUG_TRAFFIC)
if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"), syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"),
packet->len, device_info); packet->len, device_info);
af = (packet->data[12] << 8) + packet->data[13]; af = (packet->data[12] << 8) + packet->data[13];
switch(af) switch (af) {
{
case 0x800: case 0x800:
type = htonl(AF_INET); type = htonl(AF_INET);
break; break;
@ -166,7 +159,9 @@ cp
break; break;
default: default:
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_ERR, _("Unknown address family %d while writing packet to %s %s"), af, device_info, device); syslog(LOG_ERR,
_("Unknown address family %d while writing packet to %s %s"),
af, device_info, device);
return -1; return -1;
} }
@ -175,21 +170,18 @@ cp
vector[1].iov_base = packet->data + 14; vector[1].iov_base = packet->data + 14;
vector[1].iov_len = packet->len - 14; vector[1].iov_len = packet->len - 14;
if(writev(device_fd, vector, 2) < 0) if(writev(device_fd, vector, 2) < 0) {
{ syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device,
syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); strerror(errno));
return -1; return -1;
} }
device_total_out += packet->len; device_total_out += packet->len;
cp cp}
}
void dump_device_stats(void) void dump_device_stats(void)
{ {
cp cp syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in);
syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out);
cp cp}
}

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: process.c,v 1.1.2.45 2002/09/09 19:39:59 guus Exp $ $Id: process.c,v 1.1.2.46 2002/09/09 21:24:41 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -92,6 +92,7 @@ int fcloseall(void)
void cleanup_and_exit(int c) void cleanup_and_exit(int c)
{ {
cp(); cp();
close_network_connections(); close_network_connections();
if(debug_lvl > DEBUG_NOTHING) if(debug_lvl > DEBUG_NOTHING)
@ -109,11 +110,12 @@ void cleanup_and_exit(int c)
int write_pidfile(void) int write_pidfile(void)
{ {
int pid; int pid;
cp(); cp();
pid = check_pid(pidfilename); pid = check_pid(pidfilename);
if(pid) if(pid) {
{
if(netname) if(netname)
fprintf(stderr, _("A tincd is already running for net `%s' with pid %d.\n"), fprintf(stderr, _("A tincd is already running for net `%s' with pid %d.\n"),
netname, pid); netname, pid);
@ -125,7 +127,7 @@ int write_pidfile(void)
/* if it's locked, write-protected, or whatever */ /* if it's locked, write-protected, or whatever */
if(!write_pid(pidfilename)) if(!write_pid(pidfilename))
return 1; return 1;
cp();
return 0; return 0;
} }
@ -135,31 +137,34 @@ int write_pidfile(void)
int kill_other(int signal) int kill_other(int signal)
{ {
int pid; int pid;
cp(); cp();
pid = read_pid(pidfilename); pid = read_pid(pidfilename);
if(!pid) if(!pid) {
{
if(netname) if(netname)
fprintf(stderr, _("No other tincd is running for net `%s'.\n"), netname); fprintf(stderr, _("No other tincd is running for net `%s'.\n"),
netname);
else else
fprintf(stderr, _("No other tincd is running.\n")); fprintf(stderr, _("No other tincd is running.\n"));
return 1; return 1;
} }
errno = 0; /* No error, sometimes errno is only changed on error */ errno = 0; /* No error, sometimes errno is only changed on error */
/* ESRCH is returned when no process with that pid is found */ /* ESRCH is returned when no process with that pid is found */
if(kill(pid, signal) && errno == ESRCH) if(kill(pid, signal) && errno == ESRCH) {
{
if(netname) if(netname)
fprintf(stderr, _("The tincd for net `%s' is no longer running. "), netname); fprintf(stderr, _("The tincd for net `%s' is no longer running. "),
netname);
else else
fprintf(stderr, _("The tincd is no longer running. ")); fprintf(stderr, _("The tincd is no longer running. "));
fprintf(stderr, _("Removing stale lock file.\n")); fprintf(stderr, _("Removing stale lock file.\n"));
remove_pid(pidfilename); remove_pid(pidfilename);
} }
cp();
return 0; return 0;
} }
@ -169,6 +174,7 @@ int kill_other(int signal)
int detach(void) int detach(void)
{ {
cp(); cp();
setup_signals(); setup_signals();
/* First check if we can open a fresh new pidfile */ /* First check if we can open a fresh new pidfile */
@ -180,11 +186,10 @@ int detach(void)
closelog(); closelog();
if(do_detach) if(do_detach) {
{ if(daemon(0, 0) < 0) {
if(daemon(0, 0) < 0) fprintf(stderr, _("Couldn't detach from terminal: %s"),
{ strerror(errno));
fprintf(stderr, _("Couldn't detach from terminal: %s"), strerror(errno));
return -1; return -1;
} }
@ -203,7 +208,7 @@ int detach(void)
syslog(LOG_NOTICE, _("tincd %s starting"), VERSION); syslog(LOG_NOTICE, _("tincd %s starting"), VERSION);
xalloc_fail_func = memory_full; xalloc_fail_func = memory_full;
cp();
return 0; return 0;
} }
@ -211,11 +216,14 @@ int detach(void)
Execute the program name, with sane environment. All output will be Execute the program name, with sane environment. All output will be
redirected to syslog. redirected to syslog.
*/ */
void _execute_script(const char *scriptname, char **envp) __attribute__ ((noreturn)); void _execute_script(const char *scriptname, char **envp)
__attribute__ ((noreturn));
void _execute_script(const char *scriptname, char **envp) void _execute_script(const char *scriptname, char **envp)
{ {
char *s; char *s;
cp(); cp();
while(*envp) while(*envp)
putenv(*envp++); putenv(*envp++);
@ -229,7 +237,8 @@ void _execute_script(const char *scriptname, char **envp)
/* No return on success */ /* No return on success */
openlog("tinc", LOG_CONS | LOG_PID, LOG_DAEMON); openlog("tinc", LOG_CONS | LOG_PID, LOG_DAEMON);
syslog(LOG_ERR, _("Could not execute `%s': %s"), scriptname, strerror(errno)); syslog(LOG_ERR, _("Could not execute `%s': %s"), scriptname,
strerror(errno));
exit(errno); exit(errno);
} }
@ -242,7 +251,9 @@ int execute_script(const char *name, char **envp)
int status; int status;
struct stat s; struct stat s;
char *scriptname; char *scriptname;
cp(); cp();
asprintf(&scriptname, "%s/%s", confbase, name); asprintf(&scriptname, "%s/%s", confbase, name);
/* First check if there is a script */ /* First check if there is a script */
@ -252,50 +263,43 @@ int execute_script(const char *name, char **envp)
pid = fork(); pid = fork();
if(pid < 0) if(pid < 0) {
{ syslog(LOG_ERR, _("System call `%s' failed: %s"), "fork",
syslog(LOG_ERR, _("System call `%s' failed: %s"), "fork", strerror(errno)); strerror(errno));
return -1; return -1;
} }
if(pid) if(pid) {
{
if(debug_lvl >= DEBUG_STATUS) if(debug_lvl >= DEBUG_STATUS)
syslog(LOG_INFO, _("Executing script %s"), name); syslog(LOG_INFO, _("Executing script %s"), name);
free(scriptname); free(scriptname);
if(waitpid(pid, &status, 0) == pid) if(waitpid(pid, &status, 0) == pid) {
{ if(WIFEXITED(status)) { /* Child exited by itself */
if(WIFEXITED(status)) /* Child exited by itself */ if(WEXITSTATUS(status)) {
{ syslog(LOG_ERR, _("Process %d (%s) exited with non-zero status %d"),
if(WEXITSTATUS(status)) pid, name, WEXITSTATUS(status));
{
syslog(LOG_ERR, _("Process %d (%s) exited with non-zero status %d"), pid, name, WEXITSTATUS(status));
return -1; return -1;
} } else
else
return 0; return 0;
} } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */
else if(WIFSIGNALED(status)) /* Child was killed by a signal */ syslog(LOG_ERR, _("Process %d (%s) was killed by signal %d (%s)"), pid,
{ name, WTERMSIG(status), strsignal(WTERMSIG(status)));
syslog(LOG_ERR, _("Process %d (%s) was killed by signal %d (%s)"), return -1;
pid, name, WTERMSIG(status), strsignal(WTERMSIG(status))); } else { /* Something strange happened */
syslog(LOG_ERR, _("Process %d (%s) terminated abnormally"), pid,
name);
return -1; return -1;
} }
else /* Something strange happened */ } else {
{ syslog(LOG_ERR, _("System call `%s' failed: %s"), "waitpid",
syslog(LOG_ERR, _("Process %d (%s) terminated abnormally"), pid, name); strerror(errno));
return -1; return -1;
} }
} }
else
{
syslog(LOG_ERR, _("System call `%s' failed: %s"), "waitpid", strerror(errno));
return -1;
}
}
cp();
/* Child here */ /* Child here */
_execute_script(scriptname, envp); _execute_script(scriptname, envp);
@ -306,8 +310,7 @@ int execute_script(const char *name, char **envp)
Signal handlers. Signal handlers.
*/ */
RETSIGTYPE RETSIGTYPE sigterm_handler(int a)
sigterm_handler(int a)
{ {
if(debug_lvl > DEBUG_NOTHING) if(debug_lvl > DEBUG_NOTHING)
syslog(LOG_NOTICE, _("Got TERM signal")); syslog(LOG_NOTICE, _("Got TERM signal"));
@ -315,31 +318,28 @@ sigterm_handler(int a)
cleanup_and_exit(0); cleanup_and_exit(0);
} }
RETSIGTYPE RETSIGTYPE sigquit_handler(int a)
sigquit_handler(int a)
{ {
if(debug_lvl > DEBUG_NOTHING) if(debug_lvl > DEBUG_NOTHING)
syslog(LOG_NOTICE, _("Got QUIT signal")); syslog(LOG_NOTICE, _("Got QUIT signal"));
cleanup_and_exit(0); cleanup_and_exit(0);
} }
RETSIGTYPE RETSIGTYPE fatal_signal_square(int a)
fatal_signal_square(int a)
{ {
syslog(LOG_ERR, _("Got another fatal signal %d (%s): not restarting."), a, strsignal(a)); syslog(LOG_ERR, _("Got another fatal signal %d (%s): not restarting."), a,
strsignal(a));
cp_trace(); cp_trace();
exit(1); exit(1);
} }
RETSIGTYPE RETSIGTYPE fatal_signal_handler(int a)
fatal_signal_handler(int a)
{ {
struct sigaction act; struct sigaction act;
syslog(LOG_ERR, _("Got fatal signal %d (%s)"), a, strsignal(a)); syslog(LOG_ERR, _("Got fatal signal %d (%s)"), a, strsignal(a));
cp_trace(); cp_trace();
if(do_detach) if(do_detach) {
{
syslog(LOG_NOTICE, _("Trying to re-execute in 5 seconds...")); syslog(LOG_NOTICE, _("Trying to re-execute in 5 seconds..."));
act.sa_handler = fatal_signal_square; act.sa_handler = fatal_signal_square;
@ -351,57 +351,49 @@ fatal_signal_handler(int a)
sleep(5); sleep(5);
remove_pid(pidfilename); remove_pid(pidfilename);
execvp(g_argv[0], g_argv); execvp(g_argv[0], g_argv);
} } else {
else
{
syslog(LOG_NOTICE, _("Not restarting.")); syslog(LOG_NOTICE, _("Not restarting."));
exit(1); exit(1);
} }
} }
RETSIGTYPE RETSIGTYPE sighup_handler(int a)
sighup_handler(int a)
{ {
if(debug_lvl > DEBUG_NOTHING) if(debug_lvl > DEBUG_NOTHING)
syslog(LOG_NOTICE, _("Got HUP signal")); syslog(LOG_NOTICE, _("Got HUP signal"));
sighup = 1; sighup = 1;
} }
RETSIGTYPE RETSIGTYPE sigint_handler(int a)
sigint_handler(int a)
{ {
if(saved_debug_lvl) if(saved_debug_lvl) {
{
syslog(LOG_NOTICE, _("Reverting to old debug level (%d)"), syslog(LOG_NOTICE, _("Reverting to old debug level (%d)"),
saved_debug_lvl); saved_debug_lvl);
debug_lvl = saved_debug_lvl; debug_lvl = saved_debug_lvl;
saved_debug_lvl = 0; saved_debug_lvl = 0;
} } else {
else syslog(LOG_NOTICE,
{ _
syslog(LOG_NOTICE, _("Temporarily setting debug level to 5. Kill me with SIGINT again to go back to level %d."), ("Temporarily setting debug level to 5. Kill me with SIGINT again to go back to level %d."),
debug_lvl); debug_lvl);
saved_debug_lvl = debug_lvl; saved_debug_lvl = debug_lvl;
debug_lvl = 5; debug_lvl = 5;
} }
} }
RETSIGTYPE RETSIGTYPE sigalrm_handler(int a)
sigalrm_handler(int a)
{ {
if(debug_lvl > DEBUG_NOTHING) if(debug_lvl > DEBUG_NOTHING)
syslog(LOG_NOTICE, _("Got ALRM signal")); syslog(LOG_NOTICE, _("Got ALRM signal"));
sigalrm = 1; sigalrm = 1;
} }
RETSIGTYPE RETSIGTYPE sigusr1_handler(int a)
sigusr1_handler(int a)
{ {
dump_connections(); dump_connections();
} }
RETSIGTYPE RETSIGTYPE sigusr2_handler(int a)
sigusr2_handler(int a)
{ {
dump_device_stats(); dump_device_stats();
dump_nodes(); dump_nodes();
@ -409,25 +401,21 @@ sigusr2_handler(int a)
dump_subnets(); dump_subnets();
} }
RETSIGTYPE RETSIGTYPE sigwinch_handler(int a)
sigwinch_handler(int a)
{ {
extern int do_purge; extern int do_purge;
do_purge = 1; do_purge = 1;
} }
RETSIGTYPE RETSIGTYPE unexpected_signal_handler(int a)
unexpected_signal_handler(int a)
{ {
syslog(LOG_WARNING, _("Got unexpected signal %d (%s)"), a, strsignal(a)); syslog(LOG_WARNING, _("Got unexpected signal %d (%s)"), a, strsignal(a));
cp_trace(); cp_trace();
} }
RETSIGTYPE RETSIGTYPE ignore_signal_handler(int a)
ignore_signal_handler(int a)
{ {
if(debug_lvl >= DEBUG_SCARY_THINGS) if(debug_lvl >= DEBUG_SCARY_THINGS) {
{
syslog(LOG_DEBUG, _("Ignored signal %d (%s)"), a, strsignal(a)); syslog(LOG_DEBUG, _("Ignored signal %d (%s)"), a, strsignal(a));
cp_trace(); cp_trace();
} }
@ -435,26 +423,26 @@ ignore_signal_handler(int a)
struct { struct {
int signal; int signal;
void (*handler)(int); void (*handler) (int);
} sighandlers[] = { } sighandlers[] = {
{ SIGHUP, sighup_handler }, {
{ SIGTERM, sigterm_handler }, SIGHUP, sighup_handler}, {
{ SIGQUIT, sigquit_handler }, SIGTERM, sigterm_handler}, {
{ SIGSEGV, fatal_signal_handler }, SIGQUIT, sigquit_handler}, {
{ SIGBUS, fatal_signal_handler }, SIGSEGV, fatal_signal_handler}, {
{ SIGILL, fatal_signal_handler }, SIGBUS, fatal_signal_handler}, {
{ SIGPIPE, ignore_signal_handler }, SIGILL, fatal_signal_handler}, {
{ SIGINT, sigint_handler }, SIGPIPE, ignore_signal_handler}, {
{ SIGUSR1, sigusr1_handler }, SIGINT, sigint_handler}, {
{ SIGUSR2, sigusr2_handler }, SIGUSR1, sigusr1_handler}, {
{ SIGCHLD, ignore_signal_handler }, SIGUSR2, sigusr2_handler}, {
{ SIGALRM, sigalrm_handler }, SIGCHLD, ignore_signal_handler}, {
{ SIGWINCH, sigwinch_handler }, SIGALRM, sigalrm_handler}, {
{ 0, NULL } SIGWINCH, sigwinch_handler}, {
0, NULL}
}; };
void void setup_signals(void)
setup_signals(void)
{ {
int i; int i;
struct sigaction act; struct sigaction act;
@ -466,8 +454,7 @@ setup_signals(void)
/* Set a default signal handler for every signal, errors will be /* Set a default signal handler for every signal, errors will be
ignored. */ ignored. */
for(i = 0; i < NSIG; i++) for(i = 0; i < NSIG; i++) {
{
if(!do_detach) if(!do_detach)
act.sa_handler = SIG_DFL; act.sa_handler = SIG_DFL;
else else
@ -481,11 +468,13 @@ setup_signals(void)
/* Then, for each known signal that we want to catch, assign a /* Then, for each known signal that we want to catch, assign a
handler to the signal, with error checking this time. */ handler to the signal, with error checking this time. */
for(i = 0; sighandlers[i].signal; i++) for(i = 0; sighandlers[i].signal; i++) {
{
act.sa_handler = sighandlers[i].handler; act.sa_handler = sighandlers[i].handler;
if(sigaction(sighandlers[i].signal, &act, NULL) < 0) if(sigaction(sighandlers[i].signal, &act, NULL) < 0)
fprintf(stderr, _("Installing signal handler for signal %d (%s) failed: %s\n"), fprintf(stderr,
sighandlers[i].signal, strsignal(sighandlers[i].signal), strerror(errno)); _
("Installing signal handler for signal %d (%s) failed: %s\n"),
sighandlers[i].signal, strsignal(sighandlers[i].signal),
strerror(errno));
} }
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: process.h,v 1.1.2.12 2002/07/10 11:27:06 guus Exp $ $Id: process.h,v 1.1.2.13 2002/09/09 21:24:41 guus Exp $
*/ */
#ifndef __TINC_PROCESS_H__ #ifndef __TINC_PROCESS_H__

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol.c,v 1.28.4.135 2002/09/09 19:39:59 guus Exp $ $Id: protocol.c,v 1.28.4.136 2002/09/09 21:24:41 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -47,7 +47,7 @@ int check_id(char *id)
{ {
int i; int i;
for (i = 0; i < strlen(id); i++) for(i = 0; i < strlen(id); i++)
if(!isalnum(id[i]) && id[i] != '_') if(!isalnum(id[i]) && id[i] != '_')
return -1; return -1;
@ -57,13 +57,14 @@ int check_id(char *id)
/* Generic request routines - takes care of logging and error /* Generic request routines - takes care of logging and error
detection as well */ detection as well */
int send_request(connection_t *c, const char *format, ...) int send_request(connection_t * c, const char *format, ...)
{ {
va_list args; va_list args;
char buffer[MAXBUFSIZE]; char buffer[MAXBUFSIZE];
int len, request; int len, request;
cp(); cp();
/* Use vsnprintf instead of vasprintf: faster, no memory /* Use vsnprintf instead of vasprintf: faster, no memory
fragmentation, cleanup is automatic, and there is a limit on the fragmentation, cleanup is automatic, and there is a limit on the
input buffer anyway */ input buffer anyway */
@ -72,55 +73,61 @@ int send_request(connection_t *c, const char *format, ...)
len = vsnprintf(buffer, MAXBUFSIZE, format, args); len = vsnprintf(buffer, MAXBUFSIZE, format, args);
va_end(args); va_end(args);
if(len < 0 || len > MAXBUFSIZE-1) if(len < 0 || len > MAXBUFSIZE - 1) {
{ syslog(LOG_ERR, _("Output buffer overflow while sending request to %s (%s)"),
syslog(LOG_ERR, _("Output buffer overflow while sending request to %s (%s)"), c->name, c->hostname); c->name, c->hostname);
return -1; return -1;
} }
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL) {
{
sscanf(buffer, "%d", &request); sscanf(buffer, "%d", &request);
if(debug_lvl >= DEBUG_META) if(debug_lvl >= DEBUG_META)
syslog(LOG_DEBUG, _("Sending %s to %s (%s): %s"), request_name[request], c->name, c->hostname, buffer); syslog(LOG_DEBUG, _("Sending %s to %s (%s): %s"),
request_name[request], c->name, c->hostname, buffer);
else else
syslog(LOG_DEBUG, _("Sending %s to %s (%s)"), request_name[request], c->name, c->hostname); syslog(LOG_DEBUG, _("Sending %s to %s (%s)"), request_name[request],
c->name, c->hostname);
} }
buffer[len++] = '\n'; buffer[len++] = '\n';
cp();
if(c == broadcast) if(c == broadcast)
return broadcast_meta(NULL, buffer, len); return broadcast_meta(NULL, buffer, len);
else else
return send_meta(c, buffer, len); return send_meta(c, buffer, len);
} }
int forward_request(connection_t *from) int forward_request(connection_t * from)
{ {
int request; int request;
cp(); cp();
if(debug_lvl >= DEBUG_PROTOCOL)
{ cp();
if(debug_lvl >= DEBUG_PROTOCOL) {
sscanf(from->buffer, "%d", &request); sscanf(from->buffer, "%d", &request);
if(debug_lvl >= DEBUG_META) if(debug_lvl >= DEBUG_META)
syslog(LOG_DEBUG, _("Forwarding %s from %s (%s): %s"), request_name[request], from->name, from->hostname, from->buffer); syslog(LOG_DEBUG, _("Forwarding %s from %s (%s): %s"),
request_name[request], from->name, from->hostname,
from->buffer);
else else
syslog(LOG_DEBUG, _("Forwarding %s from %s (%s)"), request_name[request], from->name, from->hostname); syslog(LOG_DEBUG, _("Forwarding %s from %s (%s)"),
request_name[request], from->name, from->hostname);
} }
from->buffer[from->reqlen - 1] = '\n'; from->buffer[from->reqlen - 1] = '\n';
cp();
return broadcast_meta(from, from->buffer, from->reqlen); return broadcast_meta(from, from->buffer, from->reqlen);
} }
int receive_request(connection_t *c) int receive_request(connection_t * c)
{ {
int request; int request;
cp(); cp();
if(sscanf(c->buffer, "%d", &request) == 1)
{ if(sscanf(c->buffer, "%d", &request) == 1) {
if((request < 0) || (request >= LAST) || !request_handlers[request]) if((request < 0) || (request >= LAST) || !request_handlers[request]) {
{
if(debug_lvl >= DEBUG_META) if(debug_lvl >= DEBUG_META)
syslog(LOG_DEBUG, _("Unknown request from %s (%s): %s"), syslog(LOG_DEBUG, _("Unknown request from %s (%s): %s"),
c->name, c->hostname, c->buffer); c->name, c->hostname, c->buffer);
@ -129,94 +136,88 @@ int receive_request(connection_t *c)
c->name, c->hostname); c->name, c->hostname);
return -1; return -1;
} } else {
else if(debug_lvl >= DEBUG_PROTOCOL) {
{
if(debug_lvl >= DEBUG_PROTOCOL)
{
if(debug_lvl >= DEBUG_META) if(debug_lvl >= DEBUG_META)
syslog(LOG_DEBUG, _("Got %s from %s (%s): %s"), syslog(LOG_DEBUG, _("Got %s from %s (%s): %s"),
request_name[request], c->name, c->hostname, c->buffer); request_name[request], c->name, c->hostname,
c->buffer);
else else
syslog(LOG_DEBUG, _("Got %s from %s (%s)"), syslog(LOG_DEBUG, _("Got %s from %s (%s)"),
request_name[request], c->name, c->hostname); request_name[request], c->name, c->hostname);
} }
} }
if((c->allow_request != ALL) && (c->allow_request != request)) if((c->allow_request != ALL) && (c->allow_request != request)) {
{ syslog(LOG_ERR, _("Unauthorized request from %s (%s)"), c->name,
syslog(LOG_ERR, _("Unauthorized request from %s (%s)"), c->name, c->hostname); c->hostname);
return -1; return -1;
} }
if(request_handlers[request](c)) if(request_handlers[request] (c))
/* Something went wrong. Probably scriptkiddies. Terminate. */ /* Something went wrong. Probably scriptkiddies. Terminate. */
{ {
syslog(LOG_ERR, _("Error while processing %s from %s (%s)"), syslog(LOG_ERR, _("Error while processing %s from %s (%s)"),
request_name[request], c->name, c->hostname); request_name[request], c->name, c->hostname);
return -1; return -1;
} }
} } else {
else
{
syslog(LOG_ERR, _("Bogus data received from %s (%s)"), syslog(LOG_ERR, _("Bogus data received from %s (%s)"),
c->name, c->hostname); c->name, c->hostname);
return -1; return -1;
} }
cp();
return 0; return 0;
} }
int past_request_compare(past_request_t *a, past_request_t *b) int past_request_compare(past_request_t * a, past_request_t * b)
{ {
cp();
return strcmp(a->request, b->request); return strcmp(a->request, b->request);
} }
void free_past_request(past_request_t *r) void free_past_request(past_request_t * r)
{ {
cp(); cp();
if(r->request) if(r->request)
free(r->request); free(r->request);
free(r); free(r);
cp();
} }
void init_requests(void) void init_requests(void)
{ {
cp(); cp();
past_request_tree = avl_alloc_tree((avl_compare_t)past_request_compare, (avl_action_t)free_past_request);
cp(); past_request_tree = avl_alloc_tree((avl_compare_t) past_request_compare, (avl_action_t) free_past_request);
} }
void exit_requests(void) void exit_requests(void)
{ {
cp(); cp();
avl_delete_tree(past_request_tree); avl_delete_tree(past_request_tree);
cp();
} }
int seen_request(char *request) int seen_request(char *request)
{ {
past_request_t p, *new; past_request_t p, *new;
cp(); cp();
p.request = request; p.request = request;
if(avl_search(past_request_tree, &p)) if(avl_search(past_request_tree, &p)) {
{
if(debug_lvl >= DEBUG_SCARY_THINGS) if(debug_lvl >= DEBUG_SCARY_THINGS)
syslog(LOG_DEBUG, _("Already seen request")); syslog(LOG_DEBUG, _("Already seen request"));
return 1; return 1;
} } else {
else new = (past_request_t *) xmalloc(sizeof(*new));
{
new = (past_request_t *)xmalloc(sizeof(*new));
new->request = xstrdup(request); new->request = xstrdup(request);
new->firstseen = now; new->firstseen = now;
avl_insert(past_request_tree, new); avl_insert(past_request_tree, new);
return 0; return 0;
} }
cp();
} }
void age_past_requests(void) void age_past_requests(void)
@ -224,11 +225,13 @@ void age_past_requests(void)
avl_node_t *node, *next; avl_node_t *node, *next;
past_request_t *p; past_request_t *p;
int left = 0, deleted = 0; int left = 0, deleted = 0;
cp(); cp();
for(node = past_request_tree->head; node; node = next)
{ for(node = past_request_tree->head; node; node = next) {
next = node->next; next = node->next;
p = (past_request_t *)node->data; p = (past_request_t *) node->data;
if(p->firstseen + pingtimeout < now) if(p->firstseen + pingtimeout < now)
avl_delete_node(past_request_tree, node), deleted++; avl_delete_node(past_request_tree, node), deleted++;
else else
@ -236,20 +239,19 @@ void age_past_requests(void)
} }
if(debug_lvl >= DEBUG_SCARY_THINGS && left + deleted) if(debug_lvl >= DEBUG_SCARY_THINGS && left + deleted)
syslog(LOG_DEBUG, _("Aging past requests: deleted %d, left %d\n"), deleted, left); syslog(LOG_DEBUG, _("Aging past requests: deleted %d, left %d\n"),
cp(); deleted, left);
} }
/* Jumptable for the request handlers */ /* Jumptable for the request handlers */
int (*request_handlers[])(connection_t*) = { int (*request_handlers[]) (connection_t *) = {
id_h, metakey_h, challenge_h, chal_reply_h, ack_h, id_h, metakey_h, challenge_h, chal_reply_h, ack_h,
status_h, error_h, termreq_h, status_h, error_h, termreq_h,
ping_h, pong_h, ping_h, pong_h,
add_subnet_h, del_subnet_h, add_subnet_h, del_subnet_h,
add_edge_h, del_edge_h, add_edge_h, del_edge_h,
key_changed_h, req_key_h, ans_key_h, key_changed_h, req_key_h, ans_key_h, tcppacket_h,
tcppacket_h,
}; };
/* Request names */ /* Request names */
@ -259,7 +261,5 @@ char (*request_name[]) = {
"STATUS", "ERROR", "TERMREQ", "STATUS", "ERROR", "TERMREQ",
"PING", "PONG", "PING", "PONG",
"ADD_SUBNET", "DEL_SUBNET", "ADD_SUBNET", "DEL_SUBNET",
"ADD_EDGE", "DEL_EDGE", "ADD_EDGE", "DEL_EDGE", "KEY_CHANGED", "REQ_KEY", "ANS_KEY", "PACKET",
"KEY_CHANGED", "REQ_KEY", "ANS_KEY",
"PACKET",
}; };

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol.h,v 1.5.4.34 2002/09/04 16:26:45 guus Exp $ $Id: protocol.h,v 1.5.4.35 2002/09/09 21:24:42 guus Exp $
*/ */
#ifndef __TINC_PROTOCOL_H__ #ifndef __TINC_PROTOCOL_H__
@ -41,7 +41,6 @@ enum {
ID = 0, METAKEY, CHALLENGE, CHAL_REPLY, ACK, ID = 0, METAKEY, CHALLENGE, CHAL_REPLY, ACK,
STATUS, ERROR, TERMREQ, STATUS, ERROR, TERMREQ,
PING, PONG, PING, PONG,
// ADD_NODE, DEL_NODE,
ADD_SUBNET, DEL_SUBNET, ADD_SUBNET, DEL_SUBNET,
ADD_EDGE, DEL_EDGE, ADD_EDGE, DEL_EDGE,
KEY_CHANGED, REQ_KEY, ANS_KEY, KEY_CHANGED, REQ_KEY, ANS_KEY,
@ -61,7 +60,7 @@ typedef struct past_request_t {
/* Basic functions */ /* Basic functions */
extern int send_request(connection_t*, const char*, ...); extern int send_request(connection_t *, const char *, ...);
extern int forward_request(connection_t *); extern int forward_request(connection_t *);
extern int receive_request(connection_t *); extern int receive_request(connection_t *);
extern int check_id(char *); extern int check_id(char *);
@ -83,8 +82,6 @@ extern int send_error(connection_t *, int, char *);
extern int send_termreq(connection_t *); extern int send_termreq(connection_t *);
extern int send_ping(connection_t *); extern int send_ping(connection_t *);
extern int send_pong(connection_t *); extern int send_pong(connection_t *);
// extern int send_add_node(connection_t *, node_t *);
// extern int send_del_node(connection_t *, node_t *);
extern int send_add_subnet(connection_t *, subnet_t *); extern int send_add_subnet(connection_t *, subnet_t *);
extern int send_del_subnet(connection_t *, subnet_t *); extern int send_del_subnet(connection_t *, subnet_t *);
extern int send_add_edge(connection_t *, edge_t *); extern int send_add_edge(connection_t *, edge_t *);
@ -96,7 +93,7 @@ extern int send_tcppacket(connection_t *, vpn_packet_t *);
/* Request handlers */ /* Request handlers */
extern int (*request_handlers[])(connection_t *); extern int (*request_handlers[]) (connection_t *);
extern int id_h(connection_t *); extern int id_h(connection_t *);
extern int metakey_h(connection_t *); extern int metakey_h(connection_t *);
@ -108,8 +105,6 @@ extern int error_h(connection_t *);
extern int termreq_h(connection_t *); extern int termreq_h(connection_t *);
extern int ping_h(connection_t *); extern int ping_h(connection_t *);
extern int pong_h(connection_t *); extern int pong_h(connection_t *);
// extern int add_node_h(connection_t *);
// extern int del_node_h(connection_t *);
extern int add_subnet_h(connection_t *); extern int add_subnet_h(connection_t *);
extern int del_subnet_h(connection_t *); extern int del_subnet_h(connection_t *);
extern int add_edge_h(connection_t *); extern int add_edge_h(connection_t *);

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_auth.c,v 1.1.4.15 2002/09/09 19:39:59 guus Exp $ $Id: protocol_auth.c,v 1.1.4.16 2002/09/09 21:24:45 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -53,76 +53,74 @@
#include "system.h" #include "system.h"
int send_id(connection_t *c) int send_id(connection_t * c)
{ {
cp(); cp();
return send_request(c, "%d %s %d", ID, myself->connection->name, myself->connection->protocol_version);
return send_request(c, "%d %s %d", ID, myself->connection->name,
myself->connection->protocol_version);
} }
int id_h(connection_t *c) int id_h(connection_t * c)
{ {
char name[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE];
int bla; int bla;
cp(); cp();
if(sscanf(c->buffer, "%*d "MAX_STRING" %d", name, &c->protocol_version) != 2)
{ if(sscanf(c->buffer, "%*d " MAX_STRING " %d", name, &c->protocol_version) != 2) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ID", c->name, c->hostname); syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ID", c->name,
c->hostname);
return -1; return -1;
} }
/* Check if identity is a valid name */ /* Check if identity is a valid name */
if(check_id(name)) if(check_id(name)) {
{ syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ID", c->name,
syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ID", c->name, c->hostname, "invalid name"); c->hostname, "invalid name");
return -1; return -1;
} }
/* If we set c->name in advance, make sure we are connected to the right host */ /* If we set c->name in advance, make sure we are connected to the right host */
if(c->name) if(c->name) {
{ if(strcmp(c->name, name)) {
if(strcmp(c->name, name)) syslog(LOG_ERR, _("Peer %s is %s instead of %s"), c->hostname, name,
{ c->name);
syslog(LOG_ERR, _("Peer %s is %s instead of %s"), c->hostname, name, c->name);
return -1; return -1;
} }
} } else
else
c->name = xstrdup(name); c->name = xstrdup(name);
/* Check if version matches */ /* Check if version matches */
if(c->protocol_version != myself->connection->protocol_version) if(c->protocol_version != myself->connection->protocol_version) {
{
syslog(LOG_ERR, _("Peer %s (%s) uses incompatible version %d"), syslog(LOG_ERR, _("Peer %s (%s) uses incompatible version %d"),
c->name, c->hostname, c->protocol_version); c->name, c->hostname, c->protocol_version);
return -1; return -1;
} }
if(bypass_security) if(bypass_security) {
{
if(!c->config_tree) if(!c->config_tree)
init_configuration(&c->config_tree); init_configuration(&c->config_tree);
c->allow_request = ACK; c->allow_request = ACK;
return send_ack(c); return send_ack(c);
} }
if(!c->config_tree) if(!c->config_tree) {
{
init_configuration(&c->config_tree); init_configuration(&c->config_tree);
bla = read_connection_config(c); bla = read_connection_config(c);
if(bla) if(bla) {
{ syslog(LOG_ERR, _("Peer %s had unknown identity (%s)"), c->hostname,
syslog(LOG_ERR, _("Peer %s had unknown identity (%s)"), c->hostname, c->name); c->name);
return -1; return -1;
} }
} }
if(read_rsa_public_key(c)) if(read_rsa_public_key(c)) {
{
return -1; return -1;
} }
@ -135,15 +133,17 @@ int id_h(connection_t *c)
c->options |= OPTION_TCPONLY | OPTION_INDIRECT; c->options |= OPTION_TCPONLY | OPTION_INDIRECT;
c->allow_request = METAKEY; c->allow_request = METAKEY;
cp();
return send_metakey(c); return send_metakey(c);
} }
int send_metakey(connection_t *c) int send_metakey(connection_t * c)
{ {
char buffer[MAX_STRING_SIZE]; char buffer[MAX_STRING_SIZE];
int len, x; int len, x;
cp(); cp();
len = RSA_size(c->rsa_key); len = RSA_size(c->rsa_key);
/* Allocate buffers for the meta key */ /* Allocate buffers for the meta key */
@ -170,11 +170,11 @@ int send_metakey(connection_t *c)
c->outkey[0] &= 0x7F; c->outkey[0] &= 0x7F;
if(debug_lvl >= DEBUG_SCARY_THINGS) if(debug_lvl >= DEBUG_SCARY_THINGS) {
{
bin2hex(c->outkey, buffer, len); bin2hex(c->outkey, buffer, len);
buffer[len*2] = '\0'; buffer[len * 2] = '\0';
syslog(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"), buffer); syslog(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"),
buffer);
} }
/* Encrypt the random data /* Encrypt the random data
@ -184,61 +184,66 @@ int send_metakey(connection_t *c)
with a length equal to that of the modulus of the RSA key. with a length equal to that of the modulus of the RSA key.
*/ */
if(RSA_public_encrypt(len, c->outkey, buffer, c->rsa_key, RSA_NO_PADDING) != len) if(RSA_public_encrypt(len, c->outkey, buffer, c->rsa_key, RSA_NO_PADDING) != len) {
{ syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"),
syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), c->name, c->hostname); c->name, c->hostname);
return -1; return -1;
} }
cp();
/* Convert the encrypted random data to a hexadecimal formatted string */ /* Convert the encrypted random data to a hexadecimal formatted string */
bin2hex(buffer, buffer, len); bin2hex(buffer, buffer, len);
buffer[len*2] = '\0'; buffer[len * 2] = '\0';
/* Send the meta key */ /* Send the meta key */
x = send_request(c, "%d %d %d %d %d %s", METAKEY, x = send_request(c, "%d %d %d %d %d %s", METAKEY,
c->outcipher?c->outcipher->nid:0, c->outdigest?c->outdigest->type:0, c->outcipher ? c->outcipher->nid : 0,
c->outmaclength, c->outcompression, buffer); c->outdigest ? c->outdigest->type : 0, c->outmaclength,
c->outcompression, buffer);
/* Further outgoing requests are encrypted with the key we just generated */ /* Further outgoing requests are encrypted with the key we just generated */
if(c->outcipher) if(c->outcipher) {
{
EVP_EncryptInit(c->outctx, c->outcipher, EVP_EncryptInit(c->outctx, c->outcipher,
c->outkey + len - c->outcipher->key_len, c->outkey + len - c->outcipher->key_len,
c->outkey + len - c->outcipher->key_len - c->outcipher->iv_len); c->outkey + len - c->outcipher->key_len -
c->outcipher->iv_len);
c->status.encryptout = 1; c->status.encryptout = 1;
} }
cp();
return x; return x;
} }
int metakey_h(connection_t *c) int metakey_h(connection_t * c)
{ {
char buffer[MAX_STRING_SIZE]; char buffer[MAX_STRING_SIZE];
int cipher, digest, maclength, compression; int cipher, digest, maclength, compression;
int len; int len;
cp(); cp();
if(sscanf(c->buffer, "%*d %d %d %d %d "MAX_STRING, &cipher, &digest, &maclength, &compression, buffer) != 5)
{ if(sscanf
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "METAKEY", c->name, c->hostname); (c->buffer, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength,
&compression, buffer) != 5) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "METAKEY", c->name,
c->hostname);
return -1; return -1;
} }
cp();
len = RSA_size(myself->connection->rsa_key); len = RSA_size(myself->connection->rsa_key);
/* Check if the length of the meta key is all right */ /* Check if the length of the meta key is all right */
if(strlen(buffer) != len*2) if(strlen(buffer) != len * 2) {
{ syslog(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name,
syslog(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name, c->hostname, "wrong keylength"); c->hostname, "wrong keylength");
return -1; return -1;
} }
/* Allocate buffers for the meta key */ /* Allocate buffers for the meta key */
cp();
if(!c->inkey) if(!c->inkey)
c->inkey = xmalloc(len); c->inkey = xmalloc(len);
@ -246,82 +251,81 @@ int metakey_h(connection_t *c)
c->inctx = xmalloc(sizeof(*c->inctx)); c->inctx = xmalloc(sizeof(*c->inctx));
/* Convert the challenge from hexadecimal back to binary */ /* Convert the challenge from hexadecimal back to binary */
cp();
hex2bin(buffer,buffer,len); hex2bin(buffer, buffer, len);
/* Decrypt the meta key */ /* Decrypt the meta key */
cp();
if(RSA_private_decrypt(len, buffer, c->inkey, myself->connection->rsa_key, RSA_NO_PADDING) != len) /* See challenge() */ if(RSA_private_decrypt(len, buffer, c->inkey, myself->connection->rsa_key, RSA_NO_PADDING) != len) { /* See challenge() */
{ syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"),
syslog(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), c->name, c->hostname); c->name, c->hostname);
return -1; return -1;
} }
if(debug_lvl >= DEBUG_SCARY_THINGS) if(debug_lvl >= DEBUG_SCARY_THINGS) {
{
bin2hex(c->inkey, buffer, len); bin2hex(c->inkey, buffer, len);
buffer[len*2] = '\0'; buffer[len * 2] = '\0';
syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer); syslog(LOG_DEBUG, _("Received random meta key (unencrypted): %s"),
buffer);
} }
/* All incoming requests will now be encrypted. */ /* All incoming requests will now be encrypted. */
cp();
/* Check and lookup cipher and digest algorithms */ /* Check and lookup cipher and digest algorithms */
if(cipher) if(cipher) {
{
c->incipher = EVP_get_cipherbynid(cipher); c->incipher = EVP_get_cipherbynid(cipher);
if(!c->incipher)
{ if(!c->incipher) {
syslog(LOG_ERR, _("%s (%s) uses unknown cipher!"), c->name, c->hostname); syslog(LOG_ERR, _("%s (%s) uses unknown cipher!"), c->name,
c->hostname);
return -1; return -1;
} }
EVP_DecryptInit(c->inctx, c->incipher, EVP_DecryptInit(c->inctx, c->incipher,
c->inkey + len - c->incipher->key_len, c->inkey + len - c->incipher->key_len,
c->inkey + len - c->incipher->key_len - c->incipher->iv_len); c->inkey + len - c->incipher->key_len -
c->incipher->iv_len);
c->status.decryptin = 1; c->status.decryptin = 1;
} } else {
else
{
c->incipher = NULL; c->incipher = NULL;
} }
c->inmaclength = maclength; c->inmaclength = maclength;
if(digest) if(digest) {
{
c->indigest = EVP_get_digestbynid(digest); c->indigest = EVP_get_digestbynid(digest);
if(!c->indigest)
{ if(!c->indigest) {
syslog(LOG_ERR, _("Node %s (%s) uses unknown digest!"), c->name, c->hostname); syslog(LOG_ERR, _("Node %s (%s) uses unknown digest!"), c->name,
c->hostname);
return -1; return -1;
} }
if(c->inmaclength > c->indigest->md_size || c->inmaclength < 0) if(c->inmaclength > c->indigest->md_size || c->inmaclength < 0) {
{ syslog(LOG_ERR, _("%s (%s) uses bogus MAC length!"), c->name,
syslog(LOG_ERR, _("%s (%s) uses bogus MAC length!"), c->name, c->hostname); c->hostname);
return -1; return -1;
} }
} } else {
else
{
c->indigest = NULL; c->indigest = NULL;
} }
c->incompression = compression; c->incompression = compression;
c->allow_request = CHALLENGE; c->allow_request = CHALLENGE;
cp();
return send_challenge(c); return send_challenge(c);
} }
int send_challenge(connection_t *c) int send_challenge(connection_t * c)
{ {
char buffer[MAX_STRING_SIZE]; char buffer[MAX_STRING_SIZE];
int len, x; int len, x;
cp(); cp();
/* CHECKME: what is most reasonable value for len? */ /* CHECKME: what is most reasonable value for len? */
len = RSA_size(c->rsa_key); len = RSA_size(c->rsa_key);
@ -330,33 +334,33 @@ int send_challenge(connection_t *c)
if(!c->hischallenge) if(!c->hischallenge)
c->hischallenge = xmalloc(len); c->hischallenge = xmalloc(len);
cp();
/* Copy random data to the buffer */ /* Copy random data to the buffer */
RAND_bytes(c->hischallenge, len); RAND_bytes(c->hischallenge, len);
cp();
/* Convert to hex */ /* Convert to hex */
bin2hex(c->hischallenge, buffer, len); bin2hex(c->hischallenge, buffer, len);
buffer[len*2] = '\0'; buffer[len * 2] = '\0';
cp();
/* Send the challenge */ /* Send the challenge */
x = send_request(c, "%d %s", CHALLENGE, buffer); x = send_request(c, "%d %s", CHALLENGE, buffer);
cp();
return x; return x;
} }
int challenge_h(connection_t *c) int challenge_h(connection_t * c)
{ {
char buffer[MAX_STRING_SIZE]; char buffer[MAX_STRING_SIZE];
int len; int len;
cp(); cp();
if(sscanf(c->buffer, "%*d "MAX_STRING, buffer) != 1)
{ if(sscanf(c->buffer, "%*d " MAX_STRING, buffer) != 1) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "CHALLENGE", c->name, c->hostname); syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "CHALLENGE", c->name,
c->hostname);
return -1; return -1;
} }
@ -364,9 +368,9 @@ int challenge_h(connection_t *c)
/* Check if the length of the challenge is all right */ /* Check if the length of the challenge is all right */
if(strlen(buffer) != len*2) if(strlen(buffer) != len * 2) {
{ syslog(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name,
syslog(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name, c->hostname, "wrong challenge length"); c->hostname, "wrong challenge length");
return -1; return -1;
} }
@ -377,54 +381,58 @@ int challenge_h(connection_t *c)
/* Convert the challenge from hexadecimal back to binary */ /* Convert the challenge from hexadecimal back to binary */
hex2bin(buffer,c->mychallenge,len); hex2bin(buffer, c->mychallenge, len);
c->allow_request = CHAL_REPLY; c->allow_request = CHAL_REPLY;
/* Rest is done by send_chal_reply() */ /* Rest is done by send_chal_reply() */
cp();
return send_chal_reply(c); return send_chal_reply(c);
} }
int send_chal_reply(connection_t *c) int send_chal_reply(connection_t * c)
{ {
char hash[EVP_MAX_MD_SIZE*2+1]; char hash[EVP_MAX_MD_SIZE * 2 + 1];
EVP_MD_CTX ctx; EVP_MD_CTX ctx;
cp(); cp();
/* Calculate the hash from the challenge we received */ /* Calculate the hash from the challenge we received */
EVP_DigestInit(&ctx, c->indigest); EVP_DigestInit(&ctx, c->indigest);
EVP_DigestUpdate(&ctx, c->mychallenge, RSA_size(myself->connection->rsa_key)); EVP_DigestUpdate(&ctx, c->mychallenge,
RSA_size(myself->connection->rsa_key));
EVP_DigestFinal(&ctx, hash, NULL); EVP_DigestFinal(&ctx, hash, NULL);
/* Convert the hash to a hexadecimal formatted string */ /* Convert the hash to a hexadecimal formatted string */
bin2hex(hash,hash,c->indigest->md_size); bin2hex(hash, hash, c->indigest->md_size);
hash[c->indigest->md_size*2] = '\0'; hash[c->indigest->md_size * 2] = '\0';
/* Send the reply */ /* Send the reply */
cp();
return send_request(c, "%d %s", CHAL_REPLY, hash); return send_request(c, "%d %s", CHAL_REPLY, hash);
} }
int chal_reply_h(connection_t *c) int chal_reply_h(connection_t * c)
{ {
char hishash[MAX_STRING_SIZE]; char hishash[MAX_STRING_SIZE];
char myhash[EVP_MAX_MD_SIZE]; char myhash[EVP_MAX_MD_SIZE];
EVP_MD_CTX ctx; EVP_MD_CTX ctx;
cp(); cp();
if(sscanf(c->buffer, "%*d "MAX_STRING, hishash) != 1)
{ if(sscanf(c->buffer, "%*d " MAX_STRING, hishash) != 1) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "CHAL_REPLY", c->name, c->hostname); syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "CHAL_REPLY", c->name,
c->hostname);
return -1; return -1;
} }
/* Check if the length of the hash is all right */ /* Check if the length of the hash is all right */
if(strlen(hishash) != c->outdigest->md_size*2) if(strlen(hishash) != c->outdigest->md_size * 2) {
{ syslog(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name,
syslog(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name, c->hostname, _("wrong challenge reply length")); c->hostname, _("wrong challenge reply length"));
return -1; return -1;
} }
@ -440,15 +448,16 @@ int chal_reply_h(connection_t *c)
/* Verify the incoming hash with the calculated hash */ /* Verify the incoming hash with the calculated hash */
if(memcmp(hishash, myhash, c->outdigest->md_size)) if(memcmp(hishash, myhash, c->outdigest->md_size)) {
{ syslog(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name,
syslog(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name, c->hostname, _("wrong challenge reply")); c->hostname, _("wrong challenge reply"));
if(debug_lvl >= DEBUG_SCARY_THINGS)
{ if(debug_lvl >= DEBUG_SCARY_THINGS) {
bin2hex(myhash, hishash, SHA_DIGEST_LENGTH); bin2hex(myhash, hishash, SHA_DIGEST_LENGTH);
hishash[SHA_DIGEST_LENGTH*2] = '\0'; hishash[SHA_DIGEST_LENGTH * 2] = '\0';
syslog(LOG_DEBUG, _("Expected challenge reply: %s"), hishash); syslog(LOG_DEBUG, _("Expected challenge reply: %s"), hishash);
} }
return -1; return -1;
} }
@ -457,28 +466,33 @@ int chal_reply_h(connection_t *c)
*/ */
c->allow_request = ACK; c->allow_request = ACK;
cp();
return send_ack(c); return send_ack(c);
} }
int send_ack(connection_t *c) int send_ack(connection_t * c)
{ {
/* ACK message contains rest of the information the other end needs /* ACK message contains rest of the information the other end needs
to create node_t and edge_t structures. */ to create node_t and edge_t structures. */
int x; int x;
struct timeval now; struct timeval now;
cp(); cp();
/* Estimate weight */ /* Estimate weight */
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
c->estimated_weight = (now.tv_sec - c->start.tv_sec) * 1000 + (now.tv_usec - c->start.tv_usec) / 1000; c->estimated_weight =
x = send_request(c, "%d %s %d %lx", ACK, myport, c->estimated_weight, c->options); (now.tv_sec - c->start.tv_sec) * 1000 + (now.tv_usec -
cp(); c->start.tv_usec) / 1000;
x = send_request(c, "%d %s %d %lx", ACK, myport, c->estimated_weight,
c->options);
return x; return x;
} }
void send_everything(connection_t *c) void send_everything(connection_t * c)
{ {
avl_node_t *node, *node2; avl_node_t *node, *node2;
node_t *n; node_t *n;
@ -487,35 +501,35 @@ void send_everything(connection_t *c)
/* Send all known subnets and edges */ /* Send all known subnets and edges */
for(node = node_tree->head; node; node = node->next) for(node = node_tree->head; node; node = node->next) {
{ n = (node_t *) node->data;
n = (node_t *)node->data;
for(node2 = n->subnet_tree->head; node2; node2 = node2->next) for(node2 = n->subnet_tree->head; node2; node2 = node2->next) {
{ s = (subnet_t *) node2->data;
s = (subnet_t *)node2->data;
send_add_subnet(c, s); send_add_subnet(c, s);
} }
for(node2 = n->edge_tree->head; node2; node2 = node2->next) for(node2 = n->edge_tree->head; node2; node2 = node2->next) {
{ e = (edge_t *) node2->data;
e = (edge_t *)node2->data;
send_add_edge(c, e); send_add_edge(c, e);
} }
} }
} }
int ack_h(connection_t *c) int ack_h(connection_t * c)
{ {
char hisport[MAX_STRING_SIZE]; char hisport[MAX_STRING_SIZE];
char *hisaddress, *dummy; char *hisaddress, *dummy;
int weight; int weight;
long int options; long int options;
node_t *n; node_t *n;
cp(); cp();
if(sscanf(c->buffer, "%*d "MAX_STRING" %d %lx", hisport, &weight, &options) != 3)
{ if(sscanf
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ACK", c->name, c->hostname); (c->buffer, "%*d " MAX_STRING " %d %lx", hisport, &weight, &options) != 3) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ACK", c->name,
c->hostname);
return -1; return -1;
} }
@ -523,19 +537,16 @@ int ack_h(connection_t *c)
n = lookup_node(c->name); n = lookup_node(c->name);
if(!n) if(!n) {
{
n = new_node(); n = new_node();
n->name = xstrdup(c->name); n->name = xstrdup(c->name);
node_add(n); node_add(n);
} } else {
else if(n->connection) {
{
if(n->connection)
{
/* Oh dear, we already have a connection to this node. */ /* Oh dear, we already have a connection to this node. */
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_DEBUG, _("Established a second connection with %s (%s), closing old connection"), n->name, n->hostname); syslog(LOG_DEBUG, _("Established a second connection with %s (%s), closing old connection"),
n->name, n->hostname);
terminate_connection(n->connection, 0); terminate_connection(n->connection, 0);
} }
} }
@ -550,7 +561,8 @@ int ack_h(connection_t *c)
c->status.active = 1; c->status.active = 1;
if(debug_lvl >= DEBUG_CONNECTIONS) if(debug_lvl >= DEBUG_CONNECTIONS)
syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), c->name, c->hostname); syslog(LOG_NOTICE, _("Connection with %s (%s) activated"), c->name,
c->hostname);
/* Send him everything we know */ /* Send him everything we know */
@ -569,10 +581,9 @@ int ack_h(connection_t *c)
c->edge->weight = (weight + c->estimated_weight) / 2; c->edge->weight = (weight + c->estimated_weight) / 2;
c->edge->connection = c; c->edge->connection = c;
c->edge->options = c->options; c->edge->options = c->options;
cp();
edge_add(c->edge); edge_add(c->edge);
cp();
/* Notify everyone of the new edge */ /* Notify everyone of the new edge */
send_add_edge(broadcast, c->edge); send_add_edge(broadcast, c->edge);
@ -580,6 +591,6 @@ int ack_h(connection_t *c)
/* Run MST and SSSP algorithms */ /* Run MST and SSSP algorithms */
graph(); graph();
cp();
return 0; return 0;
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_edge.c,v 1.1.4.11 2002/09/09 19:40:04 guus Exp $ $Id: protocol_edge.c,v 1.1.4.12 2002/09/09 21:24:48 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -45,22 +45,25 @@
#include "system.h" #include "system.h"
int send_add_edge(connection_t *c, edge_t *e) int send_add_edge(connection_t * c, edge_t * e)
{ {
int x; int x;
char *address, *port; char *address, *port;
cp(); cp();
sockaddr2str(&e->address, &address, &port); sockaddr2str(&e->address, &address, &port);
x = send_request(c, "%d %lx %s %s %s %s %lx %d", ADD_EDGE, random(), x = send_request(c, "%d %lx %s %s %s %s %lx %d", ADD_EDGE, random(),
e->from->name, e->to->name, address, port, e->from->name, e->to->name, address, port,
e->options, e->weight); e->options, e->weight);
free(address); free(address);
free(port); free(port);
cp();
return x; return x;
} }
int add_edge_h(connection_t *c) int add_edge_h(connection_t * c)
{ {
edge_t *e; edge_t *e;
node_t *from, *to; node_t *from, *to;
@ -71,25 +74,27 @@ int add_edge_h(connection_t *c)
sockaddr_t address; sockaddr_t address;
long int options; long int options;
int weight; int weight;
cp(); cp();
if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %lx %d", if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %lx %d",
from_name, to_name, to_address, to_port, &options, &weight) != 6) from_name, to_name, to_address, to_port, &options, &weight) != 6) {
{ syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_EDGE", c->name,
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_EDGE", c->name, c->hostname); c->hostname);
return -1; return -1;
} }
/* Check if names are valid */ /* Check if names are valid */
if(check_id(from_name)) if(check_id(from_name)) {
{ syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_EDGE", c->name,
syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_EDGE", c->name, c->hostname, _("invalid name")); c->hostname, _("invalid name"));
return -1; return -1;
} }
if(check_id(to_name)) if(check_id(to_name)) {
{ syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_EDGE", c->name,
syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_EDGE", c->name, c->hostname, _("invalid name")); c->hostname, _("invalid name"));
return -1; return -1;
} }
@ -100,8 +105,7 @@ int add_edge_h(connection_t *c)
from = lookup_node(from_name); from = lookup_node(from_name);
if(!from) if(!from) {
{
from = new_node(); from = new_node();
from->name = xstrdup(from_name); from->name = xstrdup(from_name);
node_add(from); node_add(from);
@ -109,8 +113,7 @@ int add_edge_h(connection_t *c)
to = lookup_node(to_name); to = lookup_node(to_name);
if(!to) if(!to) {
{
to = new_node(); to = new_node();
to->name = xstrdup(to_name); to->name = xstrdup(to_name);
node_add(to); node_add(to);
@ -124,31 +127,26 @@ int add_edge_h(connection_t *c)
e = lookup_edge(from, to); e = lookup_edge(from, to);
if(e) if(e) {
{ if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) {
if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) if(from == myself) {
{
if(from == myself)
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself which does not match existing entry"), "ADD_EDGE", c->name, c->hostname); syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself which does not match existing entry"),
"ADD_EDGE", c->name, c->hostname);
send_add_edge(c, e); send_add_edge(c, e);
return 0; return 0;
} } else {
else
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_WARNING, _("Got %s from %s (%s) which does not match existing entry"), "ADD_EDGE", c->name, c->hostname); syslog(LOG_WARNING, _("Got %s from %s (%s) which does not match existing entry"),
"ADD_EDGE", c->name, c->hostname);
edge_del(e); edge_del(e);
} }
} } else
else
return 0; return 0;
} } else if(from == myself) {
else if(from == myself)
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself which does not exist"), "ADD_EDGE", c->name, c->hostname); syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself which does not exist"),
"ADD_EDGE", c->name, c->hostname);
e = new_edge(); e = new_edge();
e->from = from; e->from = from;
e->to = to; e->to = to;
@ -172,42 +170,44 @@ int add_edge_h(connection_t *c)
/* Run MST before or after we tell the rest? */ /* Run MST before or after we tell the rest? */
graph(); graph();
cp();
return 0; return 0;
} }
int send_del_edge(connection_t *c, edge_t *e) int send_del_edge(connection_t * c, edge_t * e)
{ {
cp(); cp();
return send_request(c, "%d %lx %s %s", DEL_EDGE, random(), return send_request(c, "%d %lx %s %s", DEL_EDGE, random(),
e->from->name, e->to->name); e->from->name, e->to->name);
} }
int del_edge_h(connection_t *c) int del_edge_h(connection_t * c)
{ {
edge_t *e; edge_t *e;
char from_name[MAX_STRING_SIZE]; char from_name[MAX_STRING_SIZE];
char to_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE];
node_t *from, *to; node_t *from, *to;
cp(); cp();
if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING"", from_name, to_name) != 2)
{ if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_EDGE", syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_EDGE", c->name,
c->name, c->hostname); c->hostname);
return -1; return -1;
} }
/* Check if names are valid */ /* Check if names are valid */
if(check_id(from_name)) if(check_id(from_name)) {
{ syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_EDGE", c->name,
syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_EDGE", c->name, c->hostname, _("invalid name")); c->hostname, _("invalid name"));
return -1; return -1;
} }
if(check_id(to_name)) if(check_id(to_name)) {
{ syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_EDGE", c->name,
syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_EDGE", c->name, c->hostname, _("invalid name")); c->hostname, _("invalid name"));
return -1; return -1;
} }
@ -218,19 +218,23 @@ int del_edge_h(connection_t *c)
from = lookup_node(from_name); from = lookup_node(from_name);
if(!from) if(!from) {
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_ERR, _("Got %s from %s (%s) which does not appear in the edge tree"), "DEL_EDGE", c->name, c->hostname); syslog(LOG_ERR,
_
("Got %s from %s (%s) which does not appear in the edge tree"),
"DEL_EDGE", c->name, c->hostname);
return 0; return 0;
} }
to = lookup_node(to_name); to = lookup_node(to_name);
if(!to) if(!to) {
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_ERR, _("Got %s from %s (%s) which does not appear in the edge tree"), "DEL_EDGE", c->name, c->hostname); syslog(LOG_ERR,
_
("Got %s from %s (%s) which does not appear in the edge tree"),
"DEL_EDGE", c->name, c->hostname);
return 0; return 0;
} }
@ -238,17 +242,19 @@ int del_edge_h(connection_t *c)
e = lookup_edge(from, to); e = lookup_edge(from, to);
if(!e) if(!e) {
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_WARNING, _("Got %s from %s (%s) which does not appear in the edge tree"), "DEL_EDGE", c->name, c->hostname); syslog(LOG_WARNING,
_
("Got %s from %s (%s) which does not appear in the edge tree"),
"DEL_EDGE", c->name, c->hostname);
return 0; return 0;
} }
if(e->from == myself) if(e->from == myself) {
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself"), "DEL_EDGE", c->name, c->hostname); syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself"),
"DEL_EDGE", c->name, c->hostname);
send_add_edge(c, e); /* Send back a correction */ send_add_edge(c, e); /* Send back a correction */
return 0; return 0;
} }
@ -264,6 +270,6 @@ int del_edge_h(connection_t *c)
/* Run MST before or after we tell the rest? */ /* Run MST before or after we tell the rest? */
graph(); graph();
cp();
return 0; return 0;
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_key.c,v 1.1.4.12 2002/09/09 19:40:05 guus Exp $ $Id: protocol_key.c,v 1.1.4.13 2002/09/09 21:24:56 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -45,26 +45,28 @@
int mykeyused = 0; int mykeyused = 0;
int send_key_changed(connection_t *c, node_t *n) int send_key_changed(connection_t * c, node_t * n)
{ {
cp(); cp();
/* Only send this message if some other daemon requested our key previously. /* Only send this message if some other daemon requested our key previously.
This reduces unnecessary key_changed broadcasts. This reduces unnecessary key_changed broadcasts.
*/ */
if(n == myself && !mykeyused) if(n == myself && !mykeyused)
return 0; return 0;
cp();
return send_request(c, "%d %lx %s", KEY_CHANGED, random(), n->name); return send_request(c, "%d %lx %s", KEY_CHANGED, random(), n->name);
} }
int key_changed_h(connection_t *c) int key_changed_h(connection_t * c)
{ {
char name[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE];
node_t *n; node_t *n;
cp(); cp();
if(sscanf(c->buffer, "%*d %*x "MAX_STRING, name) != 1)
{ if(sscanf(c->buffer, "%*d %*x " MAX_STRING, name) != 1) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "KEY_CHANGED", syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "KEY_CHANGED",
c->name, c->hostname); c->name, c->hostname);
return -1; return -1;
@ -75,10 +77,9 @@ int key_changed_h(connection_t *c)
n = lookup_node(name); n = lookup_node(name);
if(!n) if(!n) {
{ syslog(LOG_ERR, _("Got %s from %s (%s) origin %s which does not exist"),
syslog(LOG_ERR, _("Got %s from %s (%s) origin %s which does not exist"), "KEY_CHANGED", "KEY_CHANGED", c->name, c->hostname, name);
c->name, c->hostname, name);
return -1; return -1;
} }
@ -88,120 +89,113 @@ int key_changed_h(connection_t *c)
/* Tell the others */ /* Tell the others */
forward_request(c); forward_request(c);
cp();
return 0; return 0;
} }
int send_req_key(connection_t *c, node_t *from, node_t *to) int send_req_key(connection_t * c, node_t * from, node_t * to)
{ {
cp(); cp();
return send_request(c, "%d %s %s", REQ_KEY,
from->name, to->name); return send_request(c, "%d %s %s", REQ_KEY, from->name, to->name);
} }
int req_key_h(connection_t *c) int req_key_h(connection_t * c)
{ {
char from_name[MAX_STRING_SIZE]; char from_name[MAX_STRING_SIZE];
char to_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE];
node_t *from, *to; node_t *from, *to;
cp(); cp();
if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING, from_name, to_name) != 2)
{ if(sscanf(c->buffer, "%*d " MAX_STRING " " MAX_STRING, from_name, to_name) != 2) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "REQ_KEY", syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "REQ_KEY", c->name,
c->name, c->hostname); c->hostname);
return -1; return -1;
} }
from = lookup_node(from_name); from = lookup_node(from_name);
if(!from) if(!from) {
{ syslog(LOG_ERR, _("Got %s from %s (%s) origin %s which does not exist in our connection list"),
syslog(LOG_ERR, _("Got %s from %s (%s) origin %s which does not exist in our connection list"), "REQ_KEY", "REQ_KEY", c->name, c->hostname, from_name);
c->name, c->hostname, from_name);
return -1; return -1;
} }
to = lookup_node(to_name); to = lookup_node(to_name);
if(!to) if(!to) {
{ syslog(LOG_ERR, _("Got %s from %s (%s) destination %s which does not exist in our connection list"),
syslog(LOG_ERR, _("Got %s from %s (%s) destination %s which does not exist in our connection list"), "REQ_KEY", "REQ_KEY", c->name, c->hostname, to_name);
c->name, c->hostname, to_name);
return -1; return -1;
} }
/* Check if this key request is for us */ /* Check if this key request is for us */
if(to == myself) /* Yes, send our own key back */ if(to == myself) { /* Yes, send our own key back */
{
mykeyused = 1; mykeyused = 1;
from->received_seqno = 0; from->received_seqno = 0;
send_ans_key(c, myself, from); send_ans_key(c, myself, from);
} } else {
else
{
/* Proxy keys
if(to->status.validkey)
{
send_ans_key(c, to, from);
}
else
*/
send_req_key(to->nexthop->connection, from, to); send_req_key(to->nexthop->connection, from, to);
} }
cp();
return 0; return 0;
} }
int send_ans_key(connection_t *c, node_t *from, node_t *to) int send_ans_key(connection_t * c, node_t * from, node_t * to)
{ {
char key[MAX_STRING_SIZE]; char key[MAX_STRING_SIZE];
cp(); cp();
bin2hex(from->key, key, from->keylength); bin2hex(from->key, key, from->keylength);
key[from->keylength * 2] = '\0'; key[from->keylength * 2] = '\0';
cp();
return send_request(c, "%d %s %s %s %d %d %d %d", ANS_KEY, return send_request(c, "%d %s %s %s %d %d %d %d", ANS_KEY,
from->name, to->name, key, from->cipher?from->cipher->nid:0, from->digest?from->digest->type:0, from->maclength, from->compression); from->name, to->name, key,
from->cipher ? from->cipher->nid : 0,
from->digest ? from->digest->type : 0, from->maclength,
from->compression);
} }
int ans_key_h(connection_t *c) int ans_key_h(connection_t * c)
{ {
char from_name[MAX_STRING_SIZE]; char from_name[MAX_STRING_SIZE];
char to_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE];
char key[MAX_STRING_SIZE]; char key[MAX_STRING_SIZE];
int cipher, digest, maclength, compression; int cipher, digest, maclength, compression;
node_t *from, *to; node_t *from, *to;
cp(); cp();
if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d", from_name, to_name, key, &cipher, &digest, &maclength, &compression) != 7)
{ if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d",
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ANS_KEY", from_name, to_name, key, &cipher, &digest, &maclength,
c->name, c->hostname); &compression) != 7) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ANS_KEY", c->name,
c->hostname);
return -1; return -1;
} }
from = lookup_node(from_name); from = lookup_node(from_name);
if(!from) if(!from) {
{ syslog(LOG_ERR, _("Got %s from %s (%s) origin %s which does not exist in our connection list"),
syslog(LOG_ERR, _("Got %s from %s (%s) origin %s which does not exist in our connection list"), "ANS_KEY", "ANS_KEY", c->name, c->hostname, from_name);
c->name, c->hostname, from_name);
return -1; return -1;
} }
to = lookup_node(to_name); to = lookup_node(to_name);
if(!to) if(!to) {
{ syslog(LOG_ERR, _("Got %s from %s (%s) destination %s which does not exist in our connection list"),
syslog(LOG_ERR, _("Got %s from %s (%s) destination %s which does not exist in our connection list"), "ANS_KEY", "ANS_KEY", c->name, c->hostname, to_name);
c->name, c->hostname, to_name);
return -1; return -1;
} }
/* Forward it if necessary */ /* Forward it if necessary */
if(to != myself) if(to != myself) {
{
return send_request(to->nexthop->connection, "%s", c->buffer); return send_request(to->nexthop->connection, "%s", c->buffer);
} }
@ -221,49 +215,47 @@ int ans_key_h(connection_t *c)
/* Check and lookup cipher and digest algorithms */ /* Check and lookup cipher and digest algorithms */
if(cipher) if(cipher) {
{
from->cipher = EVP_get_cipherbynid(cipher); from->cipher = EVP_get_cipherbynid(cipher);
if(!from->cipher)
{ if(!from->cipher) {
syslog(LOG_ERR, _("Node %s (%s) uses unknown cipher!"), from->name, from->hostname); syslog(LOG_ERR, _("Node %s (%s) uses unknown cipher!"), from->name,
from->hostname);
return -1; return -1;
} }
if(from->keylength != from->cipher->key_len + from->cipher->iv_len)
{ if(from->keylength != from->cipher->key_len + from->cipher->iv_len) {
syslog(LOG_ERR, _("Node %s (%s) uses wrong keylength!"), from->name, from->hostname); syslog(LOG_ERR, _("Node %s (%s) uses wrong keylength!"), from->name,
from->hostname);
return -1; return -1;
} }
} } else {
else
{
from->cipher = NULL; from->cipher = NULL;
} }
from->maclength = maclength; from->maclength = maclength;
if(digest) if(digest) {
{
from->digest = EVP_get_digestbynid(digest); from->digest = EVP_get_digestbynid(digest);
if(!from->digest)
{ if(!from->digest) {
syslog(LOG_ERR, _("Node %s (%s) uses unknown digest!"), from->name, from->hostname); syslog(LOG_ERR, _("Node %s (%s) uses unknown digest!"), from->name,
from->hostname);
return -1; return -1;
} }
if(from->maclength > from->digest->md_size || from->maclength < 0)
{ if(from->maclength > from->digest->md_size || from->maclength < 0) {
syslog(LOG_ERR, _("Node %s (%s) uses bogus MAC length!"), from->name, from->hostname); syslog(LOG_ERR, _("Node %s (%s) uses bogus MAC length!"),
from->name, from->hostname);
return -1; return -1;
} }
} } else {
else
{
from->digest = NULL; from->digest = NULL;
} }
from->compression = compression; from->compression = compression;
flush_queue(from); flush_queue(from);
cp();
return 0; return 0;
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_misc.c,v 1.1.4.5 2002/09/09 19:40:08 guus Exp $ $Id: protocol_misc.c,v 1.1.4.6 2002/09/09 21:25:02 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -42,146 +42,158 @@
/* Status and error notification routines */ /* Status and error notification routines */
int send_status(connection_t *c, int statusno, char *statusstring) int send_status(connection_t * c, int statusno, char *statusstring)
{ {
cp(); cp();
if(!statusstring) if(!statusstring)
statusstring = status_text[statusno]; statusstring = status_text[statusno];
cp();
return send_request(c, "%d %d %s", STATUS, statusno, statusstring); return send_request(c, "%d %d %s", STATUS, statusno, statusstring);
} }
int status_h(connection_t *c) int status_h(connection_t * c)
{ {
int statusno; int statusno;
char statusstring[MAX_STRING_SIZE]; char statusstring[MAX_STRING_SIZE];
cp(); cp();
if(sscanf(c->buffer, "%*d %d "MAX_STRING, &statusno, statusstring) != 2)
{ if(sscanf(c->buffer, "%*d %d " MAX_STRING, &statusno, statusstring) != 2) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "STATUS", syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "STATUS",
c->name, c->hostname); c->name, c->hostname);
return -1; return -1;
} }
if(debug_lvl >= DEBUG_STATUS) if(debug_lvl >= DEBUG_STATUS) {
{
syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"), syslog(LOG_NOTICE, _("Status message from %s (%s): %s: %s"),
c->name, c->hostname, status_text[statusno], statusstring); c->name, c->hostname, status_text[statusno], statusstring);
} }
cp();
return 0; return 0;
} }
int send_error(connection_t *c, int err, char *errstring) int send_error(connection_t * c, int err, char *errstring)
{ {
cp(); cp();
if(!errstring) if(!errstring)
errstring = strerror(err); errstring = strerror(err);
return send_request(c, "%d %d %s", ERROR, err, errstring); return send_request(c, "%d %d %s", ERROR, err, errstring);
} }
int error_h(connection_t *c) int error_h(connection_t * c)
{ {
int err; int err;
char errorstring[MAX_STRING_SIZE]; char errorstring[MAX_STRING_SIZE];
cp(); cp();
if(sscanf(c->buffer, "%*d %d "MAX_STRING, &err, errorstring) != 2)
{ if(sscanf(c->buffer, "%*d %d " MAX_STRING, &err, errorstring) != 2) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ERROR", syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ERROR",
c->name, c->hostname); c->name, c->hostname);
return -1; return -1;
} }
if(debug_lvl >= DEBUG_ERROR) if(debug_lvl >= DEBUG_ERROR) {
{
syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"), syslog(LOG_NOTICE, _("Error message from %s (%s): %s: %s"),
c->name, c->hostname, strerror(err), errorstring); c->name, c->hostname, strerror(err), errorstring);
} }
terminate_connection(c, c->status.active); terminate_connection(c, c->status.active);
cp();
return 0; return 0;
} }
int send_termreq(connection_t *c) int send_termreq(connection_t * c)
{ {
cp(); cp();
return send_request(c, "%d", TERMREQ); return send_request(c, "%d", TERMREQ);
} }
int termreq_h(connection_t *c) int termreq_h(connection_t * c)
{ {
cp(); cp();
terminate_connection(c, c->status.active); terminate_connection(c, c->status.active);
cp();
return 0; return 0;
} }
int send_ping(connection_t *c) int send_ping(connection_t * c)
{ {
cp(); cp();
c->status.pinged = 1; c->status.pinged = 1;
c->last_ping_time = now; c->last_ping_time = now;
cp();
return send_request(c, "%d", PING); return send_request(c, "%d", PING);
} }
int ping_h(connection_t *c) int ping_h(connection_t * c)
{ {
cp(); cp();
return send_pong(c); return send_pong(c);
} }
int send_pong(connection_t *c) int send_pong(connection_t * c)
{ {
cp(); cp();
return send_request(c, "%d", PONG); return send_request(c, "%d", PONG);
} }
int pong_h(connection_t *c) int pong_h(connection_t * c)
{ {
cp(); cp();
c->status.pinged = 0; c->status.pinged = 0;
/* Succesful connection, reset timeout if this is an outgoing connection. */ /* Succesful connection, reset timeout if this is an outgoing connection. */
if(c->outgoing) if(c->outgoing)
c->outgoing->timeout = 0; c->outgoing->timeout = 0;
cp();
return 0; return 0;
} }
/* Sending and receiving packets via TCP */ /* Sending and receiving packets via TCP */
int send_tcppacket(connection_t *c, vpn_packet_t *packet) int send_tcppacket(connection_t * c, vpn_packet_t * packet)
{ {
int x; int x;
cp(); cp();
/* Evil hack. */ /* Evil hack. */
x = send_request(c, "%d %hd", PACKET, packet->len); x = send_request(c, "%d %hd", PACKET, packet->len);
if(x) if(x)
return x; return x;
cp();
return send_meta(c, packet->data, packet->len); return send_meta(c, packet->data, packet->len);
} }
int tcppacket_h(connection_t *c) int tcppacket_h(connection_t * c)
{ {
short int len; short int len;
cp(); cp();
if(sscanf(c->buffer, "%*d %hd", &len) != 1)
{ if(sscanf(c->buffer, "%*d %hd", &len) != 1) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "PACKET", c->name, c->hostname); syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "PACKET", c->name,
c->hostname);
return -1; return -1;
} }
/* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */ /* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */
c->tcplen = len; c->tcplen = len;
cp();
return 0; return 0;
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_node.c,v 1.1.4.7 2002/09/09 19:40:08 guus Exp $ $Id: protocol_node.c,v 1.1.4.8 2002/09/09 21:25:02 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -43,7 +43,7 @@
#include "system.h" #include "system.h"
int send_add_node(connection_t *c, node_t *n) int send_add_node(connection_t * c, node_t * n)
{ {
int x; int x;
char *address, *port; char *address, *port;
@ -52,9 +52,7 @@ int send_add_node(connection_t *c, node_t *n)
return 0; return 0;
sockaddr2str(&n->address, &address, &port); sockaddr2str(&n->address, &address, &port);
x = send_request(c, "%d %s %s %s %lx %d %s %s", ADD_NODE, x = send_request(c, "%d %s %s %s %lx %d %s %s", ADD_NODE, n->name, address, port, n->options, n->distance + 1, // Alternatively, use n->distance + c->estimated_weight
n->name, address, port,
n->options, n->distance + 1, // Alternatively, use n->distance + c->estimated_weight
n->prevhop->name, n->via->name); n->prevhop->name, n->via->name);
free(address); free(address);
free(port); free(port);
@ -62,7 +60,7 @@ int send_add_node(connection_t *c, node_t *n)
return x; return x;
} }
int add_node_h(connection_t *c) int add_node_h(connection_t * c)
{ {
connection_t *other; connection_t *other;
node_t *n, *prevhop, *via; node_t *n, *prevhop, *via;
@ -75,18 +73,21 @@ int add_node_h(connection_t *c)
int distance; int distance;
avl_node_t *node; avl_node_t *node;
cp(); cp();
if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %lx %d "MAX_STRING" "MAX_STRING, if(sscanf
name, address, port, &options, &distance, prevhopname, vianame) != 7) (c->buffer,
{ "%*d " MAX_STRING " " MAX_STRING " " MAX_STRING " %lx %d " MAX_STRING
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_NODE", c->name, c->hostname); " " MAX_STRING, name, address, port, &options, &distance, prevhopname,
vianame) != 7) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_NODE", c->name,
c->hostname);
return -1; return -1;
} }
/* Check if names are valid */ /* Check if names are valid */
if(check_id(name)) if(check_id(name)) {
{ syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_NODE", c->name,
syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_NODE", c->name, c->hostname, _("invalid name")); c->hostname, _("invalid name"));
return -1; return -1;
} }
@ -99,8 +100,7 @@ int add_node_h(connection_t *c)
prevhop = lookup_node(prevhopname); prevhop = lookup_node(prevhopname);
if(!prevhop) if(!prevhop) {
{
prevhop = new_node(); prevhop = new_node();
prevhop->name = xstrdup(prevhopname); prevhop->name = xstrdup(prevhopname);
node_add(prevhop); node_add(prevhop);
@ -108,8 +108,7 @@ int add_node_h(connection_t *c)
via = lookup_node(vianame); via = lookup_node(vianame);
if(!via) if(!via) {
{
via = new_node(); via = new_node();
via->name = xstrdup(vianame); via->name = xstrdup(vianame);
node_add(via); node_add(via);
@ -117,8 +116,7 @@ int add_node_h(connection_t *c)
n = lookup_node(name); n = lookup_node(name);
if(!n) if(!n) {
{
// It's a new node. Add it and tell the others. // It's a new node. Add it and tell the others.
n = new_node(); n = new_node();
n->name = xstrdup(name); n->name = xstrdup(name);
@ -130,22 +128,24 @@ int add_node_h(connection_t *c)
n->prevhop = prevhop; n->prevhop = prevhop;
n->via = via; n->via = via;
node_add(n); node_add(n);
if(prevhop == myself) if(prevhop == myself) {
{ syslog(LOG_WARNING,
syslog(LOG_WARNING, _("Got ADD_NODE %s prevhop %s via %s from %s, sending back a DEL_NODE!"), name, prevhopname, vianame, c->name); _
("Got ADD_NODE %s prevhop %s via %s from %s, sending back a DEL_NODE!"),
name, prevhopname, vianame, c->name);
// send_del_node(c, n); // send_del_node(c, n);
return 0; return 0;
} }
n->status.reachable = 1; n->status.reachable = 1;
} } else {
else
{
// If this ADD_NODE is closer or more direct, use it instead of the old one. // If this ADD_NODE is closer or more direct, use it instead of the old one.
if(!n->status.reachable || ((n->options & OPTION_INDIRECT) && !(options & OPTION_INDIRECT)) || n->distance > distance) if(!n->status.reachable
{ || ((n->options & OPTION_INDIRECT) && !(options & OPTION_INDIRECT))
if(prevhop == myself) || n->distance > distance) {
{ if(prevhop == myself) {
syslog(LOG_WARNING, _("Got ADD_NODE %s prevhop %s via %s from %s!"), name, prevhopname, vianame, c->name); syslog(LOG_WARNING,
_("Got ADD_NODE %s prevhop %s via %s from %s!"), name,
prevhopname, vianame, c->name);
// send_del_node(c, n); // send_del_node(c, n);
return 0; return 0;
} }
@ -161,17 +161,15 @@ int add_node_h(connection_t *c)
n->status.reachable = 1; n->status.reachable = 1;
n->status.validkey = 0; n->status.validkey = 0;
n->status.waitingforkey = 0; n->status.waitingforkey = 0;
} } else
else
// Otherwise, just ignore it. // Otherwise, just ignore it.
return 0; return 0;
} }
/* Tell the rest about the new node */ /* Tell the rest about the new node */
for(node = connection_tree->head; node; node = node->next) for(node = connection_tree->head; node; node = node->next) {
{ other = (connection_t *) node->data;
other = (connection_t *)node->data;
if(other->status.active && other != c) if(other->status.active && other != c)
send_add_node(other, n); send_add_node(other, n);
} }
@ -180,13 +178,13 @@ int add_node_h(connection_t *c)
return 0; return 0;
} }
int send_del_node(connection_t *c, node_t *n) int send_del_node(connection_t * c, node_t * n)
{ {
cp(); cp();
return send_request(c, "%d %s %s", DEL_NODE, n->name, n->prevhop->name); return send_request(c, "%d %s %s", DEL_NODE, n->name, n->prevhop->name);
} }
int del_node_h(connection_t *c) int del_node_h(connection_t * c)
{ {
char name[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE];
char prevhopname[MAX_STRING_SIZE]; char prevhopname[MAX_STRING_SIZE];
@ -194,18 +192,18 @@ int del_node_h(connection_t *c)
connection_t *other; connection_t *other;
avl_node_t *node; avl_node_t *node;
cp(); cp();
if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING, name, prevhopname) != 2) if(sscanf(c->buffer, "%*d " MAX_STRING " " MAX_STRING, name, prevhopname) !=
{ 2) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_NODE", syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_NODE", c->name,
c->name, c->hostname); c->hostname);
return -1; return -1;
} }
/* Check if names are valid */ /* Check if names are valid */
if(check_id(name)) if(check_id(name)) {
{ syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_NODE", c->name,
syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_NODE", c->name, c->hostname, _("invalid name")); c->hostname, _("invalid name"));
return -1; return -1;
} }
@ -214,25 +212,25 @@ int del_node_h(connection_t *c)
n = lookup_node(name); n = lookup_node(name);
prevhop = lookup_node(prevhopname); prevhop = lookup_node(prevhopname);
if(!n || !prevhop) if(!n || !prevhop) {
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_WARNING, _("Got %s from %s (%s) which does not appear in the node tree"), "DEL_NODE", c->name, c->hostname); syslog(LOG_WARNING,
_
("Got %s from %s (%s) which does not appear in the node tree"),
"DEL_NODE", c->name, c->hostname);
return 0; return 0;
} }
/* If we got a DEL_NODE but we know of a different route to it, tell the one who send the DEL_NODE */ /* If we got a DEL_NODE but we know of a different route to it, tell the one who send the DEL_NODE */
if(n->nexthop != c->node) if(n->nexthop != c->node) {
{
return send_add_node(c, n); return send_add_node(c, n);
} }
/* Otherwise, tell the rest about the deleted node */ /* Otherwise, tell the rest about the deleted node */
for(node = connection_tree->head; node; node = node->next) for(node = connection_tree->head; node; node = node->next) {
{ other = (connection_t *) node->data;
other = (connection_t *)node->data;
if(other->status.active && other != c) if(other->status.active && other != c)
send_del_node(other, n); send_del_node(other, n);
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: protocol_subnet.c,v 1.1.4.7 2002/09/09 19:40:09 guus Exp $ $Id: protocol_subnet.c,v 1.1.4.8 2002/09/09 21:25:02 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -43,36 +43,41 @@
#include "system.h" #include "system.h"
int send_add_subnet(connection_t *c, subnet_t *subnet) int send_add_subnet(connection_t * c, subnet_t * subnet)
{ {
int x; int x;
char *netstr; char *netstr;
cp(); cp();
x = send_request(c, "%d %lx %s %s", ADD_SUBNET, random(), x = send_request(c, "%d %lx %s %s", ADD_SUBNET, random(),
subnet->owner->name, netstr = net2str(subnet)); subnet->owner->name, netstr = net2str(subnet));
free(netstr); free(netstr);
cp();
return x; return x;
} }
int add_subnet_h(connection_t *c) int add_subnet_h(connection_t * c)
{ {
char subnetstr[MAX_STRING_SIZE]; char subnetstr[MAX_STRING_SIZE];
char name[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE];
node_t *owner; node_t *owner;
subnet_t *s; subnet_t *s;
cp(); cp();
if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
{ if(sscanf(c->buffer, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_SUBNET", c->name, c->hostname); syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_SUBNET", c->name,
c->hostname);
return -1; return -1;
} }
/* Check if owner name is a valid */ /* Check if owner name is a valid */
if(check_id(name)) if(check_id(name)) {
{ syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_SUBNET", c->name,
syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_SUBNET", c->name, c->hostname, _("invalid name")); c->hostname, _("invalid name"));
return -1; return -1;
} }
@ -80,9 +85,9 @@ int add_subnet_h(connection_t *c)
s = str2net(subnetstr); s = str2net(subnetstr);
if(!s) if(!s) {
{ syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_SUBNET", c->name,
syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_SUBNET", c->name, c->hostname, _("invalid subnet string")); c->hostname, _("invalid subnet string"));
return -1; return -1;
} }
@ -93,8 +98,7 @@ int add_subnet_h(connection_t *c)
owner = lookup_node(name); owner = lookup_node(name);
if(!owner) if(!owner) {
{
owner = new_node(); owner = new_node();
owner->name = xstrdup(name); owner->name = xstrdup(name);
node_add(owner); node_add(owner);
@ -102,18 +106,17 @@ int add_subnet_h(connection_t *c)
/* Check if we already know this subnet */ /* Check if we already know this subnet */
if(lookup_subnet(owner, s)) if(lookup_subnet(owner, s)) {
{
free_subnet(s); free_subnet(s);
return 0; return 0;
} }
/* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */ /* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */
if(owner == myself) if(owner == myself) {
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself"), "ADD_SUBNET", c->name, c->hostname); syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself"),
"ADD_SUBNET", c->name, c->hostname);
s->owner = myself; s->owner = myself;
send_del_subnet(c, s); send_del_subnet(c, s);
return 0; return 0;
@ -126,40 +129,46 @@ int add_subnet_h(connection_t *c)
/* Tell the rest */ /* Tell the rest */
forward_request(c); forward_request(c);
cp();
return 0; return 0;
} }
int send_del_subnet(connection_t *c, subnet_t *s) int send_del_subnet(connection_t * c, subnet_t * s)
{ {
int x; int x;
char *netstr; char *netstr;
cp(); cp();
netstr = net2str(s); netstr = net2str(s);
x = send_request(c, "%d %lx %s %s", DEL_SUBNET, random(), s->owner->name, netstr); x = send_request(c, "%d %lx %s %s", DEL_SUBNET, random(), s->owner->name, netstr);
free(netstr); free(netstr);
cp();
return x; return x;
} }
int del_subnet_h(connection_t *c) int del_subnet_h(connection_t * c)
{ {
char subnetstr[MAX_STRING_SIZE]; char subnetstr[MAX_STRING_SIZE];
char name[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE];
node_t *owner; node_t *owner;
subnet_t *s, *find; subnet_t *s, *find;
cp(); cp();
if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING, name, subnetstr) != 2)
{ if(sscanf(c->buffer, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_SUBNET", c->name, c->hostname); syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_SUBNET", c->name,
c->hostname);
return -1; return -1;
} }
/* Check if owner name is a valid */ /* Check if owner name is a valid */
if(check_id(name)) if(check_id(name)) {
{ syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_SUBNET", c->name,
syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_SUBNET", c->name, c->hostname, _("invalid name")); c->hostname, _("invalid name"));
return -1; return -1;
} }
@ -167,8 +176,7 @@ int del_subnet_h(connection_t *c)
owner = lookup_node(name); owner = lookup_node(name);
if(!owner) if(!owner) {
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_WARNING, _("Got %s from %s (%s) for %s which is not in our node tree"), syslog(LOG_WARNING, _("Got %s from %s (%s) for %s which is not in our node tree"),
"DEL_SUBNET", c->name, c->hostname, name); "DEL_SUBNET", c->name, c->hostname, name);
@ -179,9 +187,9 @@ int del_subnet_h(connection_t *c)
s = str2net(subnetstr); s = str2net(subnetstr);
if(!s) if(!s) {
{ syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_SUBNET", c->name,
syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_SUBNET", c->name, c->hostname, _("invalid subnet string")); c->hostname, _("invalid subnet string"));
return -1; return -1;
} }
@ -196,8 +204,7 @@ int del_subnet_h(connection_t *c)
free_subnet(s); free_subnet(s);
if(!find) if(!find) {
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_WARNING, _("Got %s from %s (%s) for %s which does not appear in his subnet tree"), syslog(LOG_WARNING, _("Got %s from %s (%s) for %s which does not appear in his subnet tree"),
"DEL_SUBNET", c->name, c->hostname, name); "DEL_SUBNET", c->name, c->hostname, name);
@ -206,10 +213,10 @@ int del_subnet_h(connection_t *c)
/* If we are the owner of this subnet, retaliate with an ADD_SUBNET */ /* If we are the owner of this subnet, retaliate with an ADD_SUBNET */
if(owner == myself) if(owner == myself) {
{
if(debug_lvl >= DEBUG_PROTOCOL) if(debug_lvl >= DEBUG_PROTOCOL)
syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself"), "DEL_SUBNET", c->name, c->hostname); syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself"),
"DEL_SUBNET", c->name, c->hostname);
send_add_subnet(c, find); send_add_subnet(c, find);
return 0; return 0;
} }
@ -222,6 +229,5 @@ int del_subnet_h(connection_t *c)
subnet_del(owner, find); subnet_del(owner, find);
cp();
return 0; return 0;
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.1.2.1 2002/07/18 14:30:45 guus Exp $ $Id: device.c,v 1.1.2.2 2002/09/09 21:25:28 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -62,27 +62,26 @@ int setup_device(void)
{ {
struct ifreq ifr; struct ifreq ifr;
struct sockaddr_ll sa; struct sockaddr_ll sa;
cp cp if(!get_config_string
if(!get_config_string(lookup_config(config_tree, "Interface"), &interface)) (lookup_config(config_tree, "Interface"), &interface))
interface = "eth0"; interface = "eth0";
if(!get_config_string(lookup_config(config_tree, "Device"), &device)) if(!get_config_string(lookup_config(config_tree, "Device"), &device))
device = interface; device = interface;
device_info = _("raw socket"); device_info = _("raw socket");
cp cp if((device_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
if((device_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) syslog(LOG_ERR, _("Could not open %s: %s"), device_info,
{ strerror(errno));
syslog(LOG_ERR, _("Could not open %s: %s"), device_info, strerror(errno));
return -1; return -1;
} }
memset(&ifr, 0, sizeof(ifr)); memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_ifrn.ifrn_name, interface, IFNAMSIZ); strncpy(ifr.ifr_ifrn.ifrn_name, interface, IFNAMSIZ);
if(ioctl(device_fd, SIOCGIFINDEX, &ifr)) if(ioctl(device_fd, SIOCGIFINDEX, &ifr)) {
{
close(device_fd); close(device_fd);
syslog(LOG_ERR, _("Can't find interface %s: %s"), interface, strerror(errno)); syslog(LOG_ERR, _("Can't find interface %s: %s"), interface,
strerror(errno));
return -1; return -1;
} }
@ -91,14 +90,12 @@ cp
sa.sll_protocol = htons(ETH_P_ALL); sa.sll_protocol = htons(ETH_P_ALL);
sa.sll_ifindex = ifr.ifr_ifindex; sa.sll_ifindex = ifr.ifr_ifindex;
if(bind(device_fd, (struct sockaddr *)&sa, (socklen_t)sizeof(sa))) if(bind(device_fd, (struct sockaddr *) &sa, (socklen_t) sizeof(sa))) {
{
syslog(LOG_ERR, _("Could not bind to %s: %s"), device, strerror(errno)); syslog(LOG_ERR, _("Could not bind to %s: %s"), device, strerror(errno));
return -1; return -1;
} }
cp cp
/* Set default MAC address for ethertap devices */ /* Set default MAC address for ethertap devices */
mymac.type = SUBNET_MAC; mymac.type = SUBNET_MAC;
mymac.net.mac.address.x[0] = 0xfe; mymac.net.mac.address.x[0] = 0xfe;
mymac.net.mac.address.x[1] = 0xfd; mymac.net.mac.address.x[1] = 0xfd;
@ -108,28 +105,24 @@ cp
mymac.net.mac.address.x[5] = 0x00; mymac.net.mac.address.x[5] = 0x00;
syslog(LOG_INFO, _("%s is a %s"), device, device_info); syslog(LOG_INFO, _("%s is a %s"), device, device_info);
cp cp return 0;
return 0;
} }
void close_device(void) void close_device(void)
{ {
cp cp close(device_fd);
close(device_fd);
} }
/* /*
read, encrypt and send data that is read, encrypt and send data that is
available through the ethertap device available through the ethertap device
*/ */
int read_packet(vpn_packet_t *packet) int read_packet(vpn_packet_t * packet)
{ {
int lenin; int lenin;
cp cp if((lenin = read(device_fd, packet->data, MTU)) <= 0) {
syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
if((lenin = read(device_fd, packet->data, MTU)) <= 0) device, strerror(errno));
{
syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno));
return -1; return -1;
} }
@ -137,38 +130,33 @@ cp
device_total_in += packet->len; device_total_in += packet->len;
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC) {
{ syslog(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len,
syslog(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); device_info);
} }
return 0; return 0;
cp cp}
}
int write_packet(vpn_packet_t *packet) int write_packet(vpn_packet_t * packet)
{ {
cp cp if(debug_lvl >= DEBUG_TRAFFIC)
if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"), syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"),
packet->len, device_info); packet->len, device_info);
if(write(device_fd, packet->data, packet->len) < 0) if(write(device_fd, packet->data, packet->len) < 0) {
{ syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device,
syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, device, strerror(errno)); strerror(errno));
return -1; return -1;
} }
device_total_out += packet->len; device_total_out += packet->len;
cp cp return 0;
return 0;
} }
void dump_device_stats(void) void dump_device_stats(void)
{ {
cp cp syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in);
syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out);
cp cp}
}

View file

@ -17,24 +17,24 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: route.c,v 1.1.2.44 2002/09/09 19:40:11 guus Exp $ $Id: route.c,v 1.1.2.45 2002/09/09 21:25:07 guus Exp $
*/ */
#include "config.h" #include "config.h"
#ifdef HAVE_SYS_PARAM_H #ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> #include <sys/param.h>
#endif #endif
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#ifdef HAVE_NET_IF_H #ifdef HAVE_NET_IF_H
#include <net/if.h> #include <net/if.h>
#endif #endif
#ifdef HAVE_NET_ETHERNET_H #ifdef HAVE_NET_ETHERNET_H
#include <net/ethernet.h> #include <net/ethernet.h>
#endif #endif
#ifdef HAVE_NETINET_IN_SYSTM_H #ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
#endif #endif
#include <netinet/ip6.h> #include <netinet/ip6.h>
#include <netinet/icmp6.h> #include <netinet/icmp6.h>
@ -44,7 +44,7 @@
#include <syslog.h> #include <syslog.h>
#include <string.h> #include <string.h>
#ifdef HAVE_INTTYPES_H #ifdef HAVE_INTTYPES_H
#include <inttypes.h> #include <inttypes.h>
#endif #endif
#include <avl_tree.h> #include <avl_tree.h>
@ -59,7 +59,7 @@
#include "system.h" #include "system.h"
#ifndef ETHER_ADDR_LEN #ifndef ETHER_ADDR_LEN
#define ETHER_ADDR_LEN 6 #define ETHER_ADDR_LEN 6
#endif #endif
int routing_mode = RMODE_ROUTER; int routing_mode = RMODE_ROUTER;
@ -67,21 +67,23 @@ int priorityinheritance = 0;
int macexpire = 600; int macexpire = 600;
subnet_t mymac; subnet_t mymac;
void learn_mac(mac_t *address) void learn_mac(mac_t * address)
{ {
subnet_t *subnet; subnet_t *subnet;
avl_node_t *node; avl_node_t *node;
connection_t *c; connection_t *c;
cp(); cp();
subnet = lookup_subnet_mac(address); subnet = lookup_subnet_mac(address);
/* If we don't know this MAC address yet, store it */ /* If we don't know this MAC address yet, store it */
if(!subnet || subnet->owner!=myself) if(!subnet || subnet->owner != myself) {
{
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_INFO, _("Learned new MAC address %hx:%hx:%hx:%hx:%hx:%hx"), syslog(LOG_INFO, _("Learned new MAC address %hx:%hx:%hx:%hx:%hx:%hx"),
address->x[0], address->x[1], address->x[2], address->x[3], address->x[4], address->x[5]); address->x[0], address->x[1], address->x[2], address->x[3],
address->x[4], address->x[5]);
subnet = new_subnet(); subnet = new_subnet();
subnet->type = SUBNET_MAC; subnet->type = SUBNET_MAC;
@ -90,9 +92,8 @@ void learn_mac(mac_t *address)
/* And tell all other tinc daemons it's our MAC */ /* And tell all other tinc daemons it's our MAC */
for(node = connection_tree->head; node; node = node->next) for(node = connection_tree->head; node; node = node->next) {
{ c = (connection_t *) node->data;
c = (connection_t *)node->data;
if(c->status.active) if(c->status.active)
send_add_subnet(c, subnet); send_add_subnet(c, subnet);
} }
@ -106,39 +107,43 @@ void age_mac(void)
subnet_t *s; subnet_t *s;
connection_t *c; connection_t *c;
avl_node_t *node, *next, *node2; avl_node_t *node, *next, *node2;
cp(); cp();
for(node = myself->subnet_tree->head; node; node = next)
{ for(node = myself->subnet_tree->head; node; node = next) {
next = node->next; next = node->next;
s = (subnet_t *)node->data; s = (subnet_t *) node->data;
if(s->type == SUBNET_MAC && s->net.mac.lastseen && s->net.mac.lastseen + macexpire < now) if(s->type == SUBNET_MAC && s->net.mac.lastseen && s->net.mac.lastseen + macexpire < now) {
{
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_INFO, _("MAC address %hx:%hx:%hx:%hx:%hx:%hx expired"), syslog(LOG_INFO, _("MAC address %hx:%hx:%hx:%hx:%hx:%hx expired"),
s->net.mac.address.x[0], s->net.mac.address.x[1], s->net.mac.address.x[2], s->net.mac.address.x[3], s->net.mac.address.x[4], s->net.mac.address.x[5]); s->net.mac.address.x[0], s->net.mac.address.x[1],
for(node2 = connection_tree->head; node2; node2 = node2->next) s->net.mac.address.x[2], s->net.mac.address.x[3],
{ s->net.mac.address.x[4], s->net.mac.address.x[5]);
c = (connection_t *)node2->data;
for(node2 = connection_tree->head; node2; node2 = node2->next) {
c = (connection_t *) node2->data;
if(c->status.active) if(c->status.active)
send_del_subnet(c, s); send_del_subnet(c, s);
} }
subnet_del(myself, s); subnet_del(myself, s);
} }
} }
cp();
} }
node_t *route_mac(vpn_packet_t *packet) node_t *route_mac(vpn_packet_t * packet)
{ {
subnet_t *subnet; subnet_t *subnet;
cp(); cp();
/* Learn source address */ /* Learn source address */
learn_mac((mac_t *)(&packet->data[6])); learn_mac((mac_t *) (&packet->data[6]));
/* Lookup destination address */ /* Lookup destination address */
subnet = lookup_subnet_mac((mac_t *)(&packet->data[0])); subnet = lookup_subnet_mac((mac_t *) (&packet->data[0]));
if(subnet) if(subnet)
return subnet->owner; return subnet->owner;
@ -146,57 +151,58 @@ node_t *route_mac(vpn_packet_t *packet)
return NULL; return NULL;
} }
node_t *route_ipv4(vpn_packet_t *packet) node_t *route_ipv4(vpn_packet_t * packet)
{ {
subnet_t *subnet; subnet_t *subnet;
cp(); cp();
if(priorityinheritance) if(priorityinheritance)
packet->priority = packet->data[15]; packet->priority = packet->data[15];
subnet = lookup_subnet_ipv4((ipv4_t *)&packet->data[30]); subnet = lookup_subnet_ipv4((ipv4_t *) & packet->data[30]);
cp();
if(!subnet) if(!subnet) {
{ if(debug_lvl >= DEBUG_TRAFFIC) {
if(debug_lvl >= DEBUG_TRAFFIC)
{
syslog(LOG_WARNING, _("Cannot route packet: unknown IPv4 destination address %d.%d.%d.%d"), syslog(LOG_WARNING, _("Cannot route packet: unknown IPv4 destination address %d.%d.%d.%d"),
packet->data[30], packet->data[31], packet->data[32], packet->data[33]); packet->data[30], packet->data[31], packet->data[32],
packet->data[33]);
} }
return NULL; return NULL;
} }
cp();
return subnet->owner; return subnet->owner;
} }
node_t *route_ipv6(vpn_packet_t *packet) node_t *route_ipv6(vpn_packet_t * packet)
{ {
subnet_t *subnet; subnet_t *subnet;
cp(); cp();
subnet = lookup_subnet_ipv6((ipv6_t *)&packet->data[38]);
cp(); subnet = lookup_subnet_ipv6((ipv6_t *) & packet->data[38]);
if(!subnet)
{ if(!subnet) {
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC) {
{
syslog(LOG_WARNING, _("Cannot route packet: unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"), syslog(LOG_WARNING, _("Cannot route packet: unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"),
ntohs(*(uint16_t *)&packet->data[38]), ntohs(*(uint16_t *) & packet->data[38]),
ntohs(*(uint16_t *)&packet->data[40]), ntohs(*(uint16_t *) & packet->data[40]),
ntohs(*(uint16_t *)&packet->data[42]), ntohs(*(uint16_t *) & packet->data[42]),
ntohs(*(uint16_t *)&packet->data[44]), ntohs(*(uint16_t *) & packet->data[44]),
ntohs(*(uint16_t *)&packet->data[46]), ntohs(*(uint16_t *) & packet->data[46]),
ntohs(*(uint16_t *)&packet->data[48]), ntohs(*(uint16_t *) & packet->data[48]),
ntohs(*(uint16_t *)&packet->data[50]), ntohs(*(uint16_t *) & packet->data[50]),
ntohs(*(uint16_t *)&packet->data[52])); ntohs(*(uint16_t *) & packet->data[52]));
} }
return NULL; return NULL;
} }
cp();
return subnet->owner; return subnet->owner;
} }
uint16_t inet_checksum(uint16_t *data, int len, uint16_t prevsum) uint16_t inet_checksum(uint16_t * data, int len, uint16_t prevsum)
{ {
uint32_t checksum = prevsum ^ 0xFFFF; uint32_t checksum = prevsum ^ 0xFFFF;
@ -209,7 +215,7 @@ uint16_t inet_checksum(uint16_t *data, int len, uint16_t prevsum)
return checksum ^ 0xFFFF; return checksum ^ 0xFFFF;
} }
void route_neighborsol(vpn_packet_t *packet) void route_neighborsol(vpn_packet_t * packet)
{ {
struct ip6_hdr *hdr; struct ip6_hdr *hdr;
struct nd_neighbor_solicit *ns; struct nd_neighbor_solicit *ns;
@ -225,9 +231,10 @@ void route_neighborsol(vpn_packet_t *packet)
} pseudo; } pseudo;
cp(); cp();
hdr = (struct ip6_hdr *)(packet->data + 14);
ns = (struct nd_neighbor_solicit *)(packet->data + 14 + sizeof(*hdr)); hdr = (struct ip6_hdr *) (packet->data + 14);
opt = (struct nd_opt_hdr *)(packet->data + 14 + sizeof(*hdr) + sizeof(*ns)); ns = (struct nd_neighbor_solicit *) (packet->data + 14 + sizeof(*hdr));
opt = (struct nd_opt_hdr *) (packet->data + 14 + sizeof(*hdr) + sizeof(*ns));
/* First, snatch the source address from the neighbor solicitation packet */ /* First, snatch the source address from the neighbor solicitation packet */
@ -236,10 +243,8 @@ void route_neighborsol(vpn_packet_t *packet)
/* Check if this is a valid neighbor solicitation request */ /* Check if this is a valid neighbor solicitation request */
if(ns->nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT || if(ns->nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT ||
opt->nd_opt_type != ND_OPT_SOURCE_LINKADDR) opt->nd_opt_type != ND_OPT_SOURCE_LINKADDR) {
{ if(debug_lvl > DEBUG_TRAFFIC) {
if(debug_lvl > DEBUG_TRAFFIC)
{
syslog(LOG_WARNING, _("Cannot route packet: received unknown type neighbor solicitation request")); syslog(LOG_WARNING, _("Cannot route packet: received unknown type neighbor solicitation request"));
} }
return; return;
@ -255,11 +260,10 @@ void route_neighborsol(vpn_packet_t *packet)
/* Generate checksum */ /* Generate checksum */
checksum = inet_checksum((uint16_t *)&pseudo, sizeof(pseudo)/2, ~0); checksum = inet_checksum((uint16_t *) & pseudo, sizeof(pseudo) / 2, ~0);
checksum = inet_checksum((uint16_t *)ns, sizeof(*ns)/2 + 4, checksum); checksum = inet_checksum((uint16_t *) ns, sizeof(*ns) / 2 + 4, checksum);
if(checksum) if(checksum) {
{
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_WARNING, _("Cannot route packet: checksum error for neighbor solicitation request")); syslog(LOG_WARNING, _("Cannot route packet: checksum error for neighbor solicitation request"));
return; return;
@ -267,15 +271,19 @@ void route_neighborsol(vpn_packet_t *packet)
/* Check if the IPv6 address exists on the VPN */ /* Check if the IPv6 address exists on the VPN */
subnet = lookup_subnet_ipv6((ipv6_t *)&ns->nd_ns_target); subnet = lookup_subnet_ipv6((ipv6_t *) & ns->nd_ns_target);
if(!subnet) if(!subnet) {
{ if(debug_lvl >= DEBUG_TRAFFIC) {
if(debug_lvl >= DEBUG_TRAFFIC)
{
syslog(LOG_WARNING, _("Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"), syslog(LOG_WARNING, _("Cannot route packet: neighbor solicitation request for unknown address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"),
ntohs(((uint16_t *)&ns->nd_ns_target)[0]), ntohs(((uint16_t *)&ns->nd_ns_target)[1]), ntohs(((uint16_t *)&ns->nd_ns_target)[2]), ntohs(((uint16_t *)&ns->nd_ns_target)[3]), ntohs(((uint16_t *) & ns->nd_ns_target)[0]),
ntohs(((uint16_t *)&ns->nd_ns_target)[4]), ntohs(((uint16_t *)&ns->nd_ns_target)[5]), ntohs(((uint16_t *)&ns->nd_ns_target)[6]), ntohs(((uint16_t *)&ns->nd_ns_target)[7])); ntohs(((uint16_t *) & ns->nd_ns_target)[1]),
ntohs(((uint16_t *) & ns->nd_ns_target)[2]),
ntohs(((uint16_t *) & ns->nd_ns_target)[3]),
ntohs(((uint16_t *) & ns->nd_ns_target)[4]),
ntohs(((uint16_t *) & ns->nd_ns_target)[5]),
ntohs(((uint16_t *) & ns->nd_ns_target)[6]),
ntohs(((uint16_t *) & ns->nd_ns_target)[7]));
} }
return; return;
@ -289,17 +297,19 @@ void route_neighborsol(vpn_packet_t *packet)
/* Create neighbor advertation reply */ /* Create neighbor advertation reply */
memcpy(packet->data, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* copy destination address */ memcpy(packet->data, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* copy destination address */
packet->data[ETHER_ADDR_LEN*2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ packet->data[ETHER_ADDR_LEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
memcpy(&hdr->ip6_dst, &hdr->ip6_src, 16); /* swap destination and source protocol address */ memcpy(&hdr->ip6_dst, &hdr->ip6_src, 16); /* swap destination and source protocol address */
memcpy(&hdr->ip6_src, &ns->nd_ns_target, 16); /* ... */ memcpy(&hdr->ip6_src, &ns->nd_ns_target, 16); /* ... */
memcpy((char *)opt + sizeof(*opt), packet->data + ETHER_ADDR_LEN, 6); /* add fake source hard addr */ memcpy((char *) opt + sizeof(*opt), packet->data + ETHER_ADDR_LEN, 6); /* add fake source hard addr */
ns->nd_ns_hdr.icmp6_cksum = 0; ns->nd_ns_hdr.icmp6_cksum = 0;
ns->nd_ns_hdr.icmp6_type = ND_NEIGHBOR_ADVERT; ns->nd_ns_hdr.icmp6_type = ND_NEIGHBOR_ADVERT;
ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[0] = 0x40; /* Set solicited flag */ ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[0] = 0x40; /* Set solicited flag */
ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[1] = ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[2] = ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[3] = 0; ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[1] =
ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[2] =
ns->nd_ns_hdr.icmp6_dataun.icmp6_un_data8[3] = 0;
opt->nd_opt_type = ND_OPT_TARGET_LINKADDR; opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
/* Create pseudo header */ /* Create pseudo header */
@ -312,21 +322,22 @@ void route_neighborsol(vpn_packet_t *packet)
/* Generate checksum */ /* Generate checksum */
checksum = inet_checksum((uint16_t *)&pseudo, sizeof(pseudo)/2, ~0); checksum = inet_checksum((uint16_t *) & pseudo, sizeof(pseudo) / 2, ~0);
checksum = inet_checksum((uint16_t *)ns, sizeof(*ns)/2 + 4, checksum); checksum = inet_checksum((uint16_t *) ns, sizeof(*ns) / 2 + 4, checksum);
ns->nd_ns_hdr.icmp6_cksum = htons(checksum); ns->nd_ns_hdr.icmp6_cksum = htons(checksum);
write_packet(packet); write_packet(packet);
cp();
} }
void route_arp(vpn_packet_t *packet) void route_arp(vpn_packet_t * packet)
{ {
struct ether_arp *arp; struct ether_arp *arp;
subnet_t *subnet; subnet_t *subnet;
uint8_t ipbuf[4]; uint8_t ipbuf[4];
cp(); cp();
/* First, snatch the source address from the ARP packet */ /* First, snatch the source address from the ARP packet */
memcpy(mymac.net.mac.address.x, packet->data + 6, 6); memcpy(mymac.net.mac.address.x, packet->data + 6, 6);
@ -336,18 +347,13 @@ void route_arp(vpn_packet_t *packet)
Most of the code here is taken from choparp.c by Takamichi Tateoka (tree@mma.club.uec.ac.jp) Most of the code here is taken from choparp.c by Takamichi Tateoka (tree@mma.club.uec.ac.jp)
*/ */
arp = (struct ether_arp *)(packet->data + 14); arp = (struct ether_arp *) (packet->data + 14);
/* Check if this is a valid ARP request */ /* Check if this is a valid ARP request */
if(ntohs(arp->arp_hrd) != ARPHRD_ETHER || if(ntohs(arp->arp_hrd) != ARPHRD_ETHER || ntohs(arp->arp_pro) != ETHERTYPE_IP ||
ntohs(arp->arp_pro) != ETHERTYPE_IP || arp->arp_hln != ETHER_ADDR_LEN || arp->arp_pln != 4 || ntohs(arp->arp_op) != ARPOP_REQUEST) {
arp->arp_hln != ETHER_ADDR_LEN || if(debug_lvl > DEBUG_TRAFFIC) {
arp->arp_pln != 4 ||
ntohs(arp->arp_op) != ARPOP_REQUEST )
{
if(debug_lvl > DEBUG_TRAFFIC)
{
syslog(LOG_WARNING, _("Cannot route packet: received unknown type ARP request")); syslog(LOG_WARNING, _("Cannot route packet: received unknown type ARP request"));
} }
return; return;
@ -355,14 +361,13 @@ void route_arp(vpn_packet_t *packet)
/* Check if the IPv4 address exists on the VPN */ /* Check if the IPv4 address exists on the VPN */
subnet = lookup_subnet_ipv4((ipv4_t *)arp->arp_tpa); subnet = lookup_subnet_ipv4((ipv4_t *) arp->arp_tpa);
if(!subnet) if(!subnet) {
{ if(debug_lvl >= DEBUG_TRAFFIC) {
if(debug_lvl >= DEBUG_TRAFFIC)
{
syslog(LOG_WARNING, _("Cannot route packet: ARP request for unknown address %d.%d.%d.%d"), syslog(LOG_WARNING, _("Cannot route packet: ARP request for unknown address %d.%d.%d.%d"),
arp->arp_tpa[0], arp->arp_tpa[1], arp->arp_tpa[2], arp->arp_tpa[3]); arp->arp_tpa[0], arp->arp_tpa[1], arp->arp_tpa[2],
arp->arp_tpa[3]);
} }
return; return;
@ -374,7 +379,7 @@ void route_arp(vpn_packet_t *packet)
return; /* silently ignore */ return; /* silently ignore */
memcpy(packet->data, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* copy destination address */ memcpy(packet->data, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* copy destination address */
packet->data[ETHER_ADDR_LEN*2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */ packet->data[ETHER_ADDR_LEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
memcpy(ipbuf, arp->arp_tpa, 4); /* save protocol addr */ memcpy(ipbuf, arp->arp_tpa, 4); /* save protocol addr */
memcpy(arp->arp_tpa, arp->arp_spa, 4); /* swap destination and source protocol address */ memcpy(arp->arp_tpa, arp->arp_spa, 4); /* swap destination and source protocol address */
@ -385,41 +390,40 @@ void route_arp(vpn_packet_t *packet)
arp->arp_op = htons(ARPOP_REPLY); arp->arp_op = htons(ARPOP_REPLY);
write_packet(packet); write_packet(packet);
cp();
} }
void route_outgoing(vpn_packet_t *packet) void route_outgoing(vpn_packet_t * packet)
{ {
uint16_t type; uint16_t type;
node_t *n = NULL; node_t *n = NULL;
cp(); cp();
/* FIXME: multicast? */ /* FIXME: multicast? */
switch(routing_mode) switch (routing_mode) {
{
case RMODE_ROUTER: case RMODE_ROUTER:
type = ntohs(*((uint16_t *)(&packet->data[12]))); type = ntohs(*((uint16_t *) (&packet->data[12])));
switch(type) switch (type) {
{
case 0x0800: case 0x0800:
n = route_ipv4(packet); n = route_ipv4(packet);
break; break;
case 0x86DD: case 0x86DD:
if(packet->data[20] == IPPROTO_ICMPV6 && packet->data[54] == ND_NEIGHBOR_SOLICIT) if(packet->data[20] == IPPROTO_ICMPV6 && packet->data[54] == ND_NEIGHBOR_SOLICIT) {
{
route_neighborsol(packet); route_neighborsol(packet);
return; return;
} }
n = route_ipv6(packet); n = route_ipv6(packet);
break; break;
case 0x0806: case 0x0806:
route_arp(packet); route_arp(packet);
return; return;
default: default:
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC)
{
syslog(LOG_WARNING, _("Cannot route packet: unknown type %hx"), type); syslog(LOG_WARNING, _("Cannot route packet: unknown type %hx"), type);
}
return; return;
} }
if(n) if(n)
@ -440,61 +444,57 @@ void route_outgoing(vpn_packet_t *packet)
} }
} }
void route_incoming(node_t *source, vpn_packet_t *packet) void route_incoming(node_t * source, vpn_packet_t * packet)
{ {
switch(routing_mode) switch (routing_mode) {
{
case RMODE_ROUTER: case RMODE_ROUTER:
{ {
node_t *n = NULL; node_t *n = NULL;
uint16_t type; uint16_t type;
type = ntohs(*((uint16_t *)(&packet->data[12]))); type = ntohs(*((uint16_t *) (&packet->data[12])));
switch(type) switch (type) {
{
case 0x0800: case 0x0800:
n = route_ipv4(packet); n = route_ipv4(packet);
break; break;
case 0x86DD: case 0x86DD:
n = route_ipv6(packet); n = route_ipv6(packet);
break; break;
default: default:
n = myself; n = myself;
break; break;
} }
if(n) if(n) {
{ if(n == myself) {
if(n == myself)
{
memcpy(packet->data, mymac.net.mac.address.x, 6); memcpy(packet->data, mymac.net.mac.address.x, 6);
write_packet(packet); write_packet(packet);
} } else
else
send_packet(n, packet); send_packet(n, packet);
} }
} }
break; break;
case RMODE_SWITCH: case RMODE_SWITCH:
{ {
subnet_t *subnet; subnet_t *subnet;
subnet = lookup_subnet_mac((mac_t *)(&packet->data[0])); subnet = lookup_subnet_mac((mac_t *) (&packet->data[0]));
if(subnet) if(subnet) {
{
if(subnet->owner == myself) if(subnet->owner == myself)
write_packet(packet); write_packet(packet);
else else
send_packet(subnet->owner, packet); send_packet(subnet->owner, packet);
} } else {
else
{
broadcast_packet(source, packet); broadcast_packet(source, packet);
write_packet(packet); write_packet(packet);
} }
} }
break; break;
case RMODE_HUB: case RMODE_HUB:
broadcast_packet(source, packet); /* Spread it on */ broadcast_packet(source, packet); /* Spread it on */
write_packet(packet); write_packet(packet);

View file

@ -17,14 +17,13 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: route.h,v 1.1.2.8 2002/06/21 10:11:33 guus Exp $ $Id: route.h,v 1.1.2.9 2002/09/09 21:25:07 guus Exp $
*/ */
#ifndef __TINC_ROUTE_H__ #ifndef __TINC_ROUTE_H__
#define __TINC_ROUTE_H__ #define __TINC_ROUTE_H__
enum enum {
{
RMODE_HUB = 0, RMODE_HUB = 0,
RMODE_SWITCH, RMODE_SWITCH,
RMODE_ROUTER, RMODE_ROUTER,

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: device.c,v 1.1.2.8 2002/06/21 10:11:37 guus Exp $ $Id: device.c,v 1.1.2.9 2002/09/09 21:25:28 guus Exp $
*/ */
@ -65,51 +65,49 @@ int setup_device(void)
int ppa; int ppa;
char *ptr; char *ptr;
cp cp if(!get_config_string(lookup_config(config_tree, "Device"), &device))
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
device = DEFAULT_DEVICE; device = DEFAULT_DEVICE;
cp cp if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0)
{
syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno)); syslog(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno));
return -1; return -1;
} }
cp cp ppa = 0;
ppa = 0;
ptr = device; ptr = device;
while(*ptr && !isdigit((int)*ptr)) ptr++; while(*ptr && !isdigit((int) *ptr))
ptr++;
ppa = atoi(ptr); ppa = atoi(ptr);
if( (ip_fd = open("/dev/ip", O_RDWR, 0)) < 0){ if((ip_fd = open("/dev/ip", O_RDWR, 0)) < 0) {
syslog(LOG_ERR, _("Could not open /dev/ip: %s"), strerror(errno)); syslog(LOG_ERR, _("Could not open /dev/ip: %s"), strerror(errno));
return -1; return -1;
} }
/* Assign a new PPA and get its unit number. */ /* Assign a new PPA and get its unit number. */
if( (ppa = ioctl(device_fd, TUNNEWPPA, ppa)) < 0){ if((ppa = ioctl(device_fd, TUNNEWPPA, ppa)) < 0) {
syslog(LOG_ERR, _("Can't assign new interface: %s"), strerror(errno)); syslog(LOG_ERR, _("Can't assign new interface: %s"), strerror(errno));
return -1; return -1;
} }
if( (if_fd = open(device, O_RDWR, 0)) < 0){ if((if_fd = open(device, O_RDWR, 0)) < 0) {
syslog(LOG_ERR, _("Could not open %s twice: %s"), device, strerror(errno)); syslog(LOG_ERR, _("Could not open %s twice: %s"), device,
strerror(errno));
return -1; return -1;
} }
if(ioctl(if_fd, I_PUSH, "ip") < 0){ if(ioctl(if_fd, I_PUSH, "ip") < 0) {
syslog(LOG_ERR, _("Can't push IP module: %s"), strerror(errno)); syslog(LOG_ERR, _("Can't push IP module: %s"), strerror(errno));
return -1; return -1;
} }
/* Assign ppa according to the unit number returned by tun device */ /* Assign ppa according to the unit number returned by tun device */
if(ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0){ if(ioctl(if_fd, IF_UNITSEL, (char *) &ppa) < 0) {
syslog(LOG_ERR, _("Can't set PPA %d: %s"), ppa, strerror(errno)); syslog(LOG_ERR, _("Can't set PPA %d: %s"), ppa, strerror(errno));
return -1; return -1;
} }
if(ioctl(ip_fd, I_LINK, if_fd) < 0){ if(ioctl(ip_fd, I_LINK, if_fd) < 0) {
syslog(LOG_ERR, _("Can't link TUN device to IP: %s"), strerror(errno)); syslog(LOG_ERR, _("Can't link TUN device to IP: %s"), strerror(errno));
return -1; return -1;
} }
@ -130,23 +128,20 @@ cp
mymac.net.mac.address.x[5] = 0x00; mymac.net.mac.address.x[5] = 0x00;
syslog(LOG_INFO, _("%s is a %s"), device, device_info); syslog(LOG_INFO, _("%s is a %s"), device, device_info);
cp cp return 0;
return 0;
} }
void close_device(void) void close_device(void)
{ {
cp cp close(device_fd);
close(device_fd);
} }
int read_packet(vpn_packet_t *packet) int read_packet(vpn_packet_t * packet)
{ {
int lenin; int lenin;
cp cp if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) {
if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
{ device, strerror(errno));
syslog(LOG_ERR, _("Error while reading from %s %s: %s"), device_info, device, strerror(errno));
return -1; return -1;
} }
@ -159,38 +154,33 @@ cp
device_total_in += packet->len; device_total_in += packet->len;
if(debug_lvl >= DEBUG_TRAFFIC) if(debug_lvl >= DEBUG_TRAFFIC) {
{ syslog(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len,
syslog(LOG_DEBUG, _("Read packet of %d bytes from %s"), packet->len, device_info); device_info);
} }
return 0; return 0;
cp cp}
}
int write_packet(vpn_packet_t *packet) int write_packet(vpn_packet_t * packet)
{ {
cp cp if(debug_lvl >= DEBUG_TRAFFIC)
if(debug_lvl >= DEBUG_TRAFFIC)
syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"), syslog(LOG_DEBUG, _("Writing packet of %d bytes to %s"),
packet->len, device_info); packet->len, device_info);
if(write(device_fd, packet->data + 14, packet->len - 14) < 0) if(write(device_fd, packet->data + 14, packet->len - 14) < 0) {
{ syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, packet->len,
syslog(LOG_ERR, _("Can't write to %s %s: %s"), device_info, packet->len, strerror(errno)); strerror(errno));
return -1; return -1;
} }
device_total_out += packet->len; device_total_out += packet->len;
cp cp return 0;
return 0;
} }
void dump_device_stats(void) void dump_device_stats(void)
{ {
cp cp syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _("Statistics for %s %s:"), device_info, device);
syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in); syslog(LOG_DEBUG, _(" total bytes in: %10d"), device_total_in);
syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out); syslog(LOG_DEBUG, _(" total bytes out: %10d"), device_total_out);
cp cp}
}

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: subnet.c,v 1.1.2.40 2002/09/09 19:40:11 guus Exp $ $Id: subnet.c,v 1.1.2.41 2002/09/09 21:25:10 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -48,10 +48,10 @@ avl_tree_t *subnet_tree;
/* Subnet comparison */ /* Subnet comparison */
int subnet_compare_mac(subnet_t *a, subnet_t *b) int subnet_compare_mac(subnet_t * a, subnet_t * b)
{ {
int result; int result;
cp();
result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof(mac_t)); result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof(mac_t));
if(result || !a->owner || !b->owner) if(result || !a->owner || !b->owner)
@ -60,10 +60,10 @@ int subnet_compare_mac(subnet_t *a, subnet_t *b)
return strcmp(a->owner->name, b->owner->name); return strcmp(a->owner->name, b->owner->name);
} }
int subnet_compare_ipv4(subnet_t *a, subnet_t *b) int subnet_compare_ipv4(subnet_t * a, subnet_t * b)
{ {
int result; int result;
cp();
result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t)); result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t));
if(result) if(result)
@ -77,10 +77,10 @@ int subnet_compare_ipv4(subnet_t *a, subnet_t *b)
return strcmp(a->owner->name, b->owner->name); return strcmp(a->owner->name, b->owner->name);
} }
int subnet_compare_ipv6(subnet_t *a, subnet_t *b) int subnet_compare_ipv6(subnet_t * a, subnet_t * b)
{ {
int result; int result;
cp();
result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t)); result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t));
if(result) if(result)
@ -94,17 +94,16 @@ int subnet_compare_ipv6(subnet_t *a, subnet_t *b)
return strcmp(a->owner->name, b->owner->name); return strcmp(a->owner->name, b->owner->name);
} }
int subnet_compare(subnet_t *a, subnet_t *b) int subnet_compare(subnet_t * a, subnet_t * b)
{ {
int result; int result;
cp();
result = a->type - b->type; result = a->type - b->type;
if(result) if(result)
return result; return result;
switch(a->type) switch (a->type) {
{
case SUBNET_MAC: case SUBNET_MAC:
return subnet_compare_mac(a, b); return subnet_compare_mac(a, b);
case SUBNET_IPV4: case SUBNET_IPV4:
@ -112,7 +111,10 @@ int subnet_compare(subnet_t *a, subnet_t *b)
case SUBNET_IPV6: case SUBNET_IPV6:
return subnet_compare_ipv6(a, b); return subnet_compare_ipv6(a, b);
default: default:
syslog(LOG_ERR, _("subnet_compare() was called with unknown subnet type %d, exitting!"), a->type); syslog(LOG_ERR,
_
("subnet_compare() was called with unknown subnet type %d, exitting!"),
a->type);
cp_trace(); cp_trace();
exit(0); exit(0);
} }
@ -125,29 +127,29 @@ int subnet_compare(subnet_t *a, subnet_t *b)
void init_subnets(void) void init_subnets(void)
{ {
cp(); cp();
subnet_tree = avl_alloc_tree((avl_compare_t)subnet_compare, (avl_action_t)free_subnet);
cp(); subnet_tree = avl_alloc_tree((avl_compare_t) subnet_compare, (avl_action_t) free_subnet);
} }
void exit_subnets(void) void exit_subnets(void)
{ {
cp(); cp();
avl_delete_tree(subnet_tree); avl_delete_tree(subnet_tree);
cp();
} }
avl_tree_t *new_subnet_tree(void) avl_tree_t *new_subnet_tree(void)
{ {
cp(); cp();
return avl_alloc_tree((avl_compare_t)subnet_compare, NULL);
cp(); return avl_alloc_tree((avl_compare_t) subnet_compare, NULL);
} }
void free_subnet_tree(avl_tree_t *subnet_tree) void free_subnet_tree(avl_tree_t * subnet_tree)
{ {
cp(); cp();
avl_delete_tree(subnet_tree); avl_delete_tree(subnet_tree);
cp();
} }
/* Allocating and freeing space for subnets */ /* Allocating and freeing space for subnets */
@ -155,35 +157,35 @@ void free_subnet_tree(avl_tree_t *subnet_tree)
subnet_t *new_subnet(void) subnet_t *new_subnet(void)
{ {
cp(); cp();
return (subnet_t *)xmalloc_and_zero(sizeof(subnet_t));
return (subnet_t *) xmalloc_and_zero(sizeof(subnet_t));
} }
void free_subnet(subnet_t *subnet) void free_subnet(subnet_t * subnet)
{ {
cp(); cp();
free(subnet); free(subnet);
} }
/* Adding and removing subnets */ /* Adding and removing subnets */
void subnet_add(node_t *n, subnet_t *subnet) void subnet_add(node_t * n, subnet_t * subnet)
{ {
cp(); cp();
subnet->owner = n; subnet->owner = n;
avl_insert(subnet_tree, subnet); avl_insert(subnet_tree, subnet);
cp();
avl_insert(n->subnet_tree, subnet); avl_insert(n->subnet_tree, subnet);
cp();
} }
void subnet_del(node_t *n, subnet_t *subnet) void subnet_del(node_t * n, subnet_t * subnet)
{ {
cp(); cp();
avl_delete(n->subnet_tree, subnet); avl_delete(n->subnet_tree, subnet);
cp();
avl_delete(subnet_tree, subnet); avl_delete(subnet_tree, subnet);
cp();
} }
/* Ascii representation of subnets */ /* Ascii representation of subnets */
@ -193,87 +195,94 @@ subnet_t *str2net(char *subnetstr)
int i, l; int i, l;
subnet_t *subnet; subnet_t *subnet;
uint16_t x[8]; uint16_t x[8];
cp(); cp();
subnet = new_subnet(); subnet = new_subnet();
cp();
if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d", if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d",
&x[0], &x[1], &x[2], &x[3], &x[0], &x[1], &x[2], &x[3], &l) == 5) {
&l) == 5)
{
subnet->type = SUBNET_IPV4; subnet->type = SUBNET_IPV4;
subnet->net.ipv4.prefixlength = l; subnet->net.ipv4.prefixlength = l;
for(i = 0; i < 4; i++) for(i = 0; i < 4; i++)
subnet->net.ipv4.address.x[i] = x[i]; subnet->net.ipv4.address.x[i] = x[i];
return subnet; return subnet;
} }
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d", 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], &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
&l) == 9) &l) == 9) {
{
subnet->type = SUBNET_IPV6; subnet->type = SUBNET_IPV6;
subnet->net.ipv6.prefixlength = l; subnet->net.ipv6.prefixlength = l;
for(i = 0; i < 8; i++) for(i = 0; i < 8; i++)
subnet->net.ipv6.address.x[i] = htons(x[i]); subnet->net.ipv6.address.x[i] = htons(x[i]);
return subnet; return subnet;
} }
if(sscanf(subnetstr, "%hu.%hu.%hu.%hu", if(sscanf(subnetstr, "%hu.%hu.%hu.%hu", &x[0], &x[1], &x[2], &x[3]) == 4) {
&x[0], &x[1], &x[2], &x[3]) == 4)
{
subnet->type = SUBNET_IPV4; subnet->type = SUBNET_IPV4;
subnet->net.ipv4.prefixlength = 32; subnet->net.ipv4.prefixlength = 32;
for(i = 0; i < 4; i++) for(i = 0; i < 4; i++)
subnet->net.ipv4.address.x[i] = x[i]; subnet->net.ipv4.address.x[i] = x[i];
return subnet; return subnet;
} }
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", 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) &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7]) == 8) {
{
subnet->type = SUBNET_IPV6; subnet->type = SUBNET_IPV6;
subnet->net.ipv6.prefixlength = 128; subnet->net.ipv6.prefixlength = 128;
for(i = 0; i < 8; i++) for(i = 0; i < 8; i++)
subnet->net.ipv6.address.x[i] = htons(x[i]); subnet->net.ipv6.address.x[i] = htons(x[i]);
return subnet; return subnet;
} }
if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx", if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx",
&x[0], &x[1], &x[2], &x[3], &x[4], &x[5]) == 6) &x[0], &x[1], &x[2], &x[3], &x[4], &x[5]) == 6) {
{
subnet->type = SUBNET_MAC; subnet->type = SUBNET_MAC;
for(i = 0; i < 6; i++) for(i = 0; i < 6; i++)
subnet->net.mac.address.x[i] = x[i]; subnet->net.mac.address.x[i] = x[i];
return subnet; return subnet;
} }
free(subnet); free(subnet);
return NULL; return NULL;
} }
char *net2str(subnet_t *subnet) char *net2str(subnet_t * subnet)
{ {
char *netstr; char *netstr;
cp(); cp();
switch(subnet->type)
{ switch (subnet->type) {
case SUBNET_MAC: case SUBNET_MAC:
asprintf(&netstr, "%hx:%hx:%hx:%hx:%hx:%hx", asprintf(&netstr, "%hx:%hx:%hx:%hx:%hx:%hx",
subnet->net.mac.address.x[0], subnet->net.mac.address.x[0],
subnet->net.mac.address.x[1], subnet->net.mac.address.x[1],
subnet->net.mac.address.x[2], subnet->net.mac.address.x[2],
subnet->net.mac.address.x[3], subnet->net.mac.address.x[3],
subnet->net.mac.address.x[4], subnet->net.mac.address.x[4], subnet->net.mac.address.x[5]);
subnet->net.mac.address.x[5]);
break; break;
case SUBNET_IPV4: case SUBNET_IPV4:
asprintf(&netstr, "%hu.%hu.%hu.%hu/%d", asprintf(&netstr, "%hu.%hu.%hu.%hu/%d",
subnet->net.ipv4.address.x[0], subnet->net.ipv4.address.x[0],
subnet->net.ipv4.address.x[1], subnet->net.ipv4.address.x[1],
subnet->net.ipv4.address.x[2], subnet->net.ipv4.address.x[2],
subnet->net.ipv4.address.x[3], subnet->net.ipv4.address.x[3], subnet->net.ipv4.prefixlength);
subnet->net.ipv4.prefixlength);
break; break;
case SUBNET_IPV6: case SUBNET_IPV6:
asprintf(&netstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d", asprintf(&netstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d",
ntohs(subnet->net.ipv6.address.x[0]), ntohs(subnet->net.ipv6.address.x[0]),
@ -286,111 +295,113 @@ char *net2str(subnet_t *subnet)
ntohs(subnet->net.ipv6.address.x[7]), ntohs(subnet->net.ipv6.address.x[7]),
subnet->net.ipv6.prefixlength); subnet->net.ipv6.prefixlength);
break; break;
default: default:
syslog(LOG_ERR, _("net2str() was called with unknown subnet type %d, exiting!"), subnet->type); syslog(LOG_ERR,
_("net2str() was called with unknown subnet type %d, exiting!"),
subnet->type);
cp_trace(); cp_trace();
exit(0); exit(0);
} }
cp();
return netstr; return netstr;
} }
/* Subnet lookup routines */ /* Subnet lookup routines */
subnet_t *lookup_subnet(node_t *owner, subnet_t *subnet) subnet_t *lookup_subnet(node_t * owner, subnet_t * subnet)
{ {
cp(); cp();
return avl_search(owner->subnet_tree, subnet); return avl_search(owner->subnet_tree, subnet);
} }
subnet_t *lookup_subnet_mac(mac_t *address) subnet_t *lookup_subnet_mac(mac_t * address)
{ {
subnet_t subnet, *p; subnet_t subnet, *p;
cp(); cp();
subnet.type = SUBNET_MAC; subnet.type = SUBNET_MAC;
memcpy(&subnet.net.mac.address, address, sizeof(mac_t)); memcpy(&subnet.net.mac.address, address, sizeof(mac_t));
subnet.owner = NULL; subnet.owner = NULL;
p = (subnet_t *)avl_search(subnet_tree, &subnet); p = (subnet_t *) avl_search(subnet_tree, &subnet);
cp();
return p; return p;
} }
subnet_t *lookup_subnet_ipv4(ipv4_t *address) subnet_t *lookup_subnet_ipv4(ipv4_t * address)
{ {
subnet_t subnet, *p; subnet_t subnet, *p;
cp(); cp();
subnet.type = SUBNET_IPV4; subnet.type = SUBNET_IPV4;
memcpy(&subnet.net.ipv4.address, address, sizeof(ipv4_t)); memcpy(&subnet.net.ipv4.address, address, sizeof(ipv4_t));
subnet.net.ipv4.prefixlength = 32; subnet.net.ipv4.prefixlength = 32;
subnet.owner = NULL; subnet.owner = NULL;
do do {
{
/* Go find subnet */ /* Go find subnet */
p = (subnet_t *)avl_search_closest_smaller(subnet_tree, &subnet); p = (subnet_t *) avl_search_closest_smaller(subnet_tree, &subnet);
/* Check if the found subnet REALLY matches */ /* Check if the found subnet REALLY matches */
cp();
if(p) if(p) {
{ if(p->type != SUBNET_IPV4) {
if(p->type != SUBNET_IPV4)
{
p = NULL; p = NULL;
break; break;
} }
if (!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength, sizeof(ipv4_t))) if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength, sizeof(ipv4_t)))
break; break;
else else {
{
/* Otherwise, see if there is a bigger enclosing subnet */ /* Otherwise, see if there is a bigger enclosing subnet */
subnet.net.ipv4.prefixlength = p->net.ipv4.prefixlength - 1; subnet.net.ipv4.prefixlength = p->net.ipv4.prefixlength - 1;
maskcpy(&subnet.net.ipv4.address, &p->net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(ipv4_t)); maskcpy(&subnet.net.ipv4.address, &p->net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(ipv4_t));
} }
} }
} while (p); } while(p);
cp();
return p; return p;
} }
subnet_t *lookup_subnet_ipv6(ipv6_t *address) subnet_t *lookup_subnet_ipv6(ipv6_t * address)
{ {
subnet_t subnet, *p; subnet_t subnet, *p;
cp(); cp();
subnet.type = SUBNET_IPV6; subnet.type = SUBNET_IPV6;
memcpy(&subnet.net.ipv6.address, address, sizeof(ipv6_t)); memcpy(&subnet.net.ipv6.address, address, sizeof(ipv6_t));
subnet.net.ipv6.prefixlength = 128; subnet.net.ipv6.prefixlength = 128;
subnet.owner = NULL; subnet.owner = NULL;
do do {
{
/* Go find subnet */ /* Go find subnet */
p = (subnet_t *)avl_search_closest_smaller(subnet_tree, &subnet); p = (subnet_t *) avl_search_closest_smaller(subnet_tree, &subnet);
/* Check if the found subnet REALLY matches */ /* Check if the found subnet REALLY matches */
cp(); if(p) {
if(p)
{
if(p->type != SUBNET_IPV6) if(p->type != SUBNET_IPV6)
return NULL; return NULL;
if (!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength, sizeof(ipv6_t))) if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength, sizeof(ipv6_t)))
break; break;
else else {
{
/* Otherwise, see if there is a bigger enclosing subnet */ /* Otherwise, see if there is a bigger enclosing subnet */
subnet.net.ipv6.prefixlength = p->net.ipv6.prefixlength - 1; subnet.net.ipv6.prefixlength = p->net.ipv6.prefixlength - 1;
maskcpy(&subnet.net.ipv6.address, &p->net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(ipv6_t)); maskcpy(&subnet.net.ipv6.address, &p->net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(ipv6_t));
} }
} }
} while (p); } while(p);
cp();
return p; return p;
} }
@ -399,15 +410,17 @@ void dump_subnets(void)
char *netstr; char *netstr;
subnet_t *subnet; subnet_t *subnet;
avl_node_t *node; avl_node_t *node;
cp(); cp();
syslog(LOG_DEBUG, _("Subnet list:")); syslog(LOG_DEBUG, _("Subnet list:"));
for(node = subnet_tree->head; node; node = node->next)
{ for(node = subnet_tree->head; node; node = node->next) {
subnet = (subnet_t *)node->data; subnet = (subnet_t *) node->data;
netstr = net2str(subnet); netstr = net2str(subnet);
syslog(LOG_DEBUG, _(" %s owner %s"), netstr, subnet->owner->name); syslog(LOG_DEBUG, _(" %s owner %s"), netstr, subnet->owner->name);
free(netstr); free(netstr);
} }
syslog(LOG_DEBUG, _("End of subnet list.")); syslog(LOG_DEBUG, _("End of subnet list."));
cp();
} }

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: subnet.h,v 1.1.2.19 2002/06/21 10:11:34 guus Exp $ $Id: subnet.h,v 1.1.2.20 2002/09/09 21:25:16 guus Exp $
*/ */
#ifndef __TINC_SUBNET_H__ #ifndef __TINC_SUBNET_H__
@ -25,28 +25,24 @@
#include "net.h" #include "net.h"
enum enum {
{
SUBNET_MAC = 0, SUBNET_MAC = 0,
SUBNET_IPV4, SUBNET_IPV4,
SUBNET_IPV6, SUBNET_IPV6,
SUBNET_TYPES /* Guardian */ SUBNET_TYPES /* Guardian */
}; };
typedef struct subnet_mac_t typedef struct subnet_mac_t {
{
mac_t address; mac_t address;
time_t lastseen; time_t lastseen;
} subnet_mac_t; } subnet_mac_t;
typedef struct subnet_ipv4_t typedef struct subnet_ipv4_t {
{
ipv4_t address; ipv4_t address;
int prefixlength; int prefixlength;
} subnet_ipv4_t; } subnet_ipv4_t;
typedef struct subnet_ipv6_t typedef struct subnet_ipv6_t {
{
ipv6_t address; ipv6_t address;
int prefixlength; int prefixlength;
} subnet_ipv6_t; } subnet_ipv6_t;
@ -61,8 +57,7 @@ typedef struct subnet_t {
/* And now for the actual subnet: */ /* And now for the actual subnet: */
union net union net {
{
subnet_mac_t mac; subnet_mac_t mac;
subnet_ipv4_t ipv4; subnet_ipv4_t ipv4;
subnet_ipv6_t ipv6; subnet_ipv6_t ipv6;

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: tincd.c,v 1.10.4.62 2002/09/09 19:40:12 guus Exp $ $Id: tincd.c,v 1.10.4.63 2002/09/09 21:25:16 guus Exp $
*/ */
#include "config.h" #include "config.h"
@ -83,30 +83,29 @@ char **g_argv; /* a copy of the cmdline arguments */
char **environment; /* A pointer to the environment on char **environment; /* A pointer to the environment on
startup */ startup */
static struct option const long_options[] = static struct option const long_options[] = {
{ {"config", required_argument, NULL, 'c'},
{ "config", required_argument, NULL, 'c' }, {"kill", optional_argument, NULL, 'k'},
{ "kill", optional_argument, NULL, 'k' }, {"net", required_argument, NULL, 'n'},
{ "net", required_argument, NULL, 'n' }, {"help", no_argument, &show_help, 1},
{ "help", no_argument, &show_help, 1 }, {"version", no_argument, &show_version, 1},
{ "version", no_argument, &show_version, 1 }, {"no-detach", no_argument, &do_detach, 0},
{ "no-detach", no_argument, &do_detach, 0 }, {"generate-keys", optional_argument, NULL, 'K'},
{ "generate-keys", optional_argument, NULL, 'K'}, {"debug", optional_argument, NULL, 'd'},
{ "debug", optional_argument, NULL, 'd'}, {"bypass-security", no_argument, &bypass_security, 1},
{ "bypass-security", no_argument, &bypass_security, 1 }, {"mlock", no_argument, &do_mlock, 1},
{ "mlock", no_argument, &do_mlock, 1}, {NULL, 0, NULL, 0}
{ NULL, 0, NULL, 0 }
}; };
static void static void usage(int status)
usage(int status)
{ {
if(status != 0) if(status != 0)
fprintf(stderr, _("Try `%s --help\' for more information.\n"), program_name); fprintf(stderr, _("Try `%s --help\' for more information.\n"),
else program_name);
{ else {
printf(_("Usage: %s [option]...\n\n"), program_name); printf(_("Usage: %s [option]...\n\n"), program_name);
printf(_(" -c, --config=DIR Read configuration options from DIR.\n" printf(_
(" -c, --config=DIR Read configuration options from DIR.\n"
" -D, --no-detach Don't fork and detach.\n" " -D, --no-detach Don't fork and detach.\n"
" -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n" " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n"
" -k, --kill[=SIGNAL] Attempt to kill a running tincd and exit.\n" " -k, --kill[=SIGNAL] Attempt to kill a running tincd and exit.\n"
@ -117,40 +116,42 @@ usage(int status)
" --version Output version information and exit.\n\n")); " --version Output version information and exit.\n\n"));
printf(_("Report bugs to tinc@nl.linux.org.\n")); printf(_("Report bugs to tinc@nl.linux.org.\n"));
} }
exit(status); exit(status);
} }
void void parse_options(int argc, char **argv, char **envp)
parse_options(int argc, char **argv, char **envp)
{ {
int r; int r;
int option_index = 0; int option_index = 0;
while((r = getopt_long(argc, argv, "c:DLd::k::n:K::", long_options, &option_index)) != EOF) while((r = getopt_long(argc, argv, "c:DLd::k::n:K::", long_options, &option_index)) != EOF) {
{ switch (r) {
switch(r)
{
case 0: /* long option */ case 0: /* long option */
break; break;
case 'c': /* config file */ case 'c': /* config file */
confbase = xmalloc(strlen(optarg)+1); confbase = xmalloc(strlen(optarg) + 1);
strcpy(confbase, optarg); strcpy(confbase, optarg);
break; break;
case 'D': /* no detach */ case 'D': /* no detach */
do_detach = 0; do_detach = 0;
break; break;
case 'L': /* no detach */ case 'L': /* no detach */
do_mlock = 1; do_mlock = 1;
break; break;
case 'd': /* inc debug level */ case 'd': /* inc debug level */
if(optarg) if(optarg)
debug_lvl = atoi(optarg); debug_lvl = atoi(optarg);
else else
debug_lvl++; debug_lvl++;
break; break;
case 'k': /* kill old tincds */ case 'k': /* kill old tincds */
if(optarg) if(optarg) {
{
if(!strcasecmp(optarg, "HUP")) if(!strcasecmp(optarg, "HUP"))
kill_tincd = SIGHUP; kill_tincd = SIGHUP;
else if(!strcasecmp(optarg, "TERM")) else if(!strcasecmp(optarg, "TERM"))
@ -167,40 +168,46 @@ parse_options(int argc, char **argv, char **envp)
kill_tincd = SIGINT; kill_tincd = SIGINT;
else if(!strcasecmp(optarg, "ALRM")) else if(!strcasecmp(optarg, "ALRM"))
kill_tincd = SIGALRM; kill_tincd = SIGALRM;
else else {
{
kill_tincd = atoi(optarg); kill_tincd = atoi(optarg);
if(!kill_tincd)
{ if(!kill_tincd) {
fprintf(stderr, _("Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n"), optarg); fprintf(stderr,
usage(1); _
} ("Invalid argument `%s'; SIGNAL must be a number or one of HUP, TERM, KILL, USR1, USR2, WINCH, INT or ALRM.\n"),
}
}
else
kill_tincd = SIGTERM;
break;
case 'n': /* net name given */
netname = xmalloc(strlen(optarg)+1);
strcpy(netname, optarg);
break;
case 'K': /* generate public/private keypair */
if(optarg)
{
generate_keys = atoi(optarg);
if(generate_keys < 512)
{
fprintf(stderr, _("Invalid argument `%s'; BITS must be a number equal to or greater than 512.\n"),
optarg); optarg);
usage(1); usage(1);
} }
generate_keys &= ~7; /* Round it to bytes */
} }
else } else
kill_tincd = SIGTERM;
break;
case 'n': /* net name given */
netname = xmalloc(strlen(optarg) + 1);
strcpy(netname, optarg);
break;
case 'K': /* generate public/private keypair */
if(optarg) {
generate_keys = atoi(optarg);
if(generate_keys < 512) {
fprintf(stderr,
_
("Invalid argument `%s'; BITS must be a number equal to or greater than 512.\n"),
optarg);
usage(1);
}
generate_keys &= ~7; /* Round it to bytes */
} else
generate_keys = 1024; generate_keys = 1024;
break; break;
case '?': case '?':
usage(1); usage(1);
default: default:
break; break;
} }
@ -211,30 +218,34 @@ parse_options(int argc, char **argv, char **envp)
void indicator(int a, int b, void *p) void indicator(int a, int b, void *p)
{ {
switch(a) switch (a) {
{
case 0: case 0:
fprintf(stderr, "."); fprintf(stderr, ".");
break; break;
case 1: case 1:
fprintf(stderr, "+"); fprintf(stderr, "+");
break; break;
case 2: case 2:
fprintf(stderr, "-"); fprintf(stderr, "-");
break; break;
case 3: case 3:
switch(b) switch (b) {
{
case 0: case 0:
fprintf(stderr, " p\n"); fprintf(stderr, " p\n");
break; break;
case 1: case 1:
fprintf(stderr, " q\n"); fprintf(stderr, " q\n");
break; break;
default: default:
fprintf(stderr, "?"); fprintf(stderr, "?");
} }
break; break;
default: default:
fprintf(stderr, "?"); fprintf(stderr, "?");
} }
@ -254,12 +265,10 @@ int keygen(int bits)
fprintf(stderr, _("Generating %d bits keys:\n"), bits); fprintf(stderr, _("Generating %d bits keys:\n"), bits);
rsa_key = RSA_generate_key(bits, 0xFFFF, indicator, NULL); rsa_key = RSA_generate_key(bits, 0xFFFF, indicator, NULL);
if(!rsa_key) if(!rsa_key) {
{
fprintf(stderr, _("Error during key generation!\n")); fprintf(stderr, _("Error during key generation!\n"));
return -1; return -1;
} } else
else
fprintf(stderr, _("Done.\n")); fprintf(stderr, _("Done.\n"));
get_config_string(lookup_config(config_tree, "Name"), &name); get_config_string(lookup_config(config_tree, "Name"), &name);
@ -302,43 +311,43 @@ int keygen(int bits)
*/ */
void make_names(void) void make_names(void)
{ {
if(netname) if(netname) {
{
if(!pidfilename) if(!pidfilename)
asprintf(&pidfilename, LOCALSTATEDIR "/run/tinc.%s.pid", netname); asprintf(&pidfilename, LOCALSTATEDIR "/run/tinc.%s.pid", netname);
if(!confbase) if(!confbase)
asprintf(&confbase, "%s/tinc/%s", CONFDIR, netname); asprintf(&confbase, "%s/tinc/%s", CONFDIR, netname);
else else
syslog(LOG_INFO, _("Both netname and configuration directory given, using the latter...")); syslog(LOG_INFO, _("Both netname and configuration directory given, using the latter..."));
if(!identname) if(!identname)
asprintf(&identname, "tinc.%s", netname); asprintf(&identname, "tinc.%s", netname);
} } else {
else
{
if(!pidfilename) if(!pidfilename)
pidfilename = LOCALSTATEDIR "/run/tinc.pid"; pidfilename = LOCALSTATEDIR "/run/tinc.pid";
if(!confbase) if(!confbase)
asprintf(&confbase, "%s/tinc", CONFDIR); asprintf(&confbase, "%s/tinc", CONFDIR);
if(!identname) if(!identname)
identname = "tinc"; identname = "tinc";
} }
} }
int int main(int argc, char **argv, char **envp)
main(int argc, char **argv, char **envp)
{ {
program_name = argv[0]; program_name = argv[0];
setlocale (LC_ALL, ""); setlocale(LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR); bindtextdomain(PACKAGE, LOCALEDIR);
textdomain (PACKAGE); textdomain(PACKAGE);
environment = envp; environment = envp;
parse_options(argc, argv, envp); parse_options(argc, argv, envp);
if(show_version) if(show_version) {
{ printf(_("%s version %s (built %s %s, protocol %d)\n"), PACKAGE,
printf(_("%s version %s (built %s %s, protocol %d)\n"), PACKAGE, VERSION, __DATE__, __TIME__, PROT_CURRENT); VERSION, __DATE__, __TIME__, PROT_CURRENT);
printf(_("Copyright (C) 1998-2002 Ivo Timmermans, Guus Sliepen and others.\n" printf(_("Copyright (C) 1998-2002 Ivo Timmermans, Guus Sliepen and others.\n"
"See the AUTHORS file for a complete list.\n\n" "See the AUTHORS file for a complete list.\n\n"
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
@ -361,9 +370,9 @@ main(int argc, char **argv, char **envp)
if(do_mlock) if(do_mlock)
#ifdef HAVE_MLOCKALL #ifdef HAVE_MLOCKALL
if(mlockall(MCL_CURRENT | MCL_FUTURE)) if(mlockall(MCL_CURRENT | MCL_FUTURE)) {
{ syslog(LOG_ERR, _("System call `%s' failed: %s"), "mlockall",
syslog(LOG_ERR, _("System call `%s' failed: %s"), "mlockall", strerror(errno)); strerror(errno));
#else #else
{ {
syslog(LOG_ERR, _("mlockall() not supported on this platform!")); syslog(LOG_ERR, _("mlockall() not supported on this platform!"));
@ -377,7 +386,7 @@ main(int argc, char **argv, char **envp)
init_configuration(&config_tree); init_configuration(&config_tree);
/* Slllluuuuuuurrrrp! */ /* Slllluuuuuuurrrrp! */
cp();
RAND_load_file("/dev/urandom", 1024); RAND_load_file("/dev/urandom", 1024);
#ifdef HAVE_SSLEAY_ADD_ALL_ALGORITHMS #ifdef HAVE_SSLEAY_ADD_ALL_ALGORITHMS
@ -386,9 +395,7 @@ main(int argc, char **argv, char **envp)
OpenSSL_add_all_algorithms(); OpenSSL_add_all_algorithms();
#endif #endif
cp(); if(generate_keys) {
if(generate_keys)
{
read_server_config(); read_server_config();
exit(keygen(generate_keys)); exit(keygen(generate_keys));
} }
@ -398,14 +405,12 @@ main(int argc, char **argv, char **envp)
if(read_server_config()) if(read_server_config())
exit(1); exit(1);
cp();
if(detach()) if(detach())
exit(0); exit(0);
cp();
for(;;) for(;;) {
{ if(!setup_network_connections()) {
if(!setup_network_connections())
{
main_loop(); main_loop();
cleanup_and_exit(1); cleanup_and_exit(1);
} }
@ -413,13 +418,10 @@ main(int argc, char **argv, char **envp)
syslog(LOG_ERR, _("Unrecoverable error")); syslog(LOG_ERR, _("Unrecoverable error"));
cp_trace(); cp_trace();
if(do_detach) if(do_detach) {
{
syslog(LOG_NOTICE, _("Restarting in %d seconds!"), maxtimeout); syslog(LOG_NOTICE, _("Restarting in %d seconds!"), maxtimeout);
sleep(maxtimeout); sleep(maxtimeout);
} } else {
else
{
syslog(LOG_ERR, _("Not restarting.")); syslog(LOG_ERR, _("Not restarting."));
exit(1); exit(1);
} }