mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
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
This commit is contained in:
parent
036608c715
commit
5d82424f5d
9 changed files with 244 additions and 61 deletions
|
|
@ -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 *);
|
||||
|
||||
|
|
|
|||
160
lib/isc/netaddr.c
Normal file
160
lib/isc/netaddr.c
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* 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
|
||||
|
|
|
|||
Loading…
Reference in a new issue