1b6336dcd168488886aaff62b1c17140126be4b4
[tinc] / src / route.c
1 /*
2     route.c -- routing
3     Copyright (C) 2000,2001 Ivo Timmermans <itimmermans@bigfoot.com>,
4                   2000,2001 Guus Sliepen <guus@sliepen.warande.net>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20     $Id: route.c,v 1.1.2.9 2001/05/28 08:21:43 guus Exp $
21 */
22
23 #include "config.h"
24
25 #ifdef HAVE_FREEBSD
26  #include <sys/param.h>
27 #else
28  #include <netinet/in.h>
29 #endif
30 #include <utils.h>
31 #include <xalloc.h>
32 #include <syslog.h>
33
34 #include "net.h"
35 #include "connection.h"
36 #include "subnet.h"
37 #include "route.h"
38
39 #include "system.h"
40
41 int routing_mode = RMODE_ROUTER;
42 subnet_t mymac;
43
44 void learn_mac(connection_t *source, mac_t *address)
45 {
46   subnet_t *subnet;
47 cp
48   subnet = lookup_subnet_mac(address);
49   
50   if(!subnet)
51     {
52       subnet = new_subnet();
53       subnet->type = SUBNET_MAC;
54 //      subnet->lasttime = gettimeofday();
55       memcpy(&subnet->net.mac.address, address, sizeof(mac_t));
56       subnet_add(source, subnet);
57
58       if(debug_lvl >= DEBUG_TRAFFIC)
59         {
60           syslog(LOG_DEBUG, _("Learned new MAC address %x:%x:%x:%x:%x:%x from %s (%s)"),
61                address->x[0],
62                address->x[1],
63                address->x[2],
64                address->x[3],
65                address->x[4],
66                address->x[5],
67                source->name, source->hostname);
68         }
69     }
70 }
71
72 connection_t *route_mac(connection_t *source, vpn_packet_t *packet)
73 {
74   subnet_t *subnet;
75 cp
76   /* Learn source address */
77
78   learn_mac(source, (mac_t *)(&packet->data[0]));
79   
80   /* Lookup destination address */
81     
82   subnet = lookup_subnet_mac((mac_t *)(&packet->data[6]));
83
84   if(!subnet)
85     {
86       if(debug_lvl >= DEBUG_TRAFFIC)
87         {
88           syslog(LOG_WARNING, _("Cannot route packet: unknown destination address %x:%x:%x:%x:%x:%x"),
89                  packet->data[6],
90                  packet->data[7],
91                  packet->data[8],
92                  packet->data[9],
93                  packet->data[10],
94                  packet->data[11]);
95         } 
96       return NULL;
97     }
98 cp  
99   return subnet->owner;  
100 }
101
102 connection_t *route_ipv4(vpn_packet_t *packet)
103 {
104   ipv4_t dest;
105   subnet_t *subnet;
106 cp
107   dest = ntohl(*((unsigned long*)(&packet->data[30])));
108   
109   subnet = lookup_subnet_ipv4(&dest);
110
111   if(!subnet)
112     {
113       if(debug_lvl >= DEBUG_TRAFFIC)
114         {
115           syslog(LOG_WARNING, _("Cannot route packet: unknown destination address %d.%d.%d.%d"),
116                  packet->data[30], packet->data[31], packet->data[32], packet->data[33]);
117         }
118
119       return NULL;
120     }
121 cp
122   return subnet->owner;  
123 }
124
125 connection_t *route_ipv6(vpn_packet_t *packet)
126 {
127 cp
128   if(debug_lvl > DEBUG_NOTHING)
129     {
130       syslog(LOG_WARNING, _("Cannot route packet: IPv6 routing not yet implemented"));
131     } 
132 cp
133   return NULL;
134 }
135
136 void route_outgoing(vpn_packet_t *packet)
137 {
138   unsigned short int type;
139   avl_node_t *node;
140   connection_t *cl;
141 cp
142   /* FIXME: multicast? */
143
144   switch(routing_mode)
145     {
146       case RMODE_ROUTER:
147         type = ntohs(*((unsigned short*)(&packet->data[12])));
148         switch(type)
149           {
150             case 0x0800:
151               cl = route_ipv4(packet);
152               break;
153             case 0x86DD:
154               cl = route_ipv6(packet);
155               break;
156             default:
157               if(debug_lvl >= DEBUG_TRAFFIC)
158                 {
159                   syslog(LOG_WARNING, _("Cannot route packet: unknown type %hx"), type);
160                 }
161               return;
162            }
163          if(cl)
164            send_packet(cl, packet);
165          break;
166         
167       case RMODE_SWITCH:
168         cl = route_mac(myself, packet);
169         if(cl)
170           send_packet(cl, packet);
171         break;
172         
173       case RMODE_HUB:
174         for(node = connection_tree->head; node; node = node->next)
175           {
176             cl = (connection_t *)node->data;
177             if(cl->status.active)
178               send_packet(cl, packet);
179           }
180         break;
181     }
182 }
183
184 void route_incoming(connection_t *source, vpn_packet_t *packet)
185 {
186   switch(routing_mode)
187     {
188       case RMODE_ROUTER:
189         memcpy(packet->data, mymac.net.mac.address.x, 6);
190         break;
191       case RMODE_SWITCH:
192         learn_mac(source, (mac_t *)(&packet->data[0]));
193         break;
194     }
195   
196   accept_packet(packet);
197 }