mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-31 06:15:55 +00:00
More portable internet addresses; fix endian bug; fix parser bugs
This commit is contained in:
154
common/inet.c
Normal file
154
common/inet.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/* inet.c
|
||||
|
||||
Subroutines to manipulate internet addresses in a safely portable
|
||||
way... */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of The Internet Software Consortium nor the names
|
||||
* of its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
|
||||
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This software has been written for the Internet Software Consortium
|
||||
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
|
||||
* Enterprises. To learn more about the Internet Software Consortium,
|
||||
* see ``http://www.vix.com/isc''. To learn more about Vixie
|
||||
* Enterprises, see ``http://www.vix.com''.
|
||||
*/
|
||||
|
||||
#include "dhcpd.h"
|
||||
|
||||
/* Return just the network number of an internet address... */
|
||||
|
||||
struct iaddr subnet_number (addr, mask)
|
||||
struct iaddr addr;
|
||||
struct iaddr mask;
|
||||
{
|
||||
int i;
|
||||
struct iaddr rv;
|
||||
|
||||
rv.len = 0;
|
||||
|
||||
/* Both addresses must have the same length... */
|
||||
if (addr.len != mask.len)
|
||||
return rv;
|
||||
|
||||
rv.len = addr.len;
|
||||
for (i = 0; i < rv.len; i++)
|
||||
rv.iabuf [i] = addr.iabuf [i] & mask.iabuf [i];
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Combine a network number and a integer to produce an internet address.
|
||||
This won't work for subnets with more than 32 bits of host address, but
|
||||
maybe this isn't a problem. */
|
||||
|
||||
struct iaddr ip_addr (subnet, mask, host_address)
|
||||
struct iaddr subnet;
|
||||
struct iaddr mask;
|
||||
unsigned long host_address;
|
||||
{
|
||||
int i, j, k;
|
||||
unsigned long swaddr;
|
||||
struct iaddr rv;
|
||||
unsigned char habuf [sizeof swaddr];
|
||||
|
||||
swaddr = htonl (host_address);
|
||||
memcpy (habuf, &swaddr, sizeof swaddr);
|
||||
|
||||
/* Combine the subnet address and the host address. If
|
||||
the host address is bigger than can fit in the subnet,
|
||||
return a zero-length iaddr structure. */
|
||||
rv = subnet;
|
||||
j = rv.len - sizeof habuf;
|
||||
for (i = sizeof habuf - 1; i >= 0; i--) {
|
||||
if (mask.iabuf [i + j]) {
|
||||
if (habuf [i] > ~mask.iabuf [i + j]) {
|
||||
rv.len = 0;
|
||||
return rv;
|
||||
}
|
||||
for (k = i - 1; k >= 0; k--) {
|
||||
if (habuf [k]) {
|
||||
rv.len = 0;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
rv.iabuf [i + j] &= habuf [i];
|
||||
break;
|
||||
}
|
||||
rv.iabuf [i + j] = habuf [i];
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
unsigned long host_addr (addr, mask)
|
||||
struct iaddr addr;
|
||||
struct iaddr mask;
|
||||
{
|
||||
int i;
|
||||
unsigned long swaddr;
|
||||
struct iaddr rv;
|
||||
|
||||
rv.len = 0;
|
||||
|
||||
/* Mask out the network bits... */
|
||||
rv.len = addr.len;
|
||||
for (i = 0; i < rv.len; i++)
|
||||
rv.iabuf [i] = addr.iabuf [i] & ~mask.iabuf [i];
|
||||
|
||||
/* Copy out up to 32 bits... */
|
||||
memcpy (&swaddr, &rv.iabuf [rv.len - sizeof swaddr], sizeof swaddr);
|
||||
|
||||
/* Swap it and return it. */
|
||||
return ntohl (swaddr);
|
||||
}
|
||||
|
||||
int addr_eq (addr1, addr2)
|
||||
struct iaddr addr1, addr2;
|
||||
{
|
||||
if (addr1.len != addr2.len)
|
||||
return 0;
|
||||
return memcmp (addr1.iabuf, addr2.iabuf, addr1.len) == 0;
|
||||
}
|
||||
|
||||
char *piaddr (addr)
|
||||
struct iaddr addr;
|
||||
{
|
||||
static char pbuf [4 * 16];
|
||||
char *s = pbuf;
|
||||
int i;
|
||||
|
||||
if (addr.len == 0) {
|
||||
strcpy (s, "<null address>");
|
||||
}
|
||||
for (i = 0; i < addr.len; i++) {
|
||||
sprintf (s, "%s%d", i ? "." : "", addr.iabuf [i]);
|
||||
s += strlen (s);
|
||||
}
|
||||
return pbuf;
|
||||
}
|
Reference in New Issue
Block a user