]> git.meshlink.io Git - meshlink/commitdiff
Remove support for Subnets.
authorGuus Sliepen <guus@meshlink.io>
Sat, 12 Apr 2014 11:24:43 +0000 (13:24 +0200)
committerGuus Sliepen <guus@meshlink.io>
Sat, 12 Apr 2014 11:24:43 +0000 (13:24 +0200)
21 files changed:
src/Makefile.am
src/conf.c
src/conf.h
src/connection.c
src/control.c
src/graph.c
src/libmeshlink.c
src/net.c
src/net_setup.c
src/node.c
src/node.h
src/process.c
src/protocol.c
src/protocol.h
src/protocol_auth.c
src/protocol_subnet.c [deleted file]
src/route.c
src/script.c
src/subnet.c [deleted file]
src/subnet.h [deleted file]
src/subnet_parse.c [deleted file]

index fab950898e554a590d433f40d2f284adb76c7d3b..1cb2b6ac49f79663b73e2c6443971051159440ae 100644 (file)
@@ -66,15 +66,12 @@ libmeshlink_la_SOURCES = \
        protocol_edge.c \
        protocol_key.c \
        protocol_misc.c \
-       protocol_subnet.c \
        route.c route.h \
        rsa.h \
        rsagen.h \
        script.c script.h \
        splay_tree.c splay_tree.h \
        sptps.c sptps.h \
-       subnet.c subnet.h \
-       subnet_parse.c \
        system.h \
        tincd.c \
        utils.c utils.h \
index 95c07477da9c8575825d34718febb30c3b333f15..836c00e4fe797ee21d8ba8adba295f0d0a9e9cdb 100644 (file)
@@ -187,34 +187,6 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result) {
        return false;
 }
 
-bool get_config_subnet(const config_t *cfg, subnet_t ** result) {
-       subnet_t subnet = {NULL};
-
-       if(!cfg)
-               return false;
-
-       if(!str2net(&subnet, cfg->value)) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Subnet expected for configuration variable %s in %s line %d",
-                          cfg->variable, cfg->file, cfg->line);
-               return false;
-       }
-
-       /* Teach newbies what subnets are... */
-
-       if(((subnet.type == SUBNET_IPV4)
-               && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof subnet.net.ipv4.address))
-               || ((subnet.type == SUBNET_IPV6)
-               && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof subnet.net.ipv6.address))) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Network address and prefix length do not match for configuration variable %s in %s line %d",
-                          cfg->variable, cfg->file, cfg->line);
-               return false;
-       }
-
-       *(*result = new_subnet()) = subnet;
-
-       return true;
-}
-
 /*
   Read exactly one line and strip the trailing newline if any.
 */
index 4f39b20ac9133dcfd3fc03dd3598ee17012c4e4d..17dcc5955538df01095aa40b6f851c2c28da5118 100644 (file)
@@ -31,8 +31,6 @@ typedef struct config_t {
        int line;
 } config_t;
 
-#include "subnet.h"
-
 extern splay_tree_t *config_tree;
 
 extern int pinginterval;
@@ -52,7 +50,6 @@ extern bool get_config_bool(const config_t *, bool *);
 extern bool get_config_int(const config_t *, int *);
 extern bool get_config_string(const config_t *, char **);
 extern bool get_config_address(const config_t *, struct addrinfo **);
-extern bool get_config_subnet(const config_t *, struct subnet_t **);
 
 extern config_t *parse_config_line(char *, const char *, int);
 extern bool read_config_file(splay_tree_t *, const char *);
index 496f6747fc05a738709f10e8c3783300c2685074..6f9d9809399ce0de832b3e1aeae6386ef3da8fab 100644 (file)
@@ -28,7 +28,6 @@
 #include "list.h"
 #include "logger.h"
 #include "rsa.h"
-#include "subnet.h"
 #include "utils.h"
 #include "xalloc.h"
 
index 456274956dd3d07883b1c3dee24b84bc796e79a2..0a8ca9b9f8540ff21a69cc73c053bb4bc342c871 100644 (file)
@@ -67,9 +67,6 @@ bool control_h(connection_t *c, const char *request) {
                case REQ_DUMP_EDGES:
                        return dump_edges(c);
 
-               case REQ_DUMP_SUBNETS:
-                       return dump_subnets(c);
-
                case REQ_DUMP_CONNECTIONS:
                        return dump_connections(c);
 
index 75996eacdd26a8539fecc9166137822d495fdc2f..b7ace49756efe0c51df5f025e301362d6a3fd63e 100644 (file)
@@ -54,7 +54,6 @@
 #include "node.h"
 #include "protocol.h"
 #include "script.h"
-#include "subnet.h"
 #include "utils.h"
 #include "xalloc.h"
 #include "graph.h"
@@ -255,8 +254,6 @@ static void check_reachability(void) {
                        for(int i = 0; i < 7; i++)
                                free(envp[i]);
 
-                       subnet_update(n, NULL, n->status.reachable);
-
                        if(!n->status.reachable) {
                                update_node_udp(n, NULL);
                                memset(&n->status, 0, sizeof n->status);
@@ -274,7 +271,6 @@ static void check_reachability(void) {
 }
 
 void graph(void) {
-       subnet_cache_flush();
        sssp_bfs();
        check_reachability();
        mst_kruskal();
index bd6a3d28f931ad9bb92ec8ef972f45ffec9f9e9b..f45faa388ae998e6d1e688f46be8e93408628a3b 100644 (file)
@@ -39,7 +39,6 @@ static bool do_mlock = false;
 */
 bool setup_meshlink_network(void) {
        init_connections();
-       init_subnets();
        init_nodes();
        init_edges();
        init_requests();
@@ -66,10 +65,6 @@ bool setup_meshlink_network(void) {
        if(!init_control())
                return false;
 
-       /* Run subnet-up scripts for our own subnets */
-
-       subnet_update(myself, NULL, true);
-
        return true;
 }
 
index 6d7682d37dae6ef632729d5749a855763d930dd8..ae821015d5bd4288647944abdc0a1cbf220df156 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -32,7 +32,6 @@
 #include "net.h"
 #include "netutl.h"
 #include "protocol.h"
-#include "subnet.h"
 #include "xalloc.h"
 
 int contradicting_add_edge = 0;
@@ -42,23 +41,18 @@ time_t last_config_check = 0;
 static timeout_t pingtimer;
 static timeout_t periodictimer;
 
-/* Purge edges and subnets of unreachable nodes. Use carefully. */
+/* Purge edges of unreachable nodes. Use carefully. */
 
+// TODO: remove
 void purge(void) {
        logger(DEBUG_PROTOCOL, LOG_DEBUG, "Purging unreachable nodes");
 
-       /* Remove all edges and subnets owned by unreachable nodes. */
+       /* Remove all edges owned by unreachable nodes. */
 
        for splay_each(node_t, n, node_tree) {
                if(!n->status.reachable) {
                        logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Purging node %s (%s)", n->name, n->hostname);
 
-                       for splay_each(subnet_t, s, n->subnet_tree) {
-                               send_del_subnet(everyone, s);
-                               if(!strictsubnets)
-                                       subnet_del(n, s);
-                       }
-
                        for splay_each(edge_t, e, n->edge_tree) {
                                if(!tunnelserver)
                                        send_del_edge(everyone, e);
@@ -74,10 +68,6 @@ void purge(void) {
                        for splay_each(edge_t, e, edge_weight_tree)
                                if(e->to == n)
                                        return;
-
-                       if(!autoconnect && (!strictsubnets || !n->subnet_tree->head))
-                               /* in strictsubnets mode do not delete nodes with subnets */
-                               node_del(n);
                }
        }
 }
@@ -335,64 +325,6 @@ int reload_configuration(void) {
 
        setup_myself_reloadable();
 
-       /* If StrictSubnet is set, expire deleted Subnets and read new ones in */
-
-       if(strictsubnets) {
-               for splay_each(subnet_t, subnet, subnet_tree)
-                       subnet->expires = 1;
-
-               load_all_subnets();
-
-               for splay_each(subnet_t, subnet, subnet_tree) {
-                       if(subnet->expires == 1) {
-                               send_del_subnet(everyone, subnet);
-                               if(subnet->owner->status.reachable)
-                                       subnet_update(subnet->owner, subnet, false);
-                               subnet_del(subnet->owner, subnet);
-                       } else if(subnet->expires == -1) {
-                               subnet->expires = 0;
-                       } else {
-                               send_add_subnet(everyone, subnet);
-                               if(subnet->owner->status.reachable)
-                                       subnet_update(subnet->owner, subnet, true);
-                       }
-               }
-       } else { /* Only read our own subnets back in */
-               for splay_each(subnet_t, subnet, myself->subnet_tree)
-                       if(!subnet->expires)
-                               subnet->expires = 1;
-
-               config_t *cfg = lookup_config(config_tree, "Subnet");
-
-               while(cfg) {
-                       subnet_t *subnet, *s2;
-
-                       if(!get_config_subnet(cfg, &subnet))
-                               continue;
-
-                       if((s2 = lookup_subnet(myself, subnet))) {
-                               if(s2->expires == 1)
-                                       s2->expires = 0;
-
-                               free_subnet(subnet);
-                       } else {
-                               subnet_add(myself, subnet);
-                               send_add_subnet(everyone, subnet);
-                               subnet_update(myself, subnet, true);
-                       }
-
-                       cfg = lookup_config_next(config_tree, cfg);
-               }
-
-               for splay_each(subnet_t, subnet, myself->subnet_tree) {
-                       if(subnet->expires == 1) {
-                               send_del_subnet(everyone, subnet);
-                               subnet_update(myself, subnet, false);
-                               subnet_del(myself, subnet);
-                       }
-               }
-       }
-
        /* Try to make outgoing connections */
 
        try_outgoing_connections();
index b344eebc3e78b60a09cdbc967ded70c11d94abcf..b311ecad74b9fd3125106e93a68a7904bdf89bf9 100644 (file)
@@ -38,7 +38,6 @@
 #include "route.h"
 #include "rsa.h"
 #include "script.h"
-#include "subnet.h"
 #include "utils.h"
 #include "xalloc.h"
 
@@ -310,62 +309,6 @@ void regenerate_key(void) {
        send_key_changed();
 }
 
-/*
-  Read Subnets from all host config files
-*/
-void load_all_subnets(void) {
-       DIR *dir;
-       struct dirent *ent;
-       char *dname;
-
-       xasprintf(&dname, "%s" SLASH "hosts", confbase);
-       dir = opendir(dname);
-       if(!dir) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Could not open %s: %s", dname, strerror(errno));
-               free(dname);
-               return;
-       }
-
-       while((ent = readdir(dir))) {
-               if(!check_id(ent->d_name))
-                       continue;
-
-               node_t *n = lookup_node(ent->d_name);
-               #ifdef _DIRENT_HAVE_D_TYPE
-               //if(ent->d_type != DT_REG)
-               //      continue;
-               #endif
-
-               splay_tree_t *config_tree;
-               init_configuration(&config_tree);
-               read_config_options(config_tree, ent->d_name);
-               read_host_config(config_tree, ent->d_name);
-
-               if(!n) {
-                       n = new_node();
-                       n->name = xstrdup(ent->d_name);
-                       node_add(n);
-               }
-
-               for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) {
-                       subnet_t *s, *s2;
-
-                       if(!get_config_subnet(cfg, &s))
-                               continue;
-
-                       if((s2 = lookup_subnet(n, s))) {
-                               s2->expires = -1;
-                       } else {
-                               subnet_add(n, s);
-                       }
-               }
-
-               exit_configuration(&config_tree);
-       }
-
-       closedir(dir);
-}
-
 void load_all_nodes(void) {
        DIR *dir;
        struct dirent *ent;
@@ -771,25 +714,12 @@ bool setup_myself(void) {
                sockaddr2str(&sa, NULL, &myport);
        }
 
-       /* Read in all the subnets specified in the host configuration file */
-
-       for(config_t *cfg = lookup_config(config_tree, "Subnet"); cfg; cfg = lookup_config_next(config_tree, cfg)) {
-               subnet_t *subnet;
-
-               if(!get_config_subnet(cfg, &subnet))
-                       return false;
-
-               subnet_add(myself, subnet);
-       }
-
        /* Check some options */
 
        if(!setup_myself_reloadable())
                return false;
 
-       get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets);
        get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver);
-       strictsubnets |= tunnelserver;
 
        if(get_config_int(lookup_config(config_tree, "MaxConnectionBurst"), &max_connection_burst)) {
                if(max_connection_burst <= 0) {
@@ -883,9 +813,7 @@ bool setup_myself(void) {
 
        graph();
 
-       if(strictsubnets)
-               load_all_subnets();
-       else if(autoconnect)
+       if(autoconnect)
                load_all_nodes();
 
        /* Open sockets */
@@ -986,7 +914,6 @@ bool setup_myself(void) {
 */
 bool setup_network(void) {
        init_connections();
-       init_subnets();
        init_nodes();
        init_edges();
        init_requests();
@@ -1023,10 +950,6 @@ bool setup_network(void) {
        for(int i = 0; i < 4; i++)
                free(envp[i]);
 
-       /* Run subnet-up scripts for our own subnets */
-
-       subnet_update(myself, NULL, true);
-
        return true;
 }
 
@@ -1048,7 +971,6 @@ void close_network_connections(void) {
                list_delete_list(outgoing_list);
 
        if(myself && myself->connection) {
-               subnet_update(myself, NULL, false);
                terminate_connection(myself->connection, false);
                free_connection(myself->connection);
        }
@@ -1066,7 +988,6 @@ void close_network_connections(void) {
 
        exit_requests();
        exit_edges();
-       exit_subnets();
        exit_nodes();
        exit_connections();
 
index aab83ca7b020dc1e2a6bb38f2bb4d52dbe19bdcc..42eb25cb539925e419799756eeeb0dc6d39279d0 100644 (file)
@@ -53,7 +53,6 @@ node_t *new_node(void) {
        node_t *n = xzalloc(sizeof *n);
 
        if(replaywin) n->late = xzalloc(replaywin);
-       n->subnet_tree = new_subnet_tree();
        n->edge_tree = new_edge_tree();
        n->mtu = MTU;
        n->maxmtu = MTU;
@@ -62,9 +61,6 @@ node_t *new_node(void) {
 }
 
 void free_node(node_t *n) {
-       if(n->subnet_tree)
-               free_subnet_tree(n->subnet_tree);
-
        if(n->edge_tree)
                free_edge_tree(n->edge_tree);
 
@@ -97,9 +93,6 @@ void node_add(node_t *n) {
 }
 
 void node_del(node_t *n) {
-       for splay_each(subnet_t, s, n->subnet_tree)
-               subnet_del(n, s);
-
        for splay_each(edge_t, e, n->edge_tree)
                edge_del(e);
 
index 1c9f230afd2e551eb19088989e55f09116d3d16c..a1f2ff7d99f01ac71d9feae5b5fbc2a8c31d2a56 100644 (file)
@@ -26,7 +26,6 @@
 #include "connection.h"
 #include "digest.h"
 #include "event.h"
-#include "subnet.h"
 
 typedef struct node_status_t {
        unsigned int unused_active:1;           /* 1 if active (not used for nodes) */
@@ -70,8 +69,6 @@ typedef struct node_t {
        struct edge_t *prevedge;                /* nearest node from him to us */
        struct node_t *via;                     /* next hop for UDP packets */
 
-       splay_tree_t *subnet_tree;              /* Pointer to a tree of subnets belonging to this node */
-
        splay_tree_t *edge_tree;                /* Edges with this node as one of the endpoints */
 
        struct connection_t *connection;        /* Connection associated with this node (if a direct connection exists) */
index eb084f4e54b3e98683c4d7e72dcf019bb209f84a..f2969163b5f966aeadea05223c2e24f9aa2a9c11 100644 (file)
@@ -30,7 +30,6 @@
 #include "net.h"
 #include "node.h"
 #include "process.h"
-#include "subnet.h"
 #include "utils.h"
 #include "xalloc.h"
 
index 374c52299fe8d7d9bd84739cf26ba43d3f75f307..8f6230f6c9c101d9615d6d7db36430cd3acee7ad 100644 (file)
@@ -29,7 +29,6 @@
 #include "xalloc.h"
 
 bool tunnelserver = false;
-bool strictsubnets = false;
 bool experimental = true;
 
 /* Jumptable for the request handlers */
@@ -38,7 +37,7 @@ static bool (*request_handlers[])(connection_t *, const char *) = {
                id_h, metakey_h, challenge_h, chal_reply_h, ack_h,
                status_h, error_h, termreq_h,
                ping_h, pong_h,
-               add_subnet_h, del_subnet_h,
+               NULL, NULL, //add_subnet_h, del_subnet_h,
                add_edge_h, del_edge_h,
                key_changed_h, req_key_h, ans_key_h, tcppacket_h, control_h,
 };
index e771c545c5b398b49ef6eb3b175d9406093636a1..663d5788832cafe6cd80e75ee9e9258bc3bbfff7 100644 (file)
@@ -58,7 +58,6 @@ typedef struct past_request_t {
 } past_request_t;
 
 extern bool tunnelserver;
-extern bool strictsubnets;
 extern bool experimental;
 
 extern ecdsa_t *invitation_key;
@@ -74,7 +73,6 @@ extern ecdsa_t *invitation_key;
 #include "edge.h"
 #include "net.h"
 #include "node.h"
-#include "subnet.h"
 
 /* Basic functions */
 
@@ -100,8 +98,6 @@ extern bool send_error(struct connection_t *, int, const  char *);
 extern bool send_termreq(struct connection_t *);
 extern bool send_ping(struct connection_t *);
 extern bool send_pong(struct connection_t *);
-extern bool send_add_subnet(struct connection_t *, const struct subnet_t *);
-extern bool send_del_subnet(struct connection_t *, const struct subnet_t *);
 extern bool send_add_edge(struct connection_t *, const struct edge_t *);
 extern bool send_del_edge(struct connection_t *, const struct edge_t *);
 extern void send_key_changed(void);
@@ -121,8 +117,6 @@ extern bool error_h(struct connection_t *, const char *);
 extern bool termreq_h(struct connection_t *, const char *);
 extern bool ping_h(struct connection_t *, const char *);
 extern bool pong_h(struct connection_t *, const char *);
-extern bool add_subnet_h(struct connection_t *, const char *);
-extern bool del_subnet_h(struct connection_t *, const char *);
 extern bool add_edge_h(struct connection_t *, const char *);
 extern bool del_edge_h(struct connection_t *, const char *);
 extern bool key_changed_h(struct connection_t *, const char *);
index 551bff60a70c02c07746eab5107c2a8484c0420f..a1395b715e0169f2defb668338ac7fe28bb5ab69 100644 (file)
@@ -678,6 +678,7 @@ bool send_ack(connection_t *c) {
 static void send_everything(connection_t *c) {
        /* Send all known subnets and edges */
 
+       // TODO: remove this
        if(disablebuggypeers) {
                static struct {
                        vpn_packet_t pkt;
@@ -689,17 +690,7 @@ static void send_everything(connection_t *c) {
                send_tcppacket(c, &zeropkt.pkt);
        }
 
-       if(tunnelserver) {
-               for splay_each(subnet_t, s, myself->subnet_tree)
-                       send_add_subnet(c, s);
-
-               return;
-       }
-
        for splay_each(node_t, n, node_tree) {
-               for splay_each(subnet_t, s, n->subnet_tree)
-                       send_add_subnet(c, s);
-
                for splay_each(edge_t, e, n->edge_tree)
                        send_add_edge(c, e);
        }
diff --git a/src/protocol_subnet.c b/src/protocol_subnet.c
deleted file mode 100644 (file)
index 06dafbc..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
-    protocol_subnet.c -- handle the meta-protocol, subnets
-    Copyright (C) 1999-2005 Ivo Timmermans,
-                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
-                  2009      Michael Tokarev <mjt@tls.msk.ru>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include "conf.h"
-#include "connection.h"
-#include "logger.h"
-#include "net.h"
-#include "netutl.h"
-#include "node.h"
-#include "protocol.h"
-#include "subnet.h"
-#include "utils.h"
-#include "xalloc.h"
-
-bool send_add_subnet(connection_t *c, const subnet_t *subnet) {
-       char netstr[MAXNETSTR];
-
-       if(!net2str(netstr, sizeof netstr, subnet))
-               return false;
-
-       return send_request(c, "%d %x %s %s", ADD_SUBNET, rand(), subnet->owner->name, netstr);
-}
-
-bool add_subnet_h(connection_t *c, const char *request) {
-       char subnetstr[MAX_STRING_SIZE];
-       char name[MAX_STRING_SIZE];
-       node_t *owner;
-       subnet_t s = {NULL}, *new, *old;
-
-       if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_SUBNET", c->name,
-                          c->hostname);
-               return false;
-       }
-
-       /* Check if owner name is valid */
-
-       if(!check_id(name)) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name,
-                          c->hostname, "invalid name");
-               return false;
-       }
-
-       /* Check if subnet string is valid */
-
-       if(!str2net(&s, subnetstr)) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ADD_SUBNET", c->name,
-                          c->hostname, "invalid subnet string");
-               return false;
-       }
-
-       if(seen_request(request))
-               return true;
-
-       /* Check if the owner of the new subnet is in the connection list */
-
-       owner = lookup_node(name);
-
-       if(tunnelserver && owner != myself && owner != c->node) {
-               /* in case of tunnelserver, ignore indirect subnet registrations */
-               logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s",
-                                  "ADD_SUBNET", c->name, c->hostname, subnetstr);
-               return true;
-       }
-
-       if(!owner) {
-               owner = new_node();
-               owner->name = xstrdup(name);
-               node_add(owner);
-       }
-
-       /* Check if we already know this subnet */
-
-       if(lookup_subnet(owner, &s))
-               return true;
-
-       /* If we don't know this subnet, but we are the owner, retaliate with a DEL_SUBNET */
-
-       if(owner == myself) {
-               logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself",
-                                  "ADD_SUBNET", c->name, c->hostname);
-               s.owner = myself;
-               send_del_subnet(c, &s);
-               return true;
-       }
-
-       /* In tunnel server mode, we should already know all allowed subnets */
-
-       if(tunnelserver) {
-               logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s",
-                               "ADD_SUBNET", c->name, c->hostname, subnetstr);
-               return true;
-       }
-
-       /* Ignore if strictsubnets is true, but forward it to others */
-
-       if(strictsubnets) {
-               logger(DEBUG_ALWAYS, LOG_WARNING, "Ignoring unauthorized %s from %s (%s): %s",
-                               "ADD_SUBNET", c->name, c->hostname, subnetstr);
-               forward_request(c, request);
-               return true;
-       }
-
-       /* If everything is correct, add the subnet to the list of the owner */
-
-       *(new = new_subnet()) = s;
-       subnet_add(owner, new);
-
-       if(owner->status.reachable)
-               subnet_update(owner, new, true);
-
-       /* Tell the rest */
-
-       if(!tunnelserver)
-               forward_request(c, request);
-
-       /* Fast handoff of roaming MAC addresses */
-
-       if(s.type == SUBNET_MAC && owner != myself && (old = lookup_subnet(myself, &s)) && old->expires)
-               old->expires = 1;
-
-       return true;
-}
-
-bool send_del_subnet(connection_t *c, const subnet_t *s) {
-       char netstr[MAXNETSTR];
-
-       if(!net2str(netstr, sizeof netstr, s))
-               return false;
-
-       return send_request(c, "%d %x %s %s", DEL_SUBNET, rand(), s->owner->name, netstr);
-}
-
-bool del_subnet_h(connection_t *c, const char *request) {
-       char subnetstr[MAX_STRING_SIZE];
-       char name[MAX_STRING_SIZE];
-       node_t *owner;
-       subnet_t s = {NULL}, *find;
-
-       if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "DEL_SUBNET", c->name,
-                          c->hostname);
-               return false;
-       }
-
-       /* Check if owner name is valid */
-
-       if(!check_id(name)) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name,
-                          c->hostname, "invalid name");
-               return false;
-       }
-
-       /* Check if subnet string is valid */
-
-       if(!str2net(&s, subnetstr)) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "DEL_SUBNET", c->name,
-                          c->hostname, "invalid subnet string");
-               return false;
-       }
-
-       if(seen_request(request))
-               return true;
-
-       /* Check if the owner of the subnet being deleted is in the connection list */
-
-       owner = lookup_node(name);
-
-       if(tunnelserver && owner != myself && owner != c->node) {
-               /* in case of tunnelserver, ignore indirect subnet deletion */
-               logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s",
-                                 "DEL_SUBNET", c->name, c->hostname, subnetstr);
-               return true;
-       }
-
-       if(!owner) {
-               logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for %s which is not in our node tree",
-                                  "DEL_SUBNET", c->name, c->hostname, name);
-               return true;
-       }
-
-       /* If everything is correct, delete the subnet from the list of the owner */
-
-       s.owner = owner;
-
-       find = lookup_subnet(owner, &s);
-
-       if(!find) {
-               logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for %s which does not appear in his subnet tree",
-                                  "DEL_SUBNET", c->name, c->hostname, name);
-               if(strictsubnets)
-                       forward_request(c, request);
-               return true;
-       }
-
-       /* If we are the owner of this subnet, retaliate with an ADD_SUBNET */
-
-       if(owner == myself) {
-               logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself",
-                                  "DEL_SUBNET", c->name, c->hostname);
-               send_add_subnet(c, find);
-               return true;
-       }
-
-       if(tunnelserver)
-               return true;
-
-       /* Tell the rest */
-
-       if(!tunnelserver)
-               forward_request(c, request);
-       if(strictsubnets)
-               return true;
-
-       /* Finally, delete it. */
-
-       if(owner->status.reachable)
-               subnet_update(owner, find, false);
-
-       subnet_del(owner, find);
-
-       return true;
-}
index 00ba4c05b19a7a33f5ed978270ed3b24f99b8a7a..5d967dc3c937dcbfd76119dd59b220ebcdd766d9 100644 (file)
 
 #include "system.h"
 
-#include "connection.h"
-#include "control_common.h"
-#include "ethernet.h"
-#include "ipv4.h"
-#include "ipv6.h"
 #include "logger.h"
-#include "meta.h"
 #include "net.h"
-#include "protocol.h"
 #include "route.h"
-#include "subnet.h"
 #include "utils.h"
 
 rmode_t routing_mode = RMODE_ROUTER;
@@ -44,43 +36,6 @@ bool overwrite_mac = false;
 mac_t mymac = {{0xFE, 0xFD, 0, 0, 0, 0}};
 bool pcap = false;
 
-/* Sizes of various headers */
-
-static const size_t ether_size = sizeof(struct ether_header);
-static const size_t arp_size = sizeof(struct ether_arp);
-static const size_t ip_size = sizeof(struct ip);
-static const size_t icmp_size = sizeof(struct icmp) - sizeof(struct ip);
-static const size_t ip6_size = sizeof(struct ip6_hdr);
-static const size_t icmp6_size = sizeof(struct icmp6_hdr);
-static const size_t ns_size = sizeof(struct nd_neighbor_solicit);
-static const size_t opt_size = sizeof(struct nd_opt_hdr);
-
-#ifndef MAX
-#define MAX(a, b) ((a) > (b) ? (a) : (b))
-#endif
-
-static timeout_t age_subnets_timeout;
-
-/* RFC 1071 */
-
-static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) {
-       uint16_t *p = data;
-       uint32_t checksum = prevsum ^ 0xFFFF;
-
-       while(len >= 2) {
-               checksum += *p++;
-               len -= 2;
-       }
-
-       if(len)
-               checksum += *(uint8_t *)p;
-
-       while(checksum >> 16)
-               checksum = (checksum & 0xFFFF) + (checksum >> 16);
-
-       return ~checksum;
-}
-
 static bool ratelimit(int frequency) {
        static time_t lasttime = 0;
        static int count = 0;
@@ -105,891 +60,6 @@ static bool checklength(node_t *source, vpn_packet_t *packet, length_t length) {
                return true;
 }
 
-static void clamp_mss(const node_t *source, const node_t *via, vpn_packet_t *packet) {
-       if(!source || !via || !(via->options & OPTION_CLAMP_MSS))
-               return;
-
-       uint16_t mtu = source->mtu;
-       if(via != myself && via->mtu < mtu)
-               mtu = via->mtu;
-
-       /* Find TCP header */
-       int start = ether_size;
-       uint16_t type = packet->data[12] << 8 | packet->data[13];
-
-       if(type == ETH_P_8021Q) {
-               start += 4;
-               type = packet->data[16] << 8 | packet->data[17];
-       }
-
-       if(type == ETH_P_IP && packet->data[start + 9] == 6)
-               start += (packet->data[start] & 0xf) * 4;
-       else if(type == ETH_P_IPV6 && packet->data[start + 6] == 6)
-               start += 40;
-       else
-               return;
-
-       if(packet->len <= start + 20)
-               return;
-
-       /* Use data offset field to calculate length of options field */
-       int len = ((packet->data[start + 12] >> 4) - 5) * 4;
-
-       if(packet->len < start + 20 + len)
-               return;
-
-       /* Search for MSS option header */
-       for(int i = 0; i < len;) {
-               if(packet->data[start + 20 + i] == 0)
-                       break;
-
-               if(packet->data[start + 20 + i] == 1) {
-                       i++;
-                       continue;
-               }
-
-               if(i > len - 2 || i > len - packet->data[start + 21 + i])
-                       break;
-
-               if(packet->data[start + 20 + i] != 2) {
-                       if(packet->data[start + 21 + i] < 2)
-                               break;
-                       i += packet->data[start + 21 + i];
-                       continue;
-               }
-
-               if(packet->data[start + 21] != 4)
-                       break;
-
-               /* Found it */
-               uint16_t oldmss = packet->data[start + 22 + i] << 8 | packet->data[start + 23 + i];
-               uint16_t newmss = mtu - start - 20;
-               uint16_t csum = packet->data[start + 16] << 8 | packet->data[start + 17];
-
-               if(oldmss <= newmss)
-                       break;
-
-               logger(DEBUG_TRAFFIC, LOG_INFO, "Clamping MSS of packet from %s to %s to %d", source->name, via->name, newmss);
-
-               /* Update the MSS value and the checksum */
-               packet->data[start + 22 + i] = newmss >> 8;
-               packet->data[start + 23 + i] = newmss & 0xff;
-               csum ^= 0xffff;
-               csum -= oldmss;
-               csum += newmss;
-               csum ^= 0xffff;
-               packet->data[start + 16] = csum >> 8;
-               packet->data[start + 17] = csum & 0xff;
-               break;
-       }
-}
-
-static void swap_mac_addresses(vpn_packet_t *packet) {
-       mac_t tmp;
-       memcpy(&tmp, &packet->data[0], sizeof tmp);
-       memcpy(&packet->data[0], &packet->data[6], sizeof tmp);
-       memcpy(&packet->data[6], &tmp, sizeof tmp);
-}
-
-static void age_subnets(void *data) {
-       bool left = false;
-
-       for splay_each(subnet_t, s, myself->subnet_tree) {
-               if(s->expires && s->expires < now.tv_sec) {
-                       if(debug_level >= DEBUG_TRAFFIC) {
-                               char netstr[MAXNETSTR];
-                               if(net2str(netstr, sizeof netstr, s))
-                                       logger(DEBUG_TRAFFIC, LOG_INFO, "Subnet %s expired", netstr);
-                       }
-
-                       for list_each(connection_t, c, connection_list)
-                               if(c->status.active)
-                                       send_del_subnet(c, s);
-
-                       subnet_del(myself, s);
-               } else {
-                       if(s->expires)
-                               left = true;
-               }
-       }
-
-       if(left)
-               timeout_set(&age_subnets_timeout, &(struct timeval){10, rand() % 100000});
-}
-
-static void learn_mac(mac_t *address) {
-       subnet_t *subnet = lookup_subnet_mac(myself, address);
-
-       /* If we don't know this MAC address yet, store it */
-
-       if(!subnet) {
-               logger(DEBUG_TRAFFIC, 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]);
-
-               subnet = new_subnet();
-               subnet->type = SUBNET_MAC;
-               subnet->expires = now.tv_sec + macexpire;
-               subnet->net.mac.address = *address;
-               subnet->weight = 10;
-               subnet_add(myself, subnet);
-               subnet_update(myself, subnet, true);
-
-               /* And tell all other tinc daemons it's our MAC */
-
-               for list_each(connection_t, c, connection_list)
-                       if(c->status.active)
-                               send_add_subnet(c, subnet);
-
-               timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval){10, rand() % 100000});
-       } else {
-               if(subnet->expires)
-                       subnet->expires = now.tv_sec + macexpire;
-       }
-}
-
-/* RFC 792 */
-
-static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) {
-       struct ip ip = {0};
-       struct icmp icmp = {0};
-
-       struct in_addr ip_src;
-       struct in_addr ip_dst;
-       uint32_t oldlen;
-
-       if(ratelimit(3))
-               return;
-
-       /* Swap Ethernet source and destination addresses */
-
-       swap_mac_addresses(packet);
-
-       /* Copy headers from packet into properly aligned structs on the stack */
-
-       memcpy(&ip, packet->data + ether_size, ip_size);
-
-       /* Remember original source and destination */
-
-       ip_src = ip.ip_src;
-       ip_dst = ip.ip_dst;
-
-       oldlen = packet->len - ether_size;
-
-       if(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
-               icmp.icmp_nextmtu = htons(packet->len - ether_size);
-
-       if(oldlen >= IP_MSS - ip_size - icmp_size)
-               oldlen = IP_MSS - ip_size - icmp_size;
-
-       /* Copy first part of original contents to ICMP message */
-
-       memmove(packet->data + ether_size + ip_size + icmp_size, packet->data + ether_size, oldlen);
-
-       /* Fill in IPv4 header */
-
-       ip.ip_v = 4;
-       ip.ip_hl = ip_size / 4;
-       ip.ip_tos = 0;
-       ip.ip_len = htons(ip_size + icmp_size + oldlen);
-       ip.ip_id = 0;
-       ip.ip_off = 0;
-       ip.ip_ttl = 255;
-       ip.ip_p = IPPROTO_ICMP;
-       ip.ip_sum = 0;
-       ip.ip_src = ip_dst;
-       ip.ip_dst = ip_src;
-
-       ip.ip_sum = inet_checksum(&ip, ip_size, ~0);
-
-       /* Fill in ICMP header */
-
-       icmp.icmp_type = type;
-       icmp.icmp_code = code;
-       icmp.icmp_cksum = 0;
-
-       icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, ~0);
-       icmp.icmp_cksum = inet_checksum(packet->data + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum);
-
-       /* Copy structs on stack back to packet */
-
-       memcpy(packet->data + ether_size, &ip, ip_size);
-       memcpy(packet->data + ether_size + ip_size, &icmp, icmp_size);
-
-       packet->len = ether_size + ip_size + icmp_size + oldlen;
-
-       send_packet(source, packet);
-}
-
-/* RFC 791 */
-
-static void fragment_ipv4_packet(node_t *dest, vpn_packet_t *packet, length_t ether_size) {
-       struct ip ip;
-       vpn_packet_t fragment;
-       int len, maxlen, todo;
-       uint8_t *offset;
-       uint16_t ip_off, origf;
-
-       memcpy(&ip, packet->data + ether_size, ip_size);
-       fragment.priority = packet->priority;
-
-       if(ip.ip_hl != ip_size / 4)
-               return;
-
-       todo = ntohs(ip.ip_len) - ip_size;
-
-       if(ether_size + ip_size + todo != packet->len) {
-               logger(DEBUG_TRAFFIC, LOG_WARNING, "Length of packet (%d) doesn't match length in IPv4 header (%d)", packet->len, (int)(ether_size + ip_size + todo));
-               return;
-       }
-
-       logger(DEBUG_TRAFFIC, LOG_INFO, "Fragmenting packet of %d bytes to %s (%s)", packet->len, dest->name, dest->hostname);
-
-       offset = packet->data + ether_size + ip_size;
-       maxlen = (dest->mtu - ether_size - ip_size) & ~0x7;
-       ip_off = ntohs(ip.ip_off);
-       origf = ip_off & ~IP_OFFMASK;
-       ip_off &= IP_OFFMASK;
-
-       while(todo) {
-               len = todo > maxlen ? maxlen : todo;
-               memcpy(fragment.data + ether_size + ip_size, offset, len);
-               todo -= len;
-               offset += len;
-
-               ip.ip_len = htons(ip_size + len);
-               ip.ip_off = htons(ip_off | origf | (todo ? IP_MF : 0));
-               ip.ip_sum = 0;
-               ip.ip_sum = inet_checksum(&ip, ip_size, ~0);
-               memcpy(fragment.data, packet->data, ether_size);
-               memcpy(fragment.data + ether_size, &ip, ip_size);
-               fragment.len = ether_size + ip_size + len;
-
-               send_packet(dest, &fragment);
-
-               ip_off += len / 8;
-       }
-}
-
-static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) {
-       subnet_t *subnet;
-       node_t *via;
-       ipv4_t dest;
-
-       memcpy(&dest, &packet->data[30], sizeof dest);
-       subnet = lookup_subnet_ipv4(&dest);
-
-       if(!subnet) {
-               logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv4 destination address %d.%d.%d.%d",
-                               source->name, source->hostname,
-                               dest.x[0],
-                               dest.x[1],
-                               dest.x[2],
-                               dest.x[3]);
-
-               route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN);
-               return;
-       }
-
-       if(subnet->owner == source) {
-               logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname);
-               return;
-       }
-
-       if(!subnet->owner->status.reachable)
-               return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_UNREACH);
-
-       if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
-               return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO);
-
-       if(priorityinheritance)
-               packet->priority = packet->data[15];
-
-       via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
-
-       if(via == source) {
-               logger(DEBUG_TRAFFIC, LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname);
-               return;
-       }
-
-       if(directonly && subnet->owner != via)
-               return route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_NET_ANO);
-
-       if(via && packet->len > MAX(via->mtu, 590) && via != myself) {
-               logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
-               if(packet->data[20] & 0x40) {
-                       packet->len = MAX(via->mtu, 590);
-                       route_ipv4_unreachable(source, packet, ether_size, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
-               } else {
-                       fragment_ipv4_packet(via, packet, ether_size);
-               }
-
-               return;
-       }
-
-       clamp_mss(source, via, packet);
-
-       send_packet(subnet->owner, packet);
-}
-
-static void route_ipv4(node_t *source, vpn_packet_t *packet) {
-       if(!checklength(source, packet, ether_size + ip_size))
-               return;
-
-       if(broadcast_mode && (((packet->data[30] & 0xf0) == 0xe0) || (
-                       packet->data[30] == 255 &&
-                       packet->data[31] == 255 &&
-                       packet->data[32] == 255 &&
-                       packet->data[33] == 255)))
-               broadcast_packet(source, packet);
-       else
-               route_ipv4_unicast(source, packet);
-}
-
-/* RFC 2463 */
-
-static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) {
-       struct ip6_hdr ip6;
-       struct icmp6_hdr icmp6 = {0};
-       uint16_t checksum;
-
-       struct {
-               struct in6_addr ip6_src;        /* source address */
-               struct in6_addr ip6_dst;        /* destination address */
-               uint32_t length;
-               uint32_t next;
-       } pseudo;
-
-       if(ratelimit(3))
-               return;
-
-       /* Swap Ethernet source and destination addresses */
-
-       swap_mac_addresses(packet);
-
-       /* Copy headers from packet to structs on the stack */
-
-       memcpy(&ip6, packet->data + ether_size, ip6_size);
-
-       /* Remember original source and destination */
-
-       pseudo.ip6_src = ip6.ip6_dst;
-       pseudo.ip6_dst = ip6.ip6_src;
-
-       pseudo.length = packet->len - ether_size;
-
-       if(type == ICMP6_PACKET_TOO_BIG)
-               icmp6.icmp6_mtu = htonl(pseudo.length);
-
-       if(pseudo.length >= IP_MSS - ip6_size - icmp6_size)
-               pseudo.length = IP_MSS - ip6_size - icmp6_size;
-
-       /* Copy first part of original contents to ICMP message */
-
-       memmove(packet->data + ether_size + ip6_size + icmp6_size, packet->data + ether_size, pseudo.length);
-
-       /* Fill in IPv6 header */
-
-       ip6.ip6_flow = htonl(0x60000000UL);
-       ip6.ip6_plen = htons(icmp6_size + pseudo.length);
-       ip6.ip6_nxt = IPPROTO_ICMPV6;
-       ip6.ip6_hlim = 255;
-       ip6.ip6_src = pseudo.ip6_src;
-       ip6.ip6_dst = pseudo.ip6_dst;
-
-       /* Fill in ICMP header */
-
-       icmp6.icmp6_type = type;
-       icmp6.icmp6_code = code;
-       icmp6.icmp6_cksum = 0;
-
-       /* Create pseudo header */
-
-       pseudo.length = htonl(icmp6_size + pseudo.length);
-       pseudo.next = htonl(IPPROTO_ICMPV6);
-
-       /* Generate checksum */
-
-       checksum = inet_checksum(&pseudo, sizeof pseudo, ~0);
-       checksum = inet_checksum(&icmp6, icmp6_size, checksum);
-       checksum = inet_checksum(packet->data + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum);
-
-       icmp6.icmp6_cksum = checksum;
-
-       /* Copy structs on stack back to packet */
-
-       memcpy(packet->data + ether_size, &ip6, ip6_size);
-       memcpy(packet->data + ether_size + ip6_size, &icmp6, icmp6_size);
-
-       packet->len = ether_size + ip6_size + ntohl(pseudo.length);
-
-       send_packet(source, packet);
-}
-
-static void route_ipv6_unicast(node_t *source, vpn_packet_t *packet) {
-       subnet_t *subnet;
-       node_t *via;
-       ipv6_t dest;
-
-       memcpy(&dest, &packet->data[38], sizeof dest);
-       subnet = lookup_subnet_ipv6(&dest);
-
-       if(!subnet) {
-               logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
-                               source->name, source->hostname,
-                               ntohs(dest.x[0]),
-                               ntohs(dest.x[1]),
-                               ntohs(dest.x[2]),
-                               ntohs(dest.x[3]),
-                               ntohs(dest.x[4]),
-                               ntohs(dest.x[5]),
-                               ntohs(dest.x[6]),
-                               ntohs(dest.x[7]));
-
-               route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR);
-               return;
-       }
-
-       if(subnet->owner == source) {
-               logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname);
-               return;
-       }
-
-       if(!subnet->owner->status.reachable)
-               return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE);
-
-       if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
-               return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
-
-       via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
-
-       if(via == source) {
-               logger(DEBUG_TRAFFIC, LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname);
-               return;
-       }
-
-       if(directonly && subnet->owner != via)
-               return route_ipv6_unreachable(source, packet, ether_size, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
-
-       if(via && packet->len > MAX(via->mtu, 1294) && via != myself) {
-               logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
-               packet->len = MAX(via->mtu, 1294);
-               route_ipv6_unreachable(source, packet, ether_size, ICMP6_PACKET_TOO_BIG, 0);
-               return;
-       }
-
-       clamp_mss(source, via, packet);
-
-       send_packet(subnet->owner, packet);
-}
-
-/* RFC 2461 */
-
-static void route_neighborsol(node_t *source, vpn_packet_t *packet) {
-       struct ip6_hdr ip6;
-       struct nd_neighbor_solicit ns;
-       struct nd_opt_hdr opt;
-       subnet_t *subnet;
-       uint16_t checksum;
-       bool has_opt;
-
-       struct {
-               struct in6_addr ip6_src;
-               struct in6_addr ip6_dst;
-               uint32_t length;
-               uint32_t next;
-       } pseudo;
-
-       if(!checklength(source, packet, ether_size + ip6_size + ns_size))
-               return;
-
-       has_opt = packet->len >= ether_size + ip6_size + ns_size + opt_size + ETH_ALEN;
-
-       if(source != myself) {
-               logger(DEBUG_TRAFFIC, LOG_WARNING, "Got neighbor solicitation request from %s (%s) while in router mode!", source->name, source->hostname);
-               return;
-       }
-
-       /* Copy headers from packet to structs on the stack */
-
-       memcpy(&ip6, packet->data + ether_size, ip6_size);
-       memcpy(&ns, packet->data + ether_size + ip6_size, ns_size);
-       if(has_opt)
-               memcpy(&opt, packet->data + ether_size + ip6_size + ns_size, opt_size);
-
-       /* First, snatch the source address from the neighbor solicitation packet */
-
-       if(overwrite_mac)
-               memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN);
-
-       /* Check if this is a valid neighbor solicitation request */
-
-       if(ns.nd_ns_hdr.icmp6_type != ND_NEIGHBOR_SOLICIT ||
-          (has_opt && opt.nd_opt_type != ND_OPT_SOURCE_LINKADDR)) {
-               logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: received unknown type neighbor solicitation request");
-               return;
-       }
-
-       /* Create pseudo header */
-
-       pseudo.ip6_src = ip6.ip6_src;
-       pseudo.ip6_dst = ip6.ip6_dst;
-       if(has_opt)
-               pseudo.length = htonl(ns_size + opt_size + ETH_ALEN);
-       else
-               pseudo.length = htonl(ns_size);
-       pseudo.next = htonl(IPPROTO_ICMPV6);
-
-       /* Generate checksum */
-
-       checksum = inet_checksum(&pseudo, sizeof pseudo, ~0);
-       checksum = inet_checksum(&ns, ns_size, checksum);
-       if(has_opt) {
-               checksum = inet_checksum(&opt, opt_size, checksum);
-               checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum);
-       }
-
-       if(checksum) {
-               logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: checksum error for neighbor solicitation request");
-               return;
-       }
-
-       /* Check if the IPv6 address exists on the VPN */
-
-       subnet = lookup_subnet_ipv6((ipv6_t *) &ns.nd_ns_target);
-
-       if(!subnet) {
-               logger(DEBUG_TRAFFIC, 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)[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;
-       }
-
-       /* Check if it is for our own subnet */
-
-       if(subnet->owner == myself)
-               return;                                          /* silently ignore */
-
-       /* Create neighbor advertation reply */
-
-       memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */
-       packet->data[ETH_ALEN * 2 - 1] ^= 0xFF;                  /* mangle source address so it looks like it's not from us */
-
-       ip6.ip6_dst = ip6.ip6_src;                               /* swap destination and source protocoll address */
-       ip6.ip6_src = ns.nd_ns_target;
-
-       if(has_opt)
-               memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN);   /* add fake source hard addr */
-
-       ns.nd_ns_cksum = 0;
-       ns.nd_ns_type = ND_NEIGHBOR_ADVERT;
-       ns.nd_ns_reserved = htonl(0x40000000UL);                 /* Set solicited flag */
-       opt.nd_opt_type = ND_OPT_TARGET_LINKADDR;
-
-       /* Create pseudo header */
-
-       pseudo.ip6_src = ip6.ip6_src;
-       pseudo.ip6_dst = ip6.ip6_dst;
-       if(has_opt)
-               pseudo.length = htonl(ns_size + opt_size + ETH_ALEN);
-       else
-               pseudo.length = htonl(ns_size);
-       pseudo.next = htonl(IPPROTO_ICMPV6);
-
-       /* Generate checksum */
-
-       checksum = inet_checksum(&pseudo, sizeof pseudo, ~0);
-       checksum = inet_checksum(&ns, ns_size, checksum);
-       if(has_opt) {
-               checksum = inet_checksum(&opt, opt_size, checksum);
-               checksum = inet_checksum(packet->data + ether_size + ip6_size + ns_size + opt_size, ETH_ALEN, checksum);
-       }
-
-       ns.nd_ns_hdr.icmp6_cksum = checksum;
-
-       /* Copy structs on stack back to packet */
-
-       memcpy(packet->data + ether_size, &ip6, ip6_size);
-       memcpy(packet->data + ether_size + ip6_size, &ns, ns_size);
-       if(has_opt)
-               memcpy(packet->data + ether_size + ip6_size + ns_size, &opt, opt_size);
-
-       send_packet(source, packet);
-}
-
-static void route_ipv6(node_t *source, vpn_packet_t *packet) {
-       if(!checklength(source, packet, ether_size + ip6_size))
-               return;
-
-       if(packet->data[20] == IPPROTO_ICMPV6 && checklength(source, packet, ether_size + ip6_size + icmp6_size) && packet->data[54] == ND_NEIGHBOR_SOLICIT) {
-               route_neighborsol(source, packet);
-               return;
-       }
-
-       if(broadcast_mode && packet->data[38] == 255)
-               broadcast_packet(source, packet);
-       else
-               route_ipv6_unicast(source, packet);
-}
-
-/* RFC 826 */
-
-static void route_arp(node_t *source, vpn_packet_t *packet) {
-       struct ether_arp arp;
-       subnet_t *subnet;
-       struct in_addr addr;
-
-       if(!checklength(source, packet, ether_size + arp_size))
-               return;
-
-       if(source != myself) {
-               logger(DEBUG_TRAFFIC, LOG_WARNING, "Got ARP request from %s (%s) while in router mode!", source->name, source->hostname);
-               return;
-       }
-
-       /* First, snatch the source address from the ARP packet */
-
-       if(overwrite_mac)
-               memcpy(mymac.x, packet->data + ETH_ALEN, ETH_ALEN);
-
-       /* Copy headers from packet to structs on the stack */
-
-       memcpy(&arp, packet->data + ether_size, arp_size);
-
-       /* Check if this is a valid ARP request */
-
-       if(ntohs(arp.arp_hrd) != ARPHRD_ETHER || ntohs(arp.arp_pro) != ETH_P_IP ||
-          arp.arp_hln != ETH_ALEN || arp.arp_pln != sizeof addr || ntohs(arp.arp_op) != ARPOP_REQUEST) {
-               logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet: received unknown type ARP request");
-               return;
-       }
-
-       /* Check if the IPv4 address exists on the VPN */
-
-       subnet = lookup_subnet_ipv4((ipv4_t *) &arp.arp_tpa);
-
-       if(!subnet) {
-               logger(DEBUG_TRAFFIC, 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]);
-               return;
-       }
-
-       /* Check if it is for our own subnet */
-
-       if(subnet->owner == myself)
-               return;                                          /* silently ignore */
-
-       memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */
-       packet->data[ETH_ALEN * 2 - 1] ^= 0xFF;                  /* mangle source address so it looks like it's not from us */
-
-       memcpy(&addr, arp.arp_tpa, sizeof addr);                 /* save protocol addr */
-       memcpy(arp.arp_tpa, arp.arp_spa, sizeof addr);           /* swap destination and source protocol address */
-       memcpy(arp.arp_spa, &addr, sizeof addr);                 /* ... */
-
-       memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN);              /* set target hard/proto addr */
-       memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN);  /* add fake source hard addr */
-       arp.arp_op = htons(ARPOP_REPLY);
-
-       /* Copy structs on stack back to packet */
-
-       memcpy(packet->data + ether_size, &arp, arp_size);
-
-       send_packet(source, packet);
-}
-
-static void route_mac(node_t *source, vpn_packet_t *packet) {
-       subnet_t *subnet;
-       mac_t dest;
-
-       /* Learn source address */
-
-       if(source == myself) {
-               mac_t src;
-               memcpy(&src, &packet->data[6], sizeof src);
-               learn_mac(&src);
-       }
-
-       /* Lookup destination address */
-
-       memcpy(&dest, &packet->data[0], sizeof dest);
-       subnet = lookup_subnet_mac(NULL, &dest);
-
-       if(!subnet) {
-               broadcast_packet(source, packet);
-               return;
-       }
-
-       if(subnet->owner == source) {
-               logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname);
-               return;
-       }
-
-       if(forwarding_mode == FMODE_OFF && source != myself && subnet->owner != myself)
-               return;
-
-       uint16_t type = packet->data[12] << 8 | packet->data[13];
-
-       if(priorityinheritance && type == ETH_P_IP && packet->len >= ether_size + ip_size)
-               packet->priority = packet->data[15];
-
-       // Handle packets larger than PMTU
-
-       node_t *via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
-
-       if(directonly && subnet->owner != via)
-               return;
-
-       if(via && packet->len > via->mtu && via != myself) {
-               logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
-               length_t ethlen = 14;
-
-               if(type == ETH_P_8021Q) {
-                       type = packet->data[16] << 8 | packet->data[17];
-                       ethlen += 4;
-               }
-
-               if(type == ETH_P_IP && packet->len > 576 + ethlen) {
-                       if(packet->data[6 + ethlen] & 0x40) {
-                               packet->len = via->mtu;
-                               route_ipv4_unreachable(source, packet, ethlen, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED);
-                       } else {
-                               fragment_ipv4_packet(via, packet, ethlen);
-                       }
-                       return;
-               } else if(type == ETH_P_IPV6 && packet->len > 1280 + ethlen) {
-                       packet->len = via->mtu;
-                       route_ipv6_unreachable(source, packet, ethlen, ICMP6_PACKET_TOO_BIG, 0);
-                       return;
-               }
-       }
-
-       clamp_mss(source, via, packet);
-
-       send_packet(subnet->owner, packet);
-}
-
-static void send_pcap(vpn_packet_t *packet) {
-       pcap = false;
-
-       for list_each(connection_t, c, connection_list) {
-               if(!c->status.pcap)
-                       continue;
-
-               pcap = true;
-               int len = packet->len;
-               if(c->outmaclength && c->outmaclength < len)
-                       len = c->outmaclength;
-
-               if(send_request(c, "%d %d %d", CONTROL, REQ_PCAP, len))
-                       send_meta(c, (char *)packet->data, len);
-       }
-}
-
-static bool do_decrement_ttl(node_t *source, vpn_packet_t *packet) {
-       uint16_t type = packet->data[12] << 8 | packet->data[13];
-       length_t ethlen = ether_size;
-
-       if(type == ETH_P_8021Q) {
-               type = packet->data[16] << 8 | packet->data[17];
-               ethlen += 4;
-       }
-
-       switch (type) {
-               case ETH_P_IP:
-                       if(!checklength(source, packet, ethlen + ip_size))
-                               return false;
-
-                       if(packet->data[ethlen + 8] < 1) {
-                               if(packet->data[ethlen + 11] != IPPROTO_ICMP || packet->data[ethlen + 32] != ICMP_TIME_EXCEEDED)
-                                       route_ipv4_unreachable(source, packet, ethlen, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL);
-                               return false;
-                       }
-
-                       uint16_t old = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9];
-                       packet->data[ethlen + 8]--;
-                       uint16_t new = packet->data[ethlen + 8] << 8 | packet->data[ethlen + 9];
-
-                       uint32_t checksum = packet->data[ethlen + 10] << 8 | packet->data[ethlen + 11];
-                       checksum += old + (~new & 0xFFFF);
-                       while(checksum >> 16)
-                               checksum = (checksum & 0xFFFF) + (checksum >> 16);
-                       packet->data[ethlen + 10] = checksum >> 8;
-                       packet->data[ethlen + 11] = checksum & 0xff;
-
-                       return true;
-
-               case ETH_P_IPV6:
-                       if(!checklength(source, packet, ethlen + ip6_size))
-                               return false;
-
-                       if(packet->data[ethlen + 7] < 1) {
-                               if(packet->data[ethlen + 6] != IPPROTO_ICMPV6 || packet->data[ethlen + 40] != ICMP6_TIME_EXCEEDED)
-                                       route_ipv6_unreachable(source, packet, ethlen, ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT);
-                               return false;
-                       }
-
-                       packet->data[ethlen + 7]--;
-
-                       return true;
-
-               default:
-                       return true;
-       }
-}
-
 void route(node_t *source, vpn_packet_t *packet) {
-       if(pcap)
-               send_pcap(packet);
-
-       if(forwarding_mode == FMODE_KERNEL && source != myself) {
-               send_packet(myself, packet);
-               return;
-       }
-
-       if(!checklength(source, packet, ether_size))
-               return;
-
-       if(decrement_ttl && source != myself)
-               if(!do_decrement_ttl(source, packet))
-                       return;
-
-       uint16_t type = packet->data[12] << 8 | packet->data[13];
-
-       switch (routing_mode) {
-               case RMODE_ROUTER:
-                       switch (type) {
-                               case ETH_P_ARP:
-                                       route_arp(source, packet);
-                                       break;
-
-                               case ETH_P_IP:
-                                       route_ipv4(source, packet);
-                                       break;
-
-                               case ETH_P_IPV6:
-                                       route_ipv6(source, packet);
-                                       break;
-
-                               default:
-                                       logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type);
-                                       break;
-                       }
-                       break;
-
-               case RMODE_SWITCH:
-                       route_mac(source, packet);
-                       break;
-
-               case RMODE_HUB:
-                       broadcast_packet(source, packet);
-                       break;
-       }
+       // TODO: route on name or key
 }
index 9a43d53188a6b0149d492aa35e37043edc375771..e441dcf5c8d675b34959d14f80ddd6882486dfa8 100644 (file)
@@ -23,6 +23,7 @@
 #include "conf.h"
 #include "logger.h"
 #include "names.h"
+#include "net.h"
 #include "script.h"
 #include "xalloc.h"
 
diff --git a/src/subnet.c b/src/subnet.c
deleted file mode 100644 (file)
index e45d004..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
-    subnet.c -- handle subnet lookups and lists
-    Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
-                  2000-2005 Ivo Timmermans
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include "splay_tree.h"
-#include "control_common.h"
-#include "hash.h"
-#include "logger.h"
-#include "names.h"
-#include "net.h"
-#include "netutl.h"
-#include "node.h"
-#include "script.h"
-#include "subnet.h"
-#include "utils.h"
-#include "xalloc.h"
-
-/* lists type of subnet */
-
-splay_tree_t *subnet_tree;
-
-/* Subnet lookup cache */
-
-hash_t *ipv4_cache;
-hash_t *ipv6_cache;
-hash_t *mac_cache;
-
-void subnet_cache_flush(void) {
-       hash_clear(ipv4_cache);
-       hash_clear(ipv6_cache);
-       hash_clear(mac_cache);
-}
-
-/* Initialising trees */
-
-void init_subnets(void) {
-       subnet_tree = splay_alloc_tree((splay_compare_t) subnet_compare, (splay_action_t) free_subnet);
-
-       ipv4_cache = hash_alloc(0x100, sizeof(ipv4_t));
-       ipv6_cache = hash_alloc(0x100, sizeof(ipv6_t));
-       mac_cache = hash_alloc(0x100, sizeof(mac_t));
-}
-
-void exit_subnets(void) {
-       splay_delete_tree(subnet_tree);
-
-       hash_free(ipv4_cache);
-       hash_free(ipv6_cache);
-       hash_free(mac_cache);
-}
-
-splay_tree_t *new_subnet_tree(void) {
-       return splay_alloc_tree((splay_compare_t) subnet_compare, NULL);
-}
-
-void free_subnet_tree(splay_tree_t *subnet_tree) {
-       splay_delete_tree(subnet_tree);
-}
-
-/* Allocating and freeing space for subnets */
-
-subnet_t *new_subnet(void) {
-       return xzalloc(sizeof(subnet_t));
-}
-
-void free_subnet(subnet_t *subnet) {
-       free(subnet);
-}
-
-/* Adding and removing subnets */
-
-void subnet_add(node_t *n, subnet_t *subnet) {
-       subnet->owner = n;
-
-       splay_insert(subnet_tree, subnet);
-       splay_insert(n->subnet_tree, subnet);
-
-       subnet_cache_flush();
-}
-
-void subnet_del(node_t *n, subnet_t *subnet) {
-       splay_delete(n->subnet_tree, subnet);
-       splay_delete(subnet_tree, subnet);
-
-       subnet_cache_flush();
-}
-
-/* Subnet lookup routines */
-
-subnet_t *lookup_subnet(const node_t *owner, const subnet_t *subnet) {
-       return splay_search(owner->subnet_tree, subnet);
-}
-
-subnet_t *lookup_subnet_mac(const node_t *owner, const mac_t *address) {
-       subnet_t *r = NULL;
-
-       // Check if this address is cached
-
-       if((r = hash_search(mac_cache, address)))
-               return r;
-
-       // Search all subnets for a matching one
-
-       for splay_each(subnet_t, p, owner ? owner->subnet_tree : subnet_tree) {
-               if(!p || p->type != SUBNET_MAC)
-                       continue;
-
-               if(!memcmp(address, &p->net.mac.address, sizeof *address)) {
-                       r = p;
-                       if(p->owner->status.reachable)
-                               break;
-               }
-       }
-
-       // Cache the result
-
-       if(r)
-               hash_insert(mac_cache, address, r);
-
-       return r;
-}
-
-subnet_t *lookup_subnet_ipv4(const ipv4_t *address) {
-       subnet_t *r = NULL;
-
-       // Check if this address is cached
-
-       if((r = hash_search(ipv4_cache, address)))
-               return r;
-
-       // Search all subnets for a matching one
-
-       for splay_each(subnet_t, p, subnet_tree) {
-               if(!p || p->type != SUBNET_IPV4)
-                       continue;
-
-               if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength)) {
-                       r = p;
-                       if(p->owner->status.reachable)
-                               break;
-               }
-       }
-
-       // Cache the result
-
-       if(r)
-               hash_insert(ipv4_cache, address, r);
-
-       return r;
-}
-
-subnet_t *lookup_subnet_ipv6(const ipv6_t *address) {
-       subnet_t *r = NULL;
-
-       // Check if this address is cached
-
-       if((r = hash_search(ipv6_cache, address)))
-               return r;
-
-       // Search all subnets for a matching one
-
-       for splay_each(subnet_t, p, subnet_tree) {
-               if(!p || p->type != SUBNET_IPV6)
-                       continue;
-
-               if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength)) {
-                       r = p;
-                       if(p->owner->status.reachable)
-                               break;
-               }
-       }
-
-       // Cache the result
-
-       if(r)
-               hash_insert(ipv6_cache, address, r);
-
-       return r;
-}
-
-void subnet_update(node_t *owner, subnet_t *subnet, bool up) {
-       char netstr[MAXNETSTR];
-       char *name, *address, *port;
-       char empty[] = "";
-
-       // Prepare environment variables to be passed to the script
-
-       char *envp[10] = {NULL};
-       xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
-       xasprintf(&envp[3], "NODE=%s", owner->name);
-
-       if(owner != myself) {
-               sockaddr2str(&owner->address, &address, &port);
-               // 4 and 5 are reserved for SUBNET and WEIGHT
-               xasprintf(&envp[6], "REMOTEADDRESS=%s", address);
-               xasprintf(&envp[7], "REMOTEPORT=%s", port);
-               free(port);
-               free(address);
-       }
-
-       xasprintf(&envp[8], "NAME=%s", myself->name);
-
-       name = up ? "subnet-up" : "subnet-down";
-
-       if(!subnet) {
-               for splay_each(subnet_t, subnet, owner->subnet_tree) {
-                       if(!net2str(netstr, sizeof netstr, subnet))
-                               continue;
-
-                       // Strip the weight from the subnet, and put it in its own environment variable
-                       char *weight = strchr(netstr, '#');
-                       if(weight)
-                               *weight++ = 0;
-                       else
-                               weight = empty;
-
-                       // Prepare the SUBNET and WEIGHT variables
-                       if(envp[4])
-                               free(envp[4]);
-                       if(envp[5])
-                               free(envp[5]);
-                       xasprintf(&envp[4], "SUBNET=%s", netstr);
-                       xasprintf(&envp[5], "WEIGHT=%s", weight);
-
-                       execute_script(name, envp);
-               }
-       } else {
-               if(net2str(netstr, sizeof netstr, subnet)) {
-                       // Strip the weight from the subnet, and put it in its own environment variable
-                       char *weight = strchr(netstr, '#');
-                       if(weight)
-                               *weight++ = 0;
-                       else
-                               weight = empty;
-
-                       // Prepare the SUBNET and WEIGHT variables
-                       xasprintf(&envp[4], "SUBNET=%s", netstr);
-                       xasprintf(&envp[5], "WEIGHT=%s", weight);
-
-                       execute_script(name, envp);
-               }
-       }
-
-       for(int i = 0; envp[i] && i < 9; i++)
-               free(envp[i]);
-}
-
-bool dump_subnets(connection_t *c) {
-       for splay_each(subnet_t, subnet, subnet_tree) {
-               char netstr[MAXNETSTR];
-
-               if(!net2str(netstr, sizeof netstr, subnet))
-                       continue;
-
-               send_request(c, "%d %d %s %s",
-                               CONTROL, REQ_DUMP_SUBNETS,
-                               netstr, subnet->owner->name);
-       }
-
-       return send_request(c, "%d %d", CONTROL, REQ_DUMP_SUBNETS);
-}
diff --git a/src/subnet.h b/src/subnet.h
deleted file mode 100644 (file)
index 9fd95b6..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-    subnet.h -- header for subnet.c
-    Copyright (C) 2000-2012 Guus Sliepen <guus@tinc-vpn.org>,
-                  2000-2005 Ivo Timmermans
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_SUBNET_H__
-#define __TINC_SUBNET_H__
-
-#include "net.h"
-
-typedef enum subnet_type_t {
-       SUBNET_MAC = 0,
-       SUBNET_IPV4,
-       SUBNET_IPV6,
-       SUBNET_TYPES            /* Guardian */
-} subnet_type_t;
-
-typedef struct subnet_mac_t {
-       mac_t address;
-} subnet_mac_t;
-
-typedef struct subnet_ipv4_t {
-       ipv4_t address;
-       int prefixlength;
-} subnet_ipv4_t;
-
-typedef struct subnet_ipv6_t {
-       ipv6_t address;
-       int prefixlength;
-} subnet_ipv6_t;
-
-#include "node.h"
-
-typedef struct subnet_t {
-       struct node_t *owner;   /* the owner of this subnet */
-
-       subnet_type_t type;     /* subnet type (IPv4? IPv6? MAC? something even weirder?) */
-       time_t expires;         /* expiry time */
-       int weight;             /* weight (higher value is higher priority) */
-
-       /* And now for the actual subnet: */
-
-       union net {
-               subnet_mac_t mac;
-               subnet_ipv4_t ipv4;
-               subnet_ipv6_t ipv6;
-       } net;
-} subnet_t;
-
-#define MAXNETSTR 64
-
-extern splay_tree_t *subnet_tree;
-
-extern int subnet_compare(const struct subnet_t *, const struct subnet_t *);
-extern subnet_t *new_subnet(void) __attribute__ ((__malloc__));
-extern void free_subnet(subnet_t *);
-extern void init_subnets(void);
-extern void exit_subnets(void);
-extern splay_tree_t *new_subnet_tree(void) __attribute__ ((__malloc__));
-extern void free_subnet_tree(splay_tree_t *);
-extern void subnet_add(struct node_t *, subnet_t *);
-extern void subnet_del(struct node_t *, subnet_t *);
-extern void subnet_update(struct node_t *, subnet_t *, bool);
-extern int maskcmp(const void *, const void *, int);
-extern void maskcpy(void *, const void *, int, int);
-extern void mask(void *, int, int);
-extern bool maskcheck(const void *, int, int);
-extern bool net2str(char *, int, const subnet_t *);
-extern bool str2net(subnet_t *, const char *);
-extern subnet_t *lookup_subnet(const struct node_t *, const subnet_t *);
-extern subnet_t *lookup_subnet_mac(const struct node_t *, const mac_t *);
-extern subnet_t *lookup_subnet_ipv4(const ipv4_t *);
-extern subnet_t *lookup_subnet_ipv6(const ipv6_t *);
-extern bool dump_subnets(struct connection_t *);
-extern void subnet_cache_flush(void);
-
-#endif /* __TINC_SUBNET_H__ */
diff --git a/src/subnet_parse.c b/src/subnet_parse.c
deleted file mode 100644 (file)
index f980180..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
-    subnet_parse.c -- handle subnet parsing
-    Copyright (C) 2000-2012 Guus Sliepen <guus@tinc-vpn.org>,
-                  2000-2005 Ivo Timmermans
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "system.h"
-
-#include "logger.h"
-#include "net.h"
-#include "netutl.h"
-#include "subnet.h"
-#include "utils.h"
-#include "xalloc.h"
-
-/* Subnet mask handling */
-
-int maskcmp(const void *va, const void *vb, int masklen) {
-       int i, m, result;
-       const char *a = va;
-       const char *b = vb;
-
-       for(m = masklen, i = 0; m >= 8; m -= 8, i++) {
-               result = a[i] - b[i];
-               if(result)
-                       return result;
-       }
-
-       if(m)
-               return (a[i] & (0x100 - (1 << (8 - m)))) -
-                       (b[i] & (0x100 - (1 << (8 - m))));
-
-       return 0;
-}
-
-void mask(void *va, int masklen, int len) {
-       int i;
-       char *a = va;
-
-       i = masklen / 8;
-       masklen %= 8;
-
-       if(masklen)
-               a[i++] &= (0x100 - (1 << (8 - masklen)));
-
-       for(; i < len; i++)
-               a[i] = 0;
-}
-
-void maskcpy(void *va, const void *vb, int masklen, int len) {
-       int i, m;
-       char *a = va;
-       const char *b = vb;
-
-       for(m = masklen, i = 0; m >= 8; m -= 8, i++)
-               a[i] = b[i];
-
-       if(m) {
-               a[i] = b[i] & (0x100 - (1 << (8 - m)));
-               i++;
-       }
-
-       for(; i < len; i++)
-               a[i] = 0;
-}
-
-bool maskcheck(const void *va, int masklen, int len) {
-       int i;
-       const char *a = va;
-
-       i = masklen / 8;
-       masklen %= 8;
-
-       if(masklen && a[i++] & (0xff >> masklen))
-               return false;
-
-       for(; i < len; i++)
-               if(a[i] != 0)
-                       return false;
-
-       return true;
-}
-
-/* Subnet comparison */
-
-static int subnet_compare_mac(const subnet_t *a, const subnet_t *b) {
-       int result;
-
-       result = memcmp(&a->net.mac.address, &b->net.mac.address, sizeof a->net.mac.address);
-
-       if(result)
-               return result;
-
-       result = a->weight - b->weight;
-
-       if(result || !a->owner || !b->owner)
-               return result;
-
-       return strcmp(a->owner->name, b->owner->name);
-}
-
-static int subnet_compare_ipv4(const subnet_t *a, const subnet_t *b) {
-       int result;
-
-       result = b->net.ipv4.prefixlength - a->net.ipv4.prefixlength;
-
-       if(result)
-               return result;
-
-       result = memcmp(&a->net.ipv4.address, &b->net.ipv4.address, sizeof(ipv4_t));
-
-       if(result)
-               return result;
-
-       result = a->weight - b->weight;
-
-       if(result || !a->owner || !b->owner)
-               return result;
-
-       return strcmp(a->owner->name, b->owner->name);
-}
-
-static int subnet_compare_ipv6(const subnet_t *a, const subnet_t *b) {
-       int result;
-
-       result = b->net.ipv6.prefixlength - a->net.ipv6.prefixlength;
-
-       if(result)
-               return result;
-
-       result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t));
-
-       if(result)
-               return result;
-
-       result = a->weight - b->weight;
-
-       if(result || !a->owner || !b->owner)
-               return result;
-
-       return strcmp(a->owner->name, b->owner->name);
-}
-
-int subnet_compare(const subnet_t *a, const subnet_t *b) {
-       int result;
-
-       result = a->type - b->type;
-
-       if(result)
-               return result;
-
-       switch (a->type) {
-       case SUBNET_MAC:
-               return subnet_compare_mac(a, b);
-       case SUBNET_IPV4:
-               return subnet_compare_ipv4(a, b);
-       case SUBNET_IPV6:
-               return subnet_compare_ipv6(a, b);
-       default:
-               logger(DEBUG_ALWAYS, LOG_ERR, "subnet_compare() was called with unknown subnet type %d, exitting!", a->type);
-               exit(1);
-       }
-
-       return 0;
-}
-
-/* Ascii representation of subnets */
-
-bool str2net(subnet_t *subnet, const char *subnetstr) {
-       int i, l;
-       uint16_t x[8];
-       int weight = 10;
-
-       if(sscanf(subnetstr, "%hu.%hu.%hu.%hu/%d#%d",
-                         &x[0], &x[1], &x[2], &x[3], &l, &weight) >= 5) {
-               if(l < 0 || l > 32)
-                       return false;
-
-               subnet->type = SUBNET_IPV4;
-               subnet->net.ipv4.prefixlength = l;
-               subnet->weight = weight;
-
-               for(int i = 0; i < 4; i++) {
-                       if(x[i] > 255)
-                               return false;
-                       subnet->net.ipv4.address.x[i] = x[i];
-               }
-
-               return true;
-       }
-
-       if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%d",
-                         &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
-                         &l, &weight) >= 9) {
-               if(l < 0 || l > 128)
-                       return false;
-
-               subnet->type = SUBNET_IPV6;
-               subnet->net.ipv6.prefixlength = l;
-               subnet->weight = weight;
-
-               for(i = 0; i < 8; i++)
-                       subnet->net.ipv6.address.x[i] = htons(x[i]);
-
-               return true;
-       }
-
-       if(sscanf(subnetstr, "%hu.%hu.%hu.%hu#%d", &x[0], &x[1], &x[2], &x[3], &weight) >= 4) {
-               subnet->type = SUBNET_IPV4;
-               subnet->net.ipv4.prefixlength = 32;
-               subnet->weight = weight;
-
-               for(i = 0; i < 4; i++) {
-                       if(x[i] > 255)
-                               return false;
-                       subnet->net.ipv4.address.x[i] = x[i];
-               }
-
-               return true;
-       }
-
-       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], &weight) >= 8) {
-               subnet->type = SUBNET_IPV6;
-               subnet->net.ipv6.prefixlength = 128;
-               subnet->weight = weight;
-
-               for(i = 0; i < 8; i++)
-                       subnet->net.ipv6.address.x[i] = htons(x[i]);
-
-               return true;
-       }
-
-       if(sscanf(subnetstr, "%hx:%hx:%hx:%hx:%hx:%hx#%d",
-                         &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &weight) >= 6) {
-               subnet->type = SUBNET_MAC;
-               subnet->weight = weight;
-
-               for(i = 0; i < 6; i++)
-                       subnet->net.mac.address.x[i] = x[i];
-
-               return true;
-       }
-
-       // IPv6 short form
-       if(strstr(subnetstr, "::")) {
-               const char *p;
-               char *q;
-               int colons = 0;
-
-               // Count number of colons
-               for(p = subnetstr; *p; p++)
-                       if(*p == ':')
-                               colons++;
-
-               if(colons > 7)
-                       return false;
-
-               // Scan numbers before the double colon
-               p = subnetstr;
-               for(i = 0; i < colons; i++) {
-                       if(*p == ':')
-                               break;
-                       x[i] = strtoul(p, &q, 0x10);
-                       if(!q || p == q || *q != ':')
-                               return false;
-                       p = ++q;
-               }
-
-               p++;
-               colons -= i;
-               if(!i) {
-                       p++;
-                       colons--;
-               }
-
-               if(!*p || *p == '/' || *p == '#')
-                       colons--;
-
-               // Fill in the blanks
-               for(; i < 8 - colons; i++)
-                       x[i] = 0;
-
-               // Scan the remaining numbers
-               for(; i < 8; i++) {
-                       x[i] = strtoul(p, &q, 0x10);
-                       if(!q || p == q)
-                               return false;
-                       if(i == 7) {
-                               p = q;
-                               break;
-                       }
-                       if(*q != ':')
-                               return false;
-                       p = ++q;
-               }
-
-               l = 128;
-               if(*p == '/')
-                       sscanf(p, "/%d#%d", &l, &weight);
-               else if(*p == '#')
-                       sscanf(p, "#%d", &weight);
-
-               if(l < 0 || l > 128)
-                       return false;
-
-               subnet->type = SUBNET_IPV6;
-               subnet->net.ipv6.prefixlength = l;
-               subnet->weight = weight;
-
-               for(i = 0; i < 8; i++)
-                       subnet->net.ipv6.address.x[i] = htons(x[i]);
-
-               return true;
-       }
-
-       return false;
-}
-
-bool net2str(char *netstr, int len, const subnet_t *subnet) {
-       if(!netstr || !subnet) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with netstr=%p, subnet=%p!", netstr, subnet);
-               return false;
-       }
-
-       switch (subnet->type) {
-               case SUBNET_MAC:
-                       snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx#%d",
-                                        subnet->net.mac.address.x[0],
-                                        subnet->net.mac.address.x[1],
-                                        subnet->net.mac.address.x[2],
-                                        subnet->net.mac.address.x[3],
-                                        subnet->net.mac.address.x[4],
-                                        subnet->net.mac.address.x[5],
-                                        subnet->weight);
-                       break;
-
-               case SUBNET_IPV4:
-                       snprintf(netstr, len, "%hu.%hu.%hu.%hu/%d#%d",
-                                        subnet->net.ipv4.address.x[0],
-                                        subnet->net.ipv4.address.x[1],
-                                        subnet->net.ipv4.address.x[2],
-                                        subnet->net.ipv4.address.x[3],
-                                        subnet->net.ipv4.prefixlength,
-                                        subnet->weight);
-                       break;
-
-               case SUBNET_IPV6:
-                       snprintf(netstr, len, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx/%d#%d",
-                                        ntohs(subnet->net.ipv6.address.x[0]),
-                                        ntohs(subnet->net.ipv6.address.x[1]),
-                                        ntohs(subnet->net.ipv6.address.x[2]),
-                                        ntohs(subnet->net.ipv6.address.x[3]),
-                                        ntohs(subnet->net.ipv6.address.x[4]),
-                                        ntohs(subnet->net.ipv6.address.x[5]),
-                                        ntohs(subnet->net.ipv6.address.x[6]),
-                                        ntohs(subnet->net.ipv6.address.x[7]),
-                                        subnet->net.ipv6.prefixlength,
-                                        subnet->weight);
-                       break;
-
-               default:
-                       logger(DEBUG_ALWAYS, LOG_ERR, "net2str() was called with unknown subnet type %d, exiting!", subnet->type);
-                       exit(1);
-       }
-
-       return true;
-}