projects
/
tinc
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
get_config_subnet needs to be fixed.
[tinc]
/
src
/
route.c
diff --git
a/src/route.c
b/src/route.c
index
2c3cc0d
..
8df8128
100644
(file)
--- a/
src/route.c
+++ b/
src/route.c
@@
-17,7
+17,7
@@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: route.c,v 1.1.2.
11 2001/06/05 16:09:55 guus
Exp $
+ $Id: route.c,v 1.1.2.
21 2001/11/16 17:40:50 zarq
Exp $
*/
#include "config.h"
*/
#include "config.h"
@@
-27,59
+27,71
@@
#endif
#include <sys/socket.h>
#include <netinet/in.h>
#endif
#include <sys/socket.h>
#include <netinet/in.h>
-#include <net/ethernet.h>
+#ifdef HAVE_SOLARIS
+ #include <net/if.h>
+ #define ETHER_ADDR_LEN 6
+#else
+ #include <net/ethernet.h>
+#endif
#include <netinet/if_ether.h>
#include <utils.h>
#include <xalloc.h>
#include <syslog.h>
#include <netinet/if_ether.h>
#include <utils.h>
#include <xalloc.h>
#include <syslog.h>
+#include <string.h>
+
+#include <avl_tree.h>
#include "net.h"
#include "net.h"
-#include "net/ethernet.h"
-#include "netinet/if_ether.h"
#include "connection.h"
#include "subnet.h"
#include "route.h"
#include "connection.h"
#include "subnet.h"
#include "route.h"
+#include "protocol.h"
+#include "device.h"
#include "system.h"
int routing_mode = RMODE_ROUTER;
subnet_t mymac;
#include "system.h"
int routing_mode = RMODE_ROUTER;
subnet_t mymac;
-void learn_mac(
connection_t *source,
mac_t *address)
+void learn_mac(mac_t *address)
{
subnet_t *subnet;
{
subnet_t *subnet;
+ avl_node_t *node;
+ connection_t *c;
cp
subnet = lookup_subnet_mac(address);
cp
subnet = lookup_subnet_mac(address);
+
+ /* If we don't know this MAC address yet, store it */
- if(!subnet)
+ if(!subnet
|| subnet->owner!=myself
)
{
{
+ if(debug_lvl >= DEBUG_TRAFFIC)
+ syslog(LOG_INFO, _("Learned new MAC address %hhx:%hhx:%hhx:%hhx:%hhx:%hhx"),
+ 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 = new_subnet();
subnet->type = SUBNET_MAC;
-// subnet->lasttime = gettimeofday();
memcpy(&subnet->net.mac.address, address, sizeof(mac_t));
memcpy(&subnet->net.mac.address, address, sizeof(mac_t));
- subnet_add(
source
, subnet);
+ subnet_add(
myself
, subnet);
- if(debug_lvl >= DEBUG_TRAFFIC)
+ /* And tell all other tinc daemons it's our MAC */
+
+ for(node = connection_tree->head; node; node = node->next)
{
{
- syslog(LOG_DEBUG, _("Learned new MAC address %x:%x:%x:%x:%x:%x from %s (%s)"),
- address->x[0],
- address->x[1],
- address->x[2],
- address->x[3],
- address->x[4],
- address->x[5],
- source->name, source->hostname);
+ c = (connection_t *)node->data;
+ if(c->status.active)
+ send_add_subnet(c, subnet);
}
}
}
}
}
}
-
connection_t *route_mac(connection_t *source,
vpn_packet_t *packet)
+
node_t *route_mac(
vpn_packet_t *packet)
{
subnet_t *subnet;
cp
/* Learn source address */
{
subnet_t *subnet;
cp
/* Learn source address */
- learn_mac(
source,
(mac_t *)(&packet->data[6]));
+ learn_mac((mac_t *)(&packet->data[6]));
/* Lookup destination address */
/* Lookup destination address */
@@
-91,21
+103,10
@@
cp
return NULL;
}
return NULL;
}
-connection_t *route_ipv4(vpn_packet_t *packet)
-{
- ipv4_t dest;
- subnet_t *subnet;
-cp
- dest = ntohl(*((unsigned long*)(&packet->data[30])));
-
- subnet = lookup_subnet_ipv4(&dest);
-
if(!subnet)
{
if(debug_lvl >= DEBUG_TRAFFIC)
{
if(!subnet)
{
if(debug_lvl >= DEBUG_TRAFFIC)
{
- syslog(LOG_WARNING, _("Cannot route packet: unknown destination address %d.%d.%d.%d"),
- packet->data[30], packet->data[31], packet->data[32], packet->data[33]);
}
return NULL;
}
return NULL;
@@
-114,15
+115,27
@@
cp
return subnet->owner;
}
return subnet->owner;
}
-
connection_t *route_ipv6
(vpn_packet_t *packet)
+
node_t *route_ip
(vpn_packet_t *packet)
{
{
+ struct addrinfo *dest;
+ subnet_t *subnet;
+cp
+#warning FIXME
+ memcpy(&dest, &packet->data[30], 0);
+
+ subnet = lookup_subnet_ip(&dest);
cp
cp
- if(
debug_lvl > DEBUG_NOTHING
)
+ if(
!subnet
)
{
{
- syslog(LOG_WARNING, _("Cannot route packet: IPv6 routing not yet implemented"));
- }
+ if(debug_lvl >= DEBUG_TRAFFIC)
+ {
+ syslog(LOG_WARNING, _("Cannot route packet: unknown IP destination address"));
+ }
+
+ return NULL;
+ }
cp
cp
- return
NULL;
+ return
subnet->owner;
}
void route_arp(vpn_packet_t *packet)
}
void route_arp(vpn_packet_t *packet)
@@
-130,8
+143,12
@@
void route_arp(vpn_packet_t *packet)
struct ether_arp *arp;
subnet_t *subnet;
unsigned char ipbuf[4];
struct ether_arp *arp;
subnet_t *subnet;
unsigned char ipbuf[4];
-
ipv4_t
dest;
+
struct addrinfo *
dest;
cp
cp
+ /* First, snatch the source address from the ARP packet */
+
+ memcpy(mymac.net.mac.address.x, packet->data + 6, 6);
+
/* This routine generates replies to ARP requests.
You don't need to set NOARP flag on the interface anymore (which is broken on FreeBSD).
Most of the code here is taken from choparp.c by Takamichi Tateoka (tree@mma.club.uec.ac.jp)
/* This routine generates replies to ARP requests.
You don't need to set NOARP flag on the interface anymore (which is broken on FreeBSD).
Most of the code here is taken from choparp.c by Takamichi Tateoka (tree@mma.club.uec.ac.jp)
@@
-155,9
+172,9
@@
cp
}
/* Check if the IP address exists on the VPN */
}
/* Check if the IP address exists on the VPN */
-
+#warning FIXME
dest = ntohl(*((unsigned long*)(arp->arp_tpa)));
dest = ntohl(*((unsigned long*)(arp->arp_tpa)));
- subnet = lookup_subnet_ip
v4
(&dest);
+ subnet = lookup_subnet_ip(&dest);
if(!subnet)
{
if(!subnet)
{
@@
-186,14
+203,14
@@
cp
memcpy(arp->arp_sha, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* add fake source hard addr */
arp->arp_op = htons(ARPOP_REPLY);
memcpy(arp->arp_sha, packet->data + ETHER_ADDR_LEN, ETHER_ADDR_LEN); /* add fake source hard addr */
arp->arp_op = htons(ARPOP_REPLY);
-
accept
_packet(packet);
+
write
_packet(packet);
cp
}
void route_outgoing(vpn_packet_t *packet)
{
unsigned short int type;
cp
}
void route_outgoing(vpn_packet_t *packet)
{
unsigned short int type;
-
connection_t *cl
;
+
node_t *n
;
cp
/* FIXME: multicast? */
cp
/* FIXME: multicast? */
@@
-204,10
+221,10
@@
cp
switch(type)
{
case 0x0800:
switch(type)
{
case 0x0800:
-
cl
= route_ipv4(packet);
+
n
= route_ipv4(packet);
break;
case 0x86DD:
break;
case 0x86DD:
-
cl
= route_ipv6(packet);
+
n
= route_ipv6(packet);
break;
case 0x0806:
route_arp(packet);
break;
case 0x0806:
route_arp(packet);
@@
-219,14
+236,14
@@
cp
}
return;
}
}
return;
}
- if(
cl
)
- send_packet(
cl
, packet);
+ if(
n
)
+ send_packet(
n
, packet);
break;
case RMODE_SWITCH:
break;
case RMODE_SWITCH:
-
cl = route_mac(myself,
packet);
- if(
cl
)
- send_packet(
cl
, packet);
+
n = route_mac(
packet);
+ if(
n
)
+ send_packet(
n
, packet);
else
broadcast_packet(myself, packet);
break;
else
broadcast_packet(myself, packet);
break;
@@
-237,23
+254,37
@@
cp
}
}
}
}
-void route_incoming(
connection
_t *source, vpn_packet_t *packet)
+void route_incoming(
node
_t *source, vpn_packet_t *packet)
{
switch(routing_mode)
{
case RMODE_ROUTER:
memcpy(packet->data, mymac.net.mac.address.x, 6); /* Override destination address to make the kernel accept it */
{
switch(routing_mode)
{
case RMODE_ROUTER:
memcpy(packet->data, mymac.net.mac.address.x, 6); /* Override destination address to make the kernel accept it */
+ write_packet(packet);
break;
case RMODE_SWITCH:
break;
case RMODE_SWITCH:
- if((packet->data[0] & packet->data[1]) == 0xFF) /* Broadcast? */
- broadcast_packet(source, packet); /* If yes, spread it on */
- else
- learn_mac(source, (mac_t *)(&packet->data[6]));
+ {
+ subnet_t *subnet;
+
+ subnet = lookup_subnet_mac((mac_t *)(&packet->data[0]));
+
+ if(subnet)
+ {
+ if(subnet->owner == myself)
+ write_packet(packet);
+ else
+ send_packet(subnet->owner, packet);
+ }
+ else
+ {
+ broadcast_packet(source, packet);
+ write_packet(packet);
+ }
+ }
break;
case RMODE_HUB:
break;
case RMODE_HUB:
- broadcast_packet(source,packet); /* Spread it on */
+ broadcast_packet(source, packet); /* Spread it on */
+ write_packet(packet);
break;
}
break;
}
-
- accept_packet(packet);
}
}