* Our INADDR_* and IN_CLASS* macros were mostly wrong - they are supposed to
be in host endian order. * Adapted ipv4 code that automatically finds a netmask to this change. * Cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30299 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1b80286772
commit
a87124634a
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2008, Haiku, Inc. All Rights Reserved.
|
* Copyright 2002-2009, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _NETINET_IN_H_
|
#ifndef _NETINET_IN_H_
|
||||||
@ -144,52 +144,46 @@ struct group_source_req {
|
|||||||
#define IPV6_MULTICAST_HOPS 25 /* int */
|
#define IPV6_MULTICAST_HOPS 25 /* int */
|
||||||
#define IPV6_MULTICAST_LOOP 26 /* int */
|
#define IPV6_MULTICAST_LOOP 26 /* int */
|
||||||
|
|
||||||
#define __IPADDR(x) ((uint32_t)htonl((uint32_t)(x)))
|
#define INADDR_ANY ((in_addr_t)0x00000000)
|
||||||
|
#define INADDR_LOOPBACK ((in_addr_t)0x7f000001)
|
||||||
|
#define INADDR_BROADCAST ((in_addr_t)0xffffffff) /* must be masked */
|
||||||
|
|
||||||
#define INADDR_ANY 0x00000000
|
#define INADDR_UNSPEC_GROUP ((in_addr_t)0xe0000000) /* 224.0.0.0 */
|
||||||
#define INADDR_LOOPBACK __IPADDR(0x7f000001)
|
#define INADDR_ALLHOSTS_GROUP ((in_addr_t)0xe0000001) /* 224.0.0.1 */
|
||||||
#define INADDR_BROADCAST 0xffffffff /* must be masked */
|
#define INADDR_ALLROUTERS_GROUP ((in_addr_t)0xe0000002) /* 224.0.0.2 */
|
||||||
|
#define INADDR_MAX_LOCAL_GROUP ((in_addr_t)0xe00000ff) /* 224.0.0.255 */
|
||||||
|
|
||||||
#define INADDR_UNSPEC_GROUP __IPADDR(0xe0000000) /* 224.0.0.0 */
|
#define IN_LOOPBACKNET 127
|
||||||
#define INADDR_ALLHOSTS_GROUP __IPADDR(0xe0000001) /* 224.0.0.1 */
|
|
||||||
#define INADDR_ALLROUTERS_GROUP __IPADDR(0xe0000002) /* 224.0.0.2 */
|
|
||||||
#define INADDR_MAX_LOCAL_GROUP __IPADDR(0xe00000ff) /* 224.0.0.255 */
|
|
||||||
|
|
||||||
#define IN_LOOPBACKNET 127 /* official! */
|
#define INADDR_NONE ((in_addr_t)0xffffffff)
|
||||||
|
|
||||||
#define INADDR_NONE 0xffffffff
|
#define IN_CLASSA(i) (((in_addr_t)(i) & 0x80000000) == 0)
|
||||||
|
#define IN_CLASSA_NET 0xff000000
|
||||||
#define IN_CLASSA(i) (((uint32_t)(i) & __IPADDR(0x80000000)) == \
|
|
||||||
__IPADDR(0x00000000))
|
|
||||||
#define IN_CLASSA_NET __IPADDR(0xff000000)
|
|
||||||
#define IN_CLASSA_NSHIFT 24
|
#define IN_CLASSA_NSHIFT 24
|
||||||
#define IN_CLASSA_HOST __IPADDR(0x00ffffff)
|
#define IN_CLASSA_HOST 0x00ffffff
|
||||||
#define IN_CLASSA_MAX 128
|
#define IN_CLASSA_MAX 128
|
||||||
|
|
||||||
#define IN_CLASSB(i) (((uint32_t)(i) & __IPADDR(0xc0000000)) == \
|
#define IN_CLASSB(i) (((in_addr_t)(i) & 0xc0000000) == 0x80000000)
|
||||||
__IPADDR(0x80000000))
|
#define IN_CLASSB_NET 0xffff0000
|
||||||
#define IN_CLASSB_NET __IPADDR(0xffff0000)
|
|
||||||
#define IN_CLASSB_NSHIFT 16
|
#define IN_CLASSB_NSHIFT 16
|
||||||
#define IN_CLASSB_HOST __IPADDR(0x0000ffff)
|
#define IN_CLASSB_HOST 0x0000ffff
|
||||||
#define IN_CLASSB_MAX 65536
|
#define IN_CLASSB_MAX 65536
|
||||||
|
|
||||||
#define IN_CLASSC(i) (((uint32_t)(i) & __IPADDR(0xe0000000)) == \
|
#define IN_CLASSC(i) (((in_addr_t)(i) & 0xe0000000) == 0xc0000000)
|
||||||
__IPADDR(0xc0000000))
|
#define IN_CLASSC_NET 0xffffff00
|
||||||
#define IN_CLASSC_NET __IPADDR(0xffffff00)
|
|
||||||
#define IN_CLASSC_NSHIFT 8
|
#define IN_CLASSC_NSHIFT 8
|
||||||
#define IN_CLASSC_HOST __IPADDR(0x000000ff)
|
#define IN_CLASSC_HOST 0x000000ff
|
||||||
|
|
||||||
#define IN_CLASSD(i) (((uint32_t)(i) & __IPADDR(0xf0000000)) == \
|
#define IN_CLASSD(i) (((in_addr_t)(i) & 0xf0000000) == 0xe0000000)
|
||||||
__IPADDR(0xe0000000))
|
|
||||||
/* These ones aren't really net and host fields, but routing needn't know. */
|
/* These ones aren't really net and host fields, but routing needn't know. */
|
||||||
#define IN_CLASSD_NET __IPADDR(0xf0000000)
|
#define IN_CLASSD_NET 0xf0000000
|
||||||
#define IN_CLASSD_NSHIFT 28
|
#define IN_CLASSD_NSHIFT 28
|
||||||
#define IN_CLASSD_HOST __IPADDR(0x0fffffff)
|
#define IN_CLASSD_HOST 0x0fffffff
|
||||||
|
|
||||||
#define IN_MULTICAST(i) IN_CLASSD(i)
|
#define IN_MULTICAST(i) IN_CLASSD(i)
|
||||||
|
|
||||||
#define IN_EXPERIMENTAL(i) (((uint32_t)(i) & 0xf0000000) == 0xf0000000)
|
#define IN_EXPERIMENTAL(i) (((in_addr_t)(i) & 0xf0000000) == 0xf0000000)
|
||||||
#define IN_BADCLASS(i) (((uint32_t)(i) & 0xf0000000) == 0xf0000000)
|
#define IN_BADCLASS(i) (((in_addr_t)(i) & 0xf0000000) == 0xf0000000)
|
||||||
|
|
||||||
#define IP_MAX_MEMBERSHIPS 20
|
#define IP_MAX_MEMBERSHIPS 20
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
|
* Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@ -21,8 +21,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Routing utility function: copies address \a from into a new address
|
||||||
Routing utility function: copies address \a from into a new address
|
|
||||||
that is put into \a to.
|
that is put into \a to.
|
||||||
If \a replaceWithZeros is set \a from will be replaced by an empty
|
If \a replaceWithZeros is set \a from will be replaced by an empty
|
||||||
address.
|
address.
|
||||||
@ -69,15 +68,15 @@ ipv4_copy_address(const sockaddr *from, sockaddr **to,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Routing utility function: applies \a mask to given \a address and puts
|
||||||
Routing utility function: applies \a mask to given \a address and puts
|
|
||||||
the resulting address into \a result.
|
the resulting address into \a result.
|
||||||
\return B_OK if the mask has been applied
|
\return B_OK if the mask has been applied
|
||||||
\return B_BAD_VALUE if \a address is NULL or if any of \a address or \a mask
|
\return B_BAD_VALUE if \a address is NULL or if any of \a address or \a mask
|
||||||
refers to an uninitialized address
|
refers to an uninitialized address
|
||||||
*/
|
*/
|
||||||
static status_t
|
static status_t
|
||||||
ipv4_mask_address(const sockaddr *address, const sockaddr *mask, sockaddr *result)
|
ipv4_mask_address(const sockaddr *address, const sockaddr *mask,
|
||||||
|
sockaddr *result)
|
||||||
{
|
{
|
||||||
if (address == NULL || address->sa_len == 0 || result == NULL
|
if (address == NULL || address->sa_len == 0 || result == NULL
|
||||||
|| (mask != NULL && mask->sa_len == 0))
|
|| (mask != NULL && mask->sa_len == 0))
|
||||||
@ -93,8 +92,7 @@ ipv4_mask_address(const sockaddr *address, const sockaddr *mask, sockaddr *resul
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Checks if the given \a address is the empty address. By default, the port
|
||||||
Checks if the given \a address is the empty address. By default, the port
|
|
||||||
is checked, too, but you can avoid that by passing \a checkPort = false.
|
is checked, too, but you can avoid that by passing \a checkPort = false.
|
||||||
\return true if \a address is NULL, uninitialized or the empty address,
|
\return true if \a address is NULL, uninitialized or the empty address,
|
||||||
false if not
|
false if not
|
||||||
@ -110,8 +108,7 @@ ipv4_is_empty_address(const sockaddr *address, bool checkPort)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Compares the IP-addresses of the two given address structures \a a and \a b.
|
||||||
Compares the IP-addresses of the two given address structures \a a and \a b.
|
|
||||||
\return true if IP-addresses of \a a and \a b are equal, false if not
|
\return true if IP-addresses of \a a and \a b are equal, false if not
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
@ -124,12 +121,12 @@ ipv4_equal_addresses(const sockaddr *a, const sockaddr *b)
|
|||||||
if (a == NULL && b != NULL)
|
if (a == NULL && b != NULL)
|
||||||
return ipv4_is_empty_address(b, false);
|
return ipv4_is_empty_address(b, false);
|
||||||
|
|
||||||
return ((sockaddr_in *)a)->sin_addr.s_addr == ((sockaddr_in *)b)->sin_addr.s_addr;
|
return ((sockaddr_in *)a)->sin_addr.s_addr
|
||||||
|
== ((sockaddr_in *)b)->sin_addr.s_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Compares the ports of the two given address structures \a a and \a b.
|
||||||
Compares the ports of the two given address structures \a a and \a b.
|
|
||||||
\return true if ports of \a a and \a b are equal, false if not
|
\return true if ports of \a a and \a b are equal, false if not
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
@ -141,8 +138,7 @@ ipv4_equal_ports(const sockaddr *a, const sockaddr *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Compares the IP-addresses and ports of the two given address structures
|
||||||
Compares the IP-addresses and ports of the two given address structures
|
|
||||||
\a a and \a b.
|
\a a and \a b.
|
||||||
\return true if IP-addresses and ports of \a a and \a b are equal, false if
|
\return true if IP-addresses and ports of \a a and \a b are equal, false if
|
||||||
not
|
not
|
||||||
@ -157,13 +153,13 @@ ipv4_equal_addresses_and_ports(const sockaddr *a, const sockaddr *b)
|
|||||||
if (a == NULL && b != NULL)
|
if (a == NULL && b != NULL)
|
||||||
return ipv4_is_empty_address(b, true);
|
return ipv4_is_empty_address(b, true);
|
||||||
|
|
||||||
return ((sockaddr_in *)a)->sin_addr.s_addr == ((sockaddr_in *)b)->sin_addr.s_addr
|
return ((sockaddr_in *)a)->sin_addr.s_addr
|
||||||
|
== ((sockaddr_in *)b)->sin_addr.s_addr
|
||||||
&& ((sockaddr_in *)a)->sin_port == ((sockaddr_in *)b)->sin_port;
|
&& ((sockaddr_in *)a)->sin_port == ((sockaddr_in *)b)->sin_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Applies the given \a mask two \a a and \a b and then checks whether
|
||||||
Applies the given \a mask two \a a and \a b and then checks whether
|
|
||||||
the masked addresses match.
|
the masked addresses match.
|
||||||
\return true if \a a matches \a b after masking both, false if not
|
\return true if \a a matches \a b after masking both, false if not
|
||||||
*/
|
*/
|
||||||
@ -194,8 +190,7 @@ ipv4_equal_masked_addresses(const sockaddr *a, const sockaddr *b,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Routing utility function: determines the least significant bit that is set
|
||||||
Routing utility function: determines the least significant bit that is set
|
|
||||||
in the given \a mask.
|
in the given \a mask.
|
||||||
\return the number of the first bit that is set (0-32, where 32 means
|
\return the number of the first bit that is set (0-32, where 32 means
|
||||||
that there's no bit set in the mask).
|
that there's no bit set in the mask).
|
||||||
@ -208,7 +203,8 @@ ipv4_first_mask_bit(const sockaddr *_mask)
|
|||||||
|
|
||||||
uint32 mask = ntohl(((const sockaddr_in *)_mask)->sin_addr.s_addr);
|
uint32 mask = ntohl(((const sockaddr_in *)_mask)->sin_addr.s_addr);
|
||||||
|
|
||||||
// TODO: this can be optimized, there are also some nice assembler mnemonics for this
|
// TODO: this can be optimized, there are also some nice assembler mnemonics
|
||||||
|
// for this
|
||||||
int8 bit = 0;
|
int8 bit = 0;
|
||||||
for (uint32 bitMask = 1; bit < 32; bitMask <<= 1, bit++) {
|
for (uint32 bitMask = 1; bit < 32; bitMask <<= 1, bit++) {
|
||||||
if (mask & bitMask)
|
if (mask & bitMask)
|
||||||
@ -219,8 +215,7 @@ ipv4_first_mask_bit(const sockaddr *_mask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Routing utility function: checks the given \a mask for correctness (which
|
||||||
Routing utility function: checks the given \a mask for correctness (which
|
|
||||||
means that (starting with LSB) consists zero or more unset bits, followed
|
means that (starting with LSB) consists zero or more unset bits, followed
|
||||||
by bits that are all set).
|
by bits that are all set).
|
||||||
\return true if \a mask is ok, false if not
|
\return true if \a mask is ok, false if not
|
||||||
@ -248,8 +243,7 @@ ipv4_check_mask(const sockaddr *_mask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Creates a buffer for the given \a address and prints the address into
|
||||||
Creates a buffer for the given \a address and prints the address into
|
|
||||||
it (hexadecimal representation in host byte order or '<none>').
|
it (hexadecimal representation in host byte order or '<none>').
|
||||||
If \a printPort is set, the port is printed, too.
|
If \a printPort is set, the port is printed, too.
|
||||||
\return B_OK if the address could be printed, \a buffer will point to
|
\return B_OK if the address could be printed, \a buffer will point to
|
||||||
@ -271,14 +265,15 @@ ipv4_print_address_buffer(const sockaddr *_address, char *buffer,
|
|||||||
else {
|
else {
|
||||||
unsigned int addr = ntohl(address->sin_addr.s_addr);
|
unsigned int addr = ntohl(address->sin_addr.s_addr);
|
||||||
|
|
||||||
if (printPort)
|
if (printPort) {
|
||||||
snprintf(buffer, bufferSize, "%u.%u.%u.%u:%u",
|
snprintf(buffer, bufferSize, "%u.%u.%u.%u:%u",
|
||||||
(addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff,
|
(addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff,
|
||||||
addr & 0xff, ntohs(address->sin_port));
|
addr & 0xff, ntohs(address->sin_port));
|
||||||
else
|
} else {
|
||||||
snprintf(buffer, bufferSize, "%u.%u.%u.%u", (addr >> 24) & 0xff,
|
snprintf(buffer, bufferSize, "%u.%u.%u.%u", (addr >> 24) & 0xff,
|
||||||
(addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);
|
(addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -301,8 +296,7 @@ ipv4_print_address(const sockaddr *_address, char **_buffer, bool printPort)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Determines the port of the given \a address.
|
||||||
Determines the port of the given \a address.
|
|
||||||
\return uint16 representing the port-nr
|
\return uint16 representing the port-nr
|
||||||
*/
|
*/
|
||||||
static uint16
|
static uint16
|
||||||
@ -315,8 +309,7 @@ ipv4_get_port(const sockaddr *address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Sets the port of the given \a address to \a port.
|
||||||
Sets the port of the given \a address to \a port.
|
|
||||||
\return B_OK if the port has been set
|
\return B_OK if the port has been set
|
||||||
\return B_BAD_VALUE if \a address is NULL or has not been initialized
|
\return B_BAD_VALUE if \a address is NULL or has not been initialized
|
||||||
*/
|
*/
|
||||||
@ -331,8 +324,7 @@ ipv4_set_port(sockaddr *address, uint16 port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Sets \a address to \a from.
|
||||||
Sets \a address to \a from.
|
|
||||||
\return B_OK if \a from has been copied into \a address
|
\return B_OK if \a from has been copied into \a address
|
||||||
\return B_BAD_VALUE if either \a address or \a from is NULL or if the
|
\return B_BAD_VALUE if either \a address or \a from is NULL or if the
|
||||||
address given in from has not been initialized
|
address given in from has not been initialized
|
||||||
@ -353,8 +345,7 @@ ipv4_set_to(sockaddr *address, const sockaddr *from)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Updates missing parts in \a address with the values in \a from.
|
||||||
Updates missing parts in \a address with the values in \a from.
|
|
||||||
\return B_OK if \a address has been updated from \a from
|
\return B_OK if \a address has been updated from \a from
|
||||||
\return B_BAD_VALUE if either \a address or \a from is NULL or if the
|
\return B_BAD_VALUE if either \a address or \a from is NULL or if the
|
||||||
address given in from has not been initialized
|
address given in from has not been initialized
|
||||||
@ -385,8 +376,7 @@ ipv4_update_to(sockaddr *_address, const sockaddr *_from)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Sets \a address to the empty address (0.0.0.0).
|
||||||
Sets \a address to the empty address (0.0.0.0).
|
|
||||||
\return B_OK if \a address has been set
|
\return B_OK if \a address has been set
|
||||||
\return B_BAD_VALUE if \a address is NULL
|
\return B_BAD_VALUE if \a address is NULL
|
||||||
*/
|
*/
|
||||||
@ -418,17 +408,16 @@ ipv4_set_to_defaults(sockaddr *_defaultMask, sockaddr *_defaultBroadcast,
|
|||||||
in_addr_t net;
|
in_addr_t net;
|
||||||
if (mask == NULL) {
|
if (mask == NULL) {
|
||||||
// choose default netmask depending on the class of the address
|
// choose default netmask depending on the class of the address
|
||||||
net = address->sin_addr.s_addr;
|
net = ntohl(address->sin_addr.s_addr);
|
||||||
if (IN_CLASSA(net)
|
if (IN_CLASSA(net) || (net >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
|
||||||
|| (ntohl(net) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
|
|
||||||
// class A, or loopback
|
// class A, or loopback
|
||||||
net = IN_CLASSA_NET;
|
net = htonl(IN_CLASSA_NET);
|
||||||
} else if (IN_CLASSB(net)) {
|
} else if (IN_CLASSB(net)) {
|
||||||
// class B
|
// class B
|
||||||
net = IN_CLASSB_NET;
|
net = htonl(IN_CLASSB_NET);
|
||||||
} else {
|
} else {
|
||||||
// class C and rest
|
// class C and rest
|
||||||
net = IN_CLASSC_NET;
|
net = htonl(IN_CLASSC_NET);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
net = mask->sin_addr.s_addr;
|
net = mask->sin_addr.s_addr;
|
||||||
@ -452,8 +441,7 @@ ipv4_set_to_defaults(sockaddr *_defaultMask, sockaddr *_defaultBroadcast,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Computes a hash-value of the given addresses \a ourAddress
|
||||||
Computes a hash-value of the given addresses \a ourAddress
|
|
||||||
and \a peerAddress.
|
and \a peerAddress.
|
||||||
\return uint32 representing the hash-value
|
\return uint32 representing the hash-value
|
||||||
*/
|
*/
|
||||||
@ -474,8 +462,7 @@ ipv4_hash_address_pair(const sockaddr *ourAddress, const sockaddr *peerAddress)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! Adds the given \a address to the IP-checksum \a checksum.
|
||||||
Adds the given \a address to the IP-checksum \a checksum.
|
|
||||||
\return B_OK if \a address has been added to the checksum
|
\return B_OK if \a address has been added to the checksum
|
||||||
\return B_BAD_VALUE if either \a address or \a checksum is NULL or if
|
\return B_BAD_VALUE if either \a address or \a checksum is NULL or if
|
||||||
the given address is not initialized
|
the given address is not initialized
|
||||||
|
Loading…
x
Reference in New Issue
Block a user