Forward packets in router mode.
[tinc] / src / route.c
index c8de7a5..e9451c8 100644 (file)
@@ -1,7 +1,7 @@
 /*
     route.c -- routing
-    Copyright (C) 2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>,
-                  2000,2001 Guus Sliepen <guus@sliepen.warande.net>
+    Copyright (C) 2000-2002 Ivo Timmermans <itimmermans@bigfoot.com>,
+                  2000-2002 Guus Sliepen <guus@sliepen.warande.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     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.19 2001/10/27 12:13:17 guus Exp $
+    $Id: route.c,v 1.1.2.24 2002/02/20 16:04:59 guus Exp $
 */
 
 #include "config.h"
 
-#ifdef HAVE_FREEBSD
+#if defined(HAVE_FREEBSD) || defined(HAVE_OPENBSD)
  #include <sys/param.h>
 #endif
 #include <sys/socket.h>
 #include <netinet/in.h>
-#ifdef HAVE_SOLARIS
+#if defined(HAVE_SOLARIS) || defined(HAVE_OPENBSD)
  #include <net/if.h>
  #define ETHER_ADDR_LEN 6
 #else
@@ -46,6 +46,7 @@
 #include "subnet.h"
 #include "route.h"
 #include "protocol.h"
+#include "device.h"
 
 #include "system.h"
 
@@ -65,7 +66,7 @@ cp
   if(!subnet || subnet->owner!=myself)
     {
       if(debug_lvl >= DEBUG_TRAFFIC)
-        syslog(LOG_INFO, _("Learned new MAC address %hhx:%hhx:%hhx:%hhx:%hhx:%hhx"),
+        syslog(LOG_INFO, _("Learned new MAC address %hx:%hx:%hx:%hx:%hx:%hx"),
                address->x[0], address->x[1], address->x[2], address->x[3],  address->x[4], address->x[5]);
                
       subnet = new_subnet();
@@ -104,23 +105,15 @@ cp
 
 node_t *route_ipv4(vpn_packet_t *packet)
 {
-  ipv4_t dest;
   subnet_t *subnet;
 cp
-#ifdef HAVE_SOLARIS
-  /* The other form gives bus errors on a SparcStation 20. */
-  dest = ((packet->data[30] * 0x100 + packet->data[31]) * 0x100 + packet->data[32]) * 0x100 + packet->data[33];
-#else
-  dest = ntohl(*((unsigned long*)(&packet->data[30])));
-#endif
-cp  
-  subnet = lookup_subnet_ipv4(&dest);
+  subnet = lookup_subnet_ipv4((ipv4_t *)&packet->data[30]);
 cp
   if(!subnet)
     {
       if(debug_lvl >= DEBUG_TRAFFIC)
         {
-          syslog(LOG_WARNING, _("Cannot route packet: unknown destination address %d.%d.%d.%d"),
+          syslog(LOG_WARNING, _("Cannot route packet: unknown IPv4 destination address %d.%d.%d.%d"),
                  packet->data[30], packet->data[31], packet->data[32], packet->data[33]);
         }
 
@@ -132,18 +125,23 @@ cp
 
 node_t *route_ipv6(vpn_packet_t *packet)
 {
-  ipv6_t dest;
   subnet_t *subnet;
 cp
-  memcpy(&dest, &packet->data[30], sizeof(ipv6_t));
-
-  subnet = lookup_subnet_ipv6(&dest);
+  subnet = lookup_subnet_ipv6((ipv6_t *)&packet->data[38]);
 cp
   if(!subnet)
     {
       if(debug_lvl >= DEBUG_TRAFFIC)
         {
-          syslog(LOG_WARNING, _("Cannot route packet: unknown IPv6 destination address"));
+          syslog(LOG_WARNING, _("Cannot route packet: unknown IPv6 destination address %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"),
+           ntohs(*(short unsigned int *)&packet->data[38]),
+           ntohs(*(short unsigned int *)&packet->data[40]),
+           ntohs(*(short unsigned int *)&packet->data[42]),
+           ntohs(*(short unsigned int *)&packet->data[44]),
+           ntohs(*(short unsigned int *)&packet->data[46]),
+           ntohs(*(short unsigned int *)&packet->data[48]),
+           ntohs(*(short unsigned int *)&packet->data[50]),
+           ntohs(*(short unsigned int *)&packet->data[52]));
         }
 
       return NULL;
@@ -157,7 +155,6 @@ void route_arp(vpn_packet_t *packet)
   struct ether_arp *arp;
   subnet_t *subnet;
   unsigned char ipbuf[4];
-  ipv4_t dest;
 cp
   /* First, snatch the source address from the ARP packet */
 
@@ -187,8 +184,7 @@ cp
 
   /* Check if the IP address exists on the VPN */
 
-  dest = ntohl(*((unsigned long*)(arp->arp_tpa)));
-  subnet = lookup_subnet_ipv4(&dest);
+  subnet = lookup_subnet_ipv4((ipv4_t *)arp->arp_tpa);
 
   if(!subnet)
     {
@@ -217,7 +213,7 @@ cp
   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
 }
 
@@ -273,8 +269,22 @@ 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 */
-        accept_packet(packet);
+        {
+          node_t *n;
+
+          n = route_ipv4(packet);
+
+          if(n)
+            {
+              if(n == myself)
+               {
+                  memcpy(packet->data, mymac.net.mac.address.x, 6);
+                  write_packet(packet);
+               }
+              else
+                send_packet(n, packet);
+            }
+          }
         break;
       case RMODE_SWITCH:
         {
@@ -285,20 +295,20 @@ void route_incoming(node_t *source, vpn_packet_t *packet)
           if(subnet)
             {
               if(subnet->owner == myself)
-                accept_packet(packet);
+                write_packet(packet);
               else
                 send_packet(subnet->owner, packet);
             }
           else
             {
               broadcast_packet(source, packet);
-              accept_packet(packet);
+              write_packet(packet);
             }
           }
         break;
       case RMODE_HUB:
         broadcast_packet(source, packet);                      /* Spread it on */
-        accept_packet(packet);
+        write_packet(packet);
         break;
     }
 }