forked from pool/strongswan
44 lines
1.1 KiB
Plaintext
44 lines
1.1 KiB
Plaintext
--- src/charon/kernel/kernel_interface.c
|
|
+++ src/charon/kernel/kernel_interface.c 2008/10/14 14:10:13
|
|
@@ -1643,26 +1643,29 @@ static status_t manage_rule(private_kern
|
|
*/
|
|
static bool addr_in_subnet(chunk_t addr, chunk_t net, int net_len)
|
|
{
|
|
- int bit, byte;
|
|
+ static const u_char mask[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
|
|
+ int byte = 0;
|
|
|
|
- if (addr.len != net.len)
|
|
+ if (addr.len != net.len || net_len > 8 * net.len )
|
|
{
|
|
return FALSE;
|
|
}
|
|
- /* scan through all bits, beginning in the front */
|
|
- for (byte = 0; byte < addr.len; byte++)
|
|
+
|
|
+ /* scan through all bytes in network order */
|
|
+ while (net_len > 0)
|
|
{
|
|
- for (bit = 7; bit >= 0; bit--)
|
|
+ if (net_len < 8)
|
|
{
|
|
- /* check if bits are equal (or we reached the end of the net) */
|
|
- if (bit + byte * 8 > net_len)
|
|
- {
|
|
- return TRUE;
|
|
- }
|
|
- if (((1<<bit) & addr.ptr[byte]) != ((1<<bit) & net.ptr[byte]))
|
|
+ return (mask[net_len] & addr.ptr[byte]) == (mask[net_len] & net.ptr[byte]);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ if (addr.ptr[byte] != net.ptr[byte])
|
|
{
|
|
return FALSE;
|
|
}
|
|
+ byte++;
|
|
+ net_len -= 8;
|
|
}
|
|
}
|
|
return TRUE;
|