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-2005 OpenVPN Solutions LLC <info@openvpn.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 version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "config-win32.h"
43 mroute_addr_init (struct mroute_addr
*addr
)
49 * Ethernet multicast addresses.
53 is_mac_mcast_addr (const uint8_t *mac
)
55 return (bool) mac
[0] & 1;
59 is_mac_mcast_maddr (const struct mroute_addr
*addr
)
61 return (addr
->type
& MR_ADDR_MASK
) == MR_ADDR_ETHER
&& is_mac_mcast_addr (addr
->addr
);
65 * Don't learn certain addresses.
68 mroute_learnable_address (const struct mroute_addr
*addr
)
71 bool not_all_zeros
= false;
72 bool not_all_ones
= false;
74 for (i
= 0; i
< addr
->len
; ++i
)
76 int b
= addr
->addr
[i
];
82 return not_all_zeros
&& not_all_ones
&& !is_mac_mcast_maddr (addr
);
86 * Given a raw packet in buf, return the src and dest
87 * addresses of the packet.
90 mroute_extract_addr_from_packet (struct mroute_addr
*src
,
91 struct mroute_addr
*dest
,
97 if (tunnel_type
== DEV_TYPE_TUN
)
101 switch (OPENVPN_IPH_GET_VER (*BPTR(buf
)))
104 if (BLEN (buf
) >= (int) sizeof (struct openvpn_iphdr
))
106 const struct openvpn_iphdr
*ip
= (const struct openvpn_iphdr
*) BPTR (buf
);
109 src
->type
= MR_ADDR_IPV4
;
112 memcpy (src
->addr
, &ip
->saddr
, 4);
116 dest
->type
= MR_ADDR_IPV4
;
119 memcpy (dest
->addr
, &ip
->daddr
, 4);
122 if ((ip
->daddr
& htonl(IP_MCAST_SUBNET_MASK
)) == htonl(IP_MCAST_NETWORK
))
123 ret
|= MROUTE_EXTRACT_MCAST
;
126 if (ip
->protocol
== OPENVPN_IPPROTO_IGMP
)
127 ret
|= MROUTE_EXTRACT_IGMP
;
129 ret
|= MROUTE_EXTRACT_SUCCEEDED
;
134 msg (M_WARN
, "Need IPv6 code in mroute_extract_addr_from_packet");
140 else if (tunnel_type
== DEV_TYPE_TAP
)
142 if (BLEN (buf
) >= (int) sizeof (struct openvpn_ethhdr
))
144 const struct openvpn_ethhdr
*eth
= (const struct openvpn_ethhdr
*) BPTR (buf
);
147 src
->type
= MR_ADDR_ETHER
;
150 memcpy (src
->addr
, eth
->source
, 6);
154 dest
->type
= MR_ADDR_ETHER
;
157 memcpy (dest
->addr
, eth
->dest
, 6);
159 /* ethernet broadcast/multicast packet? */
160 if (is_mac_mcast_addr (eth
->dest
))
161 ret
|= MROUTE_EXTRACT_BCAST
;
164 ret
|= MROUTE_EXTRACT_SUCCEEDED
;
171 * Translate a struct sockaddr_in (saddr)
172 * to a struct mroute_addr (addr).
175 mroute_extract_sockaddr_in (struct mroute_addr
*addr
, const struct sockaddr_in
*saddr
, bool use_port
)
177 if (saddr
->sin_family
== AF_INET
)
181 addr
->type
= MR_ADDR_IPV4
| MR_WITH_PORT
;
184 memcpy (addr
->addr
, &saddr
->sin_addr
.s_addr
, 4);
185 memcpy (addr
->addr
+ 4, &saddr
->sin_port
, 2);
189 addr
->type
= MR_ADDR_IPV4
;
192 memcpy (addr
->addr
, &saddr
->sin_addr
.s_addr
, 4);
200 * Zero off the host bits in an address, leaving
201 * only the network bits, using the netbits member of
202 * struct mroute_addr as the controlling parameter.
205 mroute_addr_mask_host_bits (struct mroute_addr
*ma
)
207 in_addr_t addr
= ntohl(*(in_addr_t
*)ma
->addr
);
208 ASSERT ((ma
->type
& MR_ADDR_MASK
) == MR_ADDR_IPV4
);
209 addr
&= netbits_to_netmask (ma
->netbits
);
210 *(in_addr_t
*)ma
->addr
= htonl (addr
);
214 * The mroute_addr hash function takes into account the
215 * address type, number of bits in the network address,
216 * and the actual address.
219 mroute_addr_hash_function (const void *key
, uint32_t iv
)
221 return hash_func (mroute_addr_hash_ptr ((const struct mroute_addr
*) key
),
222 mroute_addr_hash_len ((const struct mroute_addr
*) key
),
227 mroute_addr_compare_function (const void *key1
, const void *key2
)
229 return mroute_addr_equal ((const struct mroute_addr
*) key1
,
230 (const struct mroute_addr
*) key2
);
234 mroute_addr_print (const struct mroute_addr
*ma
,
237 struct buffer out
= alloc_buf_gc (64, gc
);
240 struct mroute_addr maddr
= *ma
;
242 switch (maddr
.type
& MR_ADDR_MASK
)
245 buf_printf (&out
, "%s", format_hex_ex (ma
->addr
, 6, 0, 1, ":", gc
));
253 buf_set_read (&buf
, maddr
.addr
, maddr
.len
);
254 addr
= buf_read_u32 (&buf
, &status
);
257 buf_printf (&out
, "%s", print_in_addr_t (addr
, IA_EMPTY_IF_UNDEF
, gc
));
258 if (maddr
.type
& MR_WITH_NETBITS
)
259 buf_printf (&out
, "/%d", maddr
.netbits
);
261 if (maddr
.type
& MR_WITH_PORT
)
263 port
= buf_read_u16 (&buf
);
265 buf_printf (&out
, ":%d", port
);
270 buf_printf (&out
, "IPV6");
273 buf_printf (&out
, "UNKNOWN");
283 * mroute_helper's main job is keeping track of
284 * currently used CIDR netlengths, so we don't
285 * have to cycle through all 33.
288 struct mroute_helper
*
289 mroute_helper_init (int ageable_ttl_secs
)
291 struct mroute_helper
*mh
;
292 ALLOC_OBJ_CLEAR (mh
, struct mroute_helper
);
293 /*mutex_init (&mh->mutex);*/
294 mh
->ageable_ttl_secs
= ageable_ttl_secs
;
299 mroute_helper_regenerate (struct mroute_helper
*mh
)
302 for (i
= MR_HELPER_NET_LEN
- 1; i
>= 0; --i
)
304 if (mh
->net_len_refcount
[i
] > 0)
305 mh
->net_len
[j
++] = (uint8_t) i
;
310 if (check_debug_level (D_MULTI_DEBUG
))
312 struct gc_arena gc
= gc_new ();
313 struct buffer out
= alloc_buf_gc (256, &gc
);
314 buf_printf (&out
, "MROUTE CIDR netlen:");
315 for (i
= 0; i
< mh
->n_net_len
; ++i
)
317 buf_printf (&out
, " /%d", mh
->net_len
[i
]);
319 dmsg (D_MULTI_DEBUG
, "%s", BSTR (&out
));
326 mroute_helper_add_iroute (struct mroute_helper
*mh
, const struct iroute
*ir
)
328 if (ir
->netbits
>= 0)
330 ASSERT (ir
->netbits
< MR_HELPER_NET_LEN
);
331 mroute_helper_lock (mh
);
332 ++mh
->cache_generation
;
333 ++mh
->net_len_refcount
[ir
->netbits
];
334 if (mh
->net_len_refcount
[ir
->netbits
] == 1)
335 mroute_helper_regenerate (mh
);
336 mroute_helper_unlock (mh
);
341 mroute_helper_del_iroute (struct mroute_helper
*mh
, const struct iroute
*ir
)
343 if (ir
->netbits
>= 0)
345 ASSERT (ir
->netbits
< MR_HELPER_NET_LEN
);
346 mroute_helper_lock (mh
);
347 ++mh
->cache_generation
;
348 --mh
->net_len_refcount
[ir
->netbits
];
349 ASSERT (mh
->net_len_refcount
[ir
->netbits
] >= 0);
350 if (!mh
->net_len_refcount
[ir
->netbits
])
351 mroute_helper_regenerate (mh
);
352 mroute_helper_unlock (mh
);
357 mroute_helper_free (struct mroute_helper
*mh
)
359 /*mutex_destroy (&mh->mutex);*/
364 static void dummy(void) {}
365 #endif /* P2MP_SERVER */