Commit 5d82424f authored by Andreas Gustafsson's avatar Andreas Gustafsson
Browse files

New source file netaddr.c; new functions isc_netaddr_eqprefix(),

isc_netaddr_masktoprefixlen(), isc_netaddr_fromsockaddr(),
isc_netaddr_fromin(), isc_netaddr_fromin6(), isc_sockaddr_fromnetaddr();
new result code ISC_R_MASKNONCONTIG
parent 036608c7
......@@ -47,7 +47,7 @@ OBJS = @ISC_EXTRA_OBJS@ \
assertions.@O@ base64.@O@ bitstring.@O@ buffer.@O@ \
bufferlist.@O@ commandline.@O@ error.@O@ event.@O@ heap.@O@ \
lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
mem.@O@ mutexblock.@O@ quota.@O@ random.@O@ \
mem.@O@ mutexblock.@O@ netaddr.@O@ quota.@O@ random.@O@ \
ratelimiter.@O@ result.@O@ rwlock.@O@ \
serial.@O@ sockaddr.@O@ str.@O@ symtab.@O@ \
task.@O@ taskpool.@O@ timer.@O@ version.@O@ \
......@@ -58,7 +58,7 @@ SRCS = @ISC_EXTRA_SRCS@ \
assertions.c base64.c bitstring.c buffer.c \
bufferlist.c commandline.c error.c event.c heap.c \
lex.c lfsr.c lib.c log.c \
mem.c mutexblock.c quota.c random.c \
mem.c mutexblock.c netaddr.c quota.c random.c \
ratelimiter.c result.c rwlock.c \
serial.c sockaddr.c str.c symtab.c \
task.c taskpool.c timer.c version.c
......
......@@ -20,16 +20,48 @@
#include <isc/net.h>
#include <isc/lang.h>
#include <isc/types.h>
ISC_LANG_BEGINDECLS
typedef struct isc_netaddr {
struct isc_netaddr {
unsigned int family;
union {
struct in_addr in;
struct in6_addr in6;
} type;
} isc_netaddr_t;
};
isc_boolean_t
isc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b,
unsigned int prefixlen);
/*
* Compare the 'prefixlen' most significant bits of the network
* addresses 'a' and 'b'. Return ISC_TRUE if they are equal,
* ISC_FALSE if not.
*/
isc_result_t
isc_netaddr_masktoprefixlen(const isc_netaddr_t *s, unsigned int *lenp);
/*
* Convert a netmask in 's' into a prefix length in '*lenp'.
* The mask should consist of zero or more '1' bits in the most
* most significant part of the address, followed by '0' bits.
* If this is not the case, ISC_R_MASKNONCONTIG is returned.
*
* Returns:
* ISC_R_SUCCESS
* ISC_R_MASKNONCONTIG
*/
void
isc_netaddr_fromsockaddr(isc_netaddr_t *netaddr, const isc_sockaddr_t *source);
void
isc_netaddr_fromin(isc_netaddr_t *netaddr, const struct in_addr *ina);
void
isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6);
ISC_LANG_ENDDECLS
......
......@@ -62,8 +62,9 @@ ISC_LANG_BEGINDECLS
#define ISC_R_UNEXPECTED 34
#define ISC_R_ALREADYRUNNING 35
#define ISC_R_IGNORE 36
#define ISC_R_MASKNONCONTIG 37
#define ISC_R_NRESULTS 37 /* Number of results */
#define ISC_R_NRESULTS 38 /* Number of results */
char * isc_result_totext(isc_result_t);
isc_result_t isc_result_register(unsigned int base,
......
......@@ -22,10 +22,11 @@
#include <isc/net.h>
#include <isc/list.h>
#include <isc/lang.h>
#include <isc/types.h>
ISC_LANG_BEGINDECLS
typedef struct isc_sockaddr {
struct isc_sockaddr {
union {
struct sockaddr sa;
struct sockaddr_in sin;
......@@ -33,7 +34,7 @@ typedef struct isc_sockaddr {
} type;
unsigned int length; /* XXXRTH beginning? */
ISC_LINK(struct isc_sockaddr) link;
} isc_sockaddr_t;
};
typedef ISC_LIST(struct isc_sockaddr) isc_sockaddrlist_t;
......@@ -62,6 +63,10 @@ void
isc_sockaddr_v6fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
in_port_t port);
void
isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na,
in_port_t port);
int
isc_sockaddr_pf(const isc_sockaddr_t *sockaddr);
/*
......
......@@ -42,6 +42,8 @@ typedef struct isc_timer isc_timer_t;
typedef struct isc_timermgr isc_timermgr_t;
typedef struct isc_rwlock isc_rwlock_t;
typedef struct isc_bitstring isc_bitstring_t;
typedef struct isc_sockaddr isc_sockaddr_t;
typedef struct isc_netaddr isc_netaddr_t;
typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *);
......
/*
* Copyright (C) 1999, 2000 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include <config.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <isc/assertions.h>
#include <isc/error.h>
#include <isc/netaddr.h>
#include <isc/sockaddr.h>
#include <isc/types.h>
isc_boolean_t
isc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b,
unsigned int prefixlen)
{
unsigned char *pa, *pb;
unsigned int ipabytes; /* Length of whole IP address in bytes */
unsigned int nbytes; /* Number of significant whole bytes */
unsigned int nbits; /* Number of significant leftover bits */
REQUIRE(a != NULL && b != NULL);
if (a->family != b->family)
return (ISC_FALSE);
switch (a->family) {
case AF_INET:
pa = (unsigned char *) &a->type.in;
pb = (unsigned char *) &b->type.in;
ipabytes = 4;
break;
case AF_INET6:
pa = (unsigned char *) &a->type.in6;
pb = (unsigned char *) &b->type.in6;
ipabytes = 16;
break;
default:
pa = pb = NULL; /* Avoid silly compiler warning. */
ipabytes = 0; /* Ditto. */
return (ISC_FALSE);
}
/* Don't crash if we get a pattern like 10.0.0.1/9999999. */
if (prefixlen > ipabytes * 8)
prefixlen = ipabytes * 8;
nbytes = prefixlen / 8;
nbits = prefixlen % 8;
if (nbytes > 0) {
if (memcmp(pa, pb, nbytes) != 0)
return (ISC_FALSE);
}
if (nbits > 0) {
unsigned int bytea, byteb, mask;
INSIST(nbytes < ipabytes);
INSIST(nbits < 8);
bytea = pa[nbytes];
byteb = pb[nbytes];
mask = (0xFF << (8-nbits)) & 0xFF;
if ((bytea & mask) != (byteb & mask))
return (ISC_FALSE);
}
return (ISC_TRUE);
}
isc_result_t
isc_netaddr_masktoprefixlen(const isc_netaddr_t *s, unsigned int *lenp)
{
unsigned int nbits, nbytes, ipbytes, i;
unsigned char *p;
switch (s->family) {
case AF_INET:
p = (unsigned char *) &s->type.in;
ipbytes = 4;
break;
case AF_INET6:
p = (unsigned char *) &s->type.in6;
ipbytes = 16;
break;
default:
ipbytes = 0;
return (ISC_R_NOTIMPLEMENTED);
}
nbytes = nbits = 0;
for (i = 0; i < ipbytes; i++) {
if (p[i] != 0xFF)
break;
}
nbytes = i;
if (i < ipbytes) {
unsigned int c = p[nbytes];
while ((c & 0x80) != 0 && nbits < 8) {
c <<= 1; nbits++;
}
if ((c & 0xFF) != 0)
return (ISC_R_MASKNONCONTIG);
i++;
}
for (; i < ipbytes; i++) {
if (p[i] != 0)
return (ISC_R_MASKNONCONTIG);
i++;
}
*lenp = nbytes * 8 + nbits;
return (ISC_R_SUCCESS);
}
void
isc_netaddr_fromin(isc_netaddr_t *netaddr, const struct in_addr *ina)
{
memset(netaddr, 0, sizeof *netaddr);
netaddr->family = AF_INET;
netaddr->type.in = *ina;
}
void
isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6)
{
memset(netaddr, 0, sizeof *netaddr);
netaddr->family = AF_INET6;
netaddr->type.in6 = *ina6;
}
void
isc_netaddr_fromsockaddr(isc_netaddr_t *t, const isc_sockaddr_t *s)
{
int family = s->type.sa.sa_family;
t->family = family;
switch (family) {
case AF_INET:
t->type.in = s->type.sin.sin_addr;
break;
case AF_INET6:
memcpy(&t->type.in6, &s->type.sin6.sin6_addr, 16);
break;
default:
INSIST(0);
}
}
......@@ -76,7 +76,8 @@ static char *text[ISC_R_NRESULTS] = {
"quota reached", /* 33 */
"unexpected error", /* 34 */
"already running", /* 35 */
"ignore" /* 36 */
"ignore", /* 36 */
"address mask not contiguous" /* 37 */
};
#define ISC_RESULT_RESULTSET 2
......
......@@ -26,7 +26,7 @@
#include <isc/assertions.h>
#include <isc/error.h>
#include <isc/sockaddr.h>
#include <isc/mem.h>
#include <isc/netaddr.h>
isc_boolean_t
isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b)
......@@ -106,58 +106,10 @@ isc_boolean_t
isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
unsigned int prefixlen)
{
unsigned char *pa, *pb;
unsigned int ipabytes; /* Length of whole IP address in bytes */
unsigned int nbytes; /* Number of significant whole bytes */
unsigned int nbits; /* Number of significant leftover bits */
REQUIRE(a != NULL && b != NULL);
if (a->length != b->length)
return (ISC_FALSE);
if (a->type.sa.sa_family != b->type.sa.sa_family)
return (ISC_FALSE);
switch (a->type.sa.sa_family) {
case AF_INET:
pa = (unsigned char *) &a->type.sin.sin_addr;
pb = (unsigned char *) &b->type.sin.sin_addr;
ipabytes = 4;
break;
case AF_INET6:
pa = ((unsigned char *) &a->type.sin6.sin6_addr);
pb = ((unsigned char *) &b->type.sin6.sin6_addr);
ipabytes = 16;
break;
default:
pa = pb = NULL; /* Avoid silly compiler warning. */
ipabytes = 0; /* Ditto. */
return (ISC_FALSE); /* XXX got a better idea? */
}
/* Don't crash if we get a pattern like 10.0.0.1/9999999. */
if (prefixlen > ipabytes * 8)
prefixlen = ipabytes * 8;
nbytes = prefixlen / 8;
nbits = prefixlen % 8;
if (nbytes > 0) {
if (memcmp(pa, pb, nbytes) != 0)
return (ISC_FALSE);
}
if (nbits > 0) {
unsigned int bytea, byteb, mask;
INSIST(nbytes < ipabytes);
INSIST(nbits < 8);
bytea = pa[nbytes];
byteb = pb[nbytes];
mask = (0xFF << (8-nbits)) & 0xFF;
if ((bytea & mask) != (byteb & mask))
return (ISC_FALSE);
}
return (ISC_TRUE);
isc_netaddr_t na, nb;
isc_netaddr_fromsockaddr(&na, a);
isc_netaddr_fromsockaddr(&nb, b);
return (isc_netaddr_eqprefix(&na, &nb, prefixlen));
}
isc_result_t
......@@ -324,6 +276,35 @@ isc_sockaddr_pf(const isc_sockaddr_t *sockaddr) {
#endif
}
void
isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na,
in_port_t port)
{
memset(sockaddr, 0, sizeof *sockaddr);
sockaddr->type.sin.sin_family = na->family;
switch (na->family) {
case AF_INET:
sockaddr->length = sizeof sockaddr->type.sin;
#ifdef ISC_PLATFORM_HAVESALEN
sockaddr->type.sin.sin_len = sizeof sockaddr->type.sin;
#endif
sockaddr->type.sin.sin_addr = na->type.in;
sockaddr->type.sin.sin_port = htons(port);
break;
case AF_INET6:
sockaddr->length = sizeof sockaddr->type.sin6;
#ifdef ISC_PLATFORM_HAVESALEN
sockaddr->type.sin6.sin6_len = sizeof sockaddr->type.sin6;
#endif
memcpy(&sockaddr->type.sin6.sin6_addr, &na->type.in6, 16);
sockaddr->type.sin6.sin6_port = htons(port);
break;
default:
INSIST(0);
}
ISC_LINK_INIT(sockaddr, link);
}
void
isc_sockaddr_setport(isc_sockaddr_t *sockaddr, in_port_t port) {
switch (sockaddr->type.sa.sa_family) {
......
......@@ -636,6 +636,7 @@
./lib/isc/log.c C 1999,2000
./lib/isc/mem.c C 1997,1998,1999,2000
./lib/isc/mutexblock.c C 1999,2000
./lib/isc/netaddr.c C 1999,2000
./lib/isc/nls/.cvsignore X 1999,2000
./lib/isc/nls/Makefile.in MAKE 1999,2000
./lib/isc/nls/msgcat.c C 1999,2000
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment