2
* OpenVPN -- An application to securely tunnel IP networks
3
* over a single TCP/UDP port, with support for SSL/TLS-based
4
* session authentication and key exchange,
5
* packet encryption, packet authentication, and
8
* Copyright (C) 2002-2004 James Yonan <jim@yonan.net>
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program (see the file COPYING included with this
22
* distribution); if not, write to the Free Software Foundation, Inc.,
23
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
#include "config-win32.h"
44
mroute_addr_init (struct mroute_addr *addr)
50
* Ethernet multicast addresses.
54
is_mac_mcast_addr (const uint8_t *mac)
56
return (bool) mac[0] & 1;
60
is_mac_mcast_maddr (const struct mroute_addr *addr)
62
return (addr->type & MR_ADDR_MASK) == MR_ADDR_ETHER && is_mac_mcast_addr (addr->addr);
66
* Don't learn certain addresses.
69
mroute_learnable_address (const struct mroute_addr *addr)
72
bool not_all_zeros = false;
73
bool not_all_ones = false;
75
for (i = 0; i < addr->len; ++i)
77
int b = addr->addr[i];
83
return not_all_zeros && not_all_ones && !is_mac_mcast_maddr (addr);
87
* Given a raw packet in buf, return the src and dest
88
* addresses of the packet.
91
mroute_extract_addr_from_packet (struct mroute_addr *src,
92
struct mroute_addr *dest,
98
if (tunnel_type == DEV_TYPE_TUN)
102
switch (OPENVPN_IPH_GET_VER (*BPTR(buf)))
105
if (BLEN (buf) >= (int) sizeof (struct openvpn_iphdr))
107
const struct openvpn_iphdr *ip = (const struct openvpn_iphdr *) BPTR (buf);
110
src->type = MR_ADDR_IPV4;
113
memcpy (src->addr, &ip->saddr, 4);
117
dest->type = MR_ADDR_IPV4;
120
memcpy (dest->addr, &ip->daddr, 4);
123
if ((ip->daddr & htonl(IP_MCAST_SUBNET_MASK)) == htonl(IP_MCAST_NETWORK))
124
ret |= MROUTE_EXTRACT_MCAST;
127
if (ip->protocol == OPENVPN_IPPROTO_IGMP)
128
ret |= MROUTE_EXTRACT_IGMP;
130
ret |= MROUTE_EXTRACT_SUCCEEDED;
135
msg (M_WARN, "Need IPv6 code in mroute_extract_addr_from_packet");
141
else if (tunnel_type == DEV_TYPE_TAP)
143
if (BLEN (buf) >= (int) sizeof (struct openvpn_ethhdr))
145
const struct openvpn_ethhdr *eth = (const struct openvpn_ethhdr *) BPTR (buf);
148
src->type = MR_ADDR_ETHER;
151
memcpy (src->addr, eth->source, 6);
155
dest->type = MR_ADDR_ETHER;
158
memcpy (dest->addr, eth->dest, 6);
160
/* ethernet broadcast/multicast packet? */
161
if (is_mac_mcast_addr (eth->dest))
162
ret |= MROUTE_EXTRACT_BCAST;
165
ret |= MROUTE_EXTRACT_SUCCEEDED;
172
* Translate a struct sockaddr_in (saddr)
173
* to a struct mroute_addr (addr).
176
mroute_extract_sockaddr_in (struct mroute_addr *addr, const struct sockaddr_in *saddr, bool use_port)
178
if (saddr->sin_family == AF_INET)
182
addr->type = MR_ADDR_IPV4 | MR_WITH_PORT;
185
memcpy (addr->addr, &saddr->sin_addr.s_addr, 4);
186
memcpy (addr->addr + 4, &saddr->sin_port, 2);
190
addr->type = MR_ADDR_IPV4;
193
memcpy (addr->addr, &saddr->sin_addr.s_addr, 4);
201
* Zero off the host bits in an address, leaving
202
* only the network bits, using the netbits member of
203
* struct mroute_addr as the controlling parameter.
206
mroute_addr_mask_host_bits (struct mroute_addr *ma)
208
in_addr_t addr = ntohl(*(in_addr_t*)ma->addr);
209
ASSERT ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4);
210
addr &= netbits_to_netmask (ma->netbits);
211
*(in_addr_t*)ma->addr = htonl (addr);
215
* The mroute_addr hash function takes into account the
216
* address type, number of bits in the network address,
217
* and the actual address.
220
mroute_addr_hash_function (const void *key, uint32_t iv)
222
return hash_func (mroute_addr_hash_ptr ((const struct mroute_addr *) key),
223
mroute_addr_hash_len ((const struct mroute_addr *) key),
228
mroute_addr_compare_function (const void *key1, const void *key2)
230
return mroute_addr_equal ((const struct mroute_addr *) key1,
231
(const struct mroute_addr *) key2);
235
mroute_addr_print (const struct mroute_addr *ma,
238
struct buffer out = alloc_buf_gc (64, gc);
241
struct mroute_addr maddr = *ma;
243
switch (maddr.type & MR_ADDR_MASK)
246
buf_printf (&out, "%s", format_hex_ex (ma->addr, 6, 0, 1, ":", gc));
254
buf_set_read (&buf, maddr.addr, maddr.len);
255
addr = buf_read_u32 (&buf, &status);
258
buf_printf (&out, "%s", print_in_addr_t (addr, IA_EMPTY_IF_UNDEF, gc));
259
if (maddr.type & MR_WITH_NETBITS)
260
buf_printf (&out, "/%d", maddr.netbits);
262
if (maddr.type & MR_WITH_PORT)
264
port = buf_read_u16 (&buf);
266
buf_printf (&out, ":%d", port);
271
buf_printf (&out, "IPV6");
274
buf_printf (&out, "UNKNOWN");
284
* mroute_helper's main job is keeping track of
285
* currently used CIDR netlengths, so we don't
286
* have to cycle through all 33.
289
struct mroute_helper *
290
mroute_helper_init (int ageable_ttl_secs)
292
struct mroute_helper *mh;
293
ALLOC_OBJ_CLEAR (mh, struct mroute_helper);
294
//mutex_init (&mh->mutex);
295
mh->ageable_ttl_secs = ageable_ttl_secs;
300
mroute_helper_regenerate (struct mroute_helper *mh)
303
for (i = MR_HELPER_NET_LEN - 1; i >= 0; --i)
305
if (mh->net_len_refcount[i] > 0)
306
mh->net_len[j++] = (uint8_t) i;
311
if (check_debug_level (D_MULTI_DEBUG))
313
struct gc_arena gc = gc_new ();
314
struct buffer out = alloc_buf_gc (256, &gc);
315
buf_printf (&out, "MROUTE CIDR netlen:");
316
for (i = 0; i < mh->n_net_len; ++i)
318
buf_printf (&out, " /%d", mh->net_len[i]);
320
dmsg (D_MULTI_DEBUG, "%s", BSTR (&out));
327
mroute_helper_add_iroute (struct mroute_helper *mh, const struct iroute *ir)
329
if (ir->netbits >= 0)
331
ASSERT (ir->netbits < MR_HELPER_NET_LEN);
332
mroute_helper_lock (mh);
333
++mh->cache_generation;
334
++mh->net_len_refcount[ir->netbits];
335
if (mh->net_len_refcount[ir->netbits] == 1)
336
mroute_helper_regenerate (mh);
337
mroute_helper_unlock (mh);
342
mroute_helper_del_iroute (struct mroute_helper *mh, const struct iroute *ir)
344
if (ir->netbits >= 0)
346
ASSERT (ir->netbits < MR_HELPER_NET_LEN);
347
mroute_helper_lock (mh);
348
++mh->cache_generation;
349
--mh->net_len_refcount[ir->netbits];
350
ASSERT (mh->net_len_refcount[ir->netbits] >= 0);
351
if (!mh->net_len_refcount[ir->netbits])
352
mroute_helper_regenerate (mh);
353
mroute_helper_unlock (mh);
358
mroute_helper_free (struct mroute_helper *mh)
360
//mutex_destroy (&mh->mutex);
365
static void dummy(void) {}
366
#endif /* P2MP_SERVER */