Skip to content

Commit

Permalink
[ipv4] Redefine IP address constants to avoid unnecessary byte swapping
Browse files Browse the repository at this point in the history
Redefine various IPv4 address constants and testing macros to avoid
unnecessary byte swapping at runtime, and slightly rename the macros
to prevent code from accidentally using the old definitions.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Jul 28, 2015
1 parent 9c185e2 commit 6efcabd
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 37 deletions.
24 changes: 15 additions & 9 deletions src/include/ipxe/in.h
Expand Up @@ -4,6 +4,7 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <byteswap.h>
#include <ipxe/socket.h>

/* Protocol numbers */
Expand All @@ -15,17 +16,22 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

/* IP address constants */

#define INADDR_NONE 0xffffffff
#define INADDR_NONE htonl ( 0xffffffff )

#define INADDR_BROADCAST 0xffffffff
#define INADDR_BROADCAST htonl ( 0xffffffff )

#define IN_CLASSA(addr) ( ( (addr) & 0x80000000 ) == 0x00000000 )
#define IN_CLASSA_NET 0xff000000
#define IN_CLASSB(addr) ( ( (addr) & 0xc0000000 ) == 0x80000000 )
#define IN_CLASSB_NET 0xffff0000
#define IN_CLASSC(addr) ( ( (addr) & 0xe0000000 ) == 0xc0000000 )
#define IN_CLASSC_NET 0xffffff00
#define IN_MULTICAST(addr) ( ( (addr) & 0xf0000000 ) == 0xe0000000 )
#define INADDR_NET_CLASSA htonl ( 0xff000000 )
#define INADDR_NET_CLASSB htonl ( 0xffff0000 )
#define INADDR_NET_CLASSC htonl ( 0xffffff00 )

#define IN_IS_CLASSA( addr ) \
( ( (addr) & htonl ( 0x80000000 ) ) == htonl ( 0x00000000 ) )
#define IN_IS_CLASSB( addr ) \
( ( (addr) & htonl ( 0xc0000000 ) ) == htonl ( 0x80000000 ) )
#define IN_IS_CLASSC( addr ) \
( ( (addr) & htonl ( 0xe0000000 ) ) == htonl ( 0xc0000000 ) )
#define IN_IS_MULTICAST( addr ) \
( ( (addr) & htonl ( 0xf0000000 ) ) == htonl ( 0xe0000000 ) )

/**
* IP address structure
Expand Down
16 changes: 8 additions & 8 deletions src/net/ipv4.c
Expand Up @@ -314,7 +314,7 @@ static int ipv4_tx ( struct io_buffer *iobuf,
if ( sin_src )
iphdr->src = sin_src->sin_addr;
if ( ( next_hop.s_addr != INADDR_BROADCAST ) &&
( ! IN_MULTICAST ( ntohl ( next_hop.s_addr ) ) ) &&
( ! IN_IS_MULTICAST ( next_hop.s_addr ) ) &&
( ( miniroute = ipv4_route ( &next_hop ) ) != NULL ) ) {
iphdr->src = miniroute->address;
netmask = miniroute->netmask;
Expand Down Expand Up @@ -353,7 +353,7 @@ static int ipv4_tx ( struct io_buffer *iobuf,
/* Broadcast address */
ipv4_stats.out_bcast_pkts++;
ll_dest = netdev->ll_broadcast;
} else if ( IN_MULTICAST ( ntohl ( next_hop.s_addr ) ) ) {
} else if ( IN_IS_MULTICAST ( next_hop.s_addr ) ) {
/* Multicast address */
ipv4_stats.out_mcast_pkts++;
if ( ( rc = netdev->ll_protocol->mc_hash ( AF_INET, &next_hop,
Expand Down Expand Up @@ -816,12 +816,12 @@ static int ipv4_create_routes ( void ) {
fetch_ipv4_setting ( settings, &netmask_setting, &netmask );
/* Calculate default netmask, if necessary */
if ( ! netmask.s_addr ) {
if ( IN_CLASSA ( ntohl ( address.s_addr ) ) ) {
netmask.s_addr = htonl ( IN_CLASSA_NET );
} else if ( IN_CLASSB ( ntohl ( address.s_addr ) ) ) {
netmask.s_addr = htonl ( IN_CLASSB_NET );
} else if ( IN_CLASSC ( ntohl ( address.s_addr ) ) ) {
netmask.s_addr = htonl ( IN_CLASSC_NET );
if ( IN_IS_CLASSA ( address.s_addr ) ) {
netmask.s_addr = INADDR_NET_CLASSA;
} else if ( IN_IS_CLASSB ( address.s_addr ) ) {
netmask.s_addr = INADDR_NET_CLASSB;
} else if ( IN_IS_CLASSC ( address.s_addr ) ) {
netmask.s_addr = INADDR_NET_CLASSC;
}
}
/* Get default gateway, if present */
Expand Down
41 changes: 21 additions & 20 deletions src/tests/ipv4_test.c
Expand Up @@ -39,7 +39,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/test.h>

/** Define inline IPv4 address */
#define IPV4(a,b,c,d) ( ( (a) << 24 ) | ( (b) << 16 ) | ( (c) << 8 ) | (d) )
#define IPV4(a,b,c,d) \
htonl ( ( (a) << 24 ) | ( (b) << 16 ) | ( (c) << 8 ) | (d) )

/**
* Report an inet_ntoa() test result
Expand All @@ -51,7 +52,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*/
static void inet_ntoa_okx ( uint32_t addr, const char *text, const char *file,
unsigned int line ) {
struct in_addr in = { .s_addr = htonl ( addr ) };
struct in_addr in = { .s_addr = addr };
char *actual;

/* Format address */
Expand Down Expand Up @@ -81,7 +82,7 @@ static void inet_aton_okx ( const char *text, uint32_t addr, const char *file,
/* Parse address */
okx ( inet_aton ( text, &actual ) != 0, file, line );
DBG ( "inet_aton ( \"%s\" ) = %s\n", text, inet_ntoa ( actual ) );
okx ( ntohl ( actual.s_addr ) == addr, file, line );
okx ( actual.s_addr == addr, file, line );
};
#define inet_aton_ok( text, addr ) \
inet_aton_okx ( text, addr, __FILE__, __LINE__ )
Expand Down Expand Up @@ -110,23 +111,23 @@ static void inet_aton_fail_okx ( const char *text, const char *file,
static void ipv4_test_exec ( void ) {

/* Address testing macros */
ok ( IN_CLASSA ( IPV4 ( 10, 0, 0, 1 ) ) );
ok ( ! IN_CLASSB ( IPV4 ( 10, 0, 0, 1 ) ) );
ok ( ! IN_CLASSC ( IPV4 ( 10, 0, 0, 1 ) ) );
ok ( ! IN_CLASSA ( IPV4 ( 172, 16, 0, 1 ) ) );
ok ( IN_CLASSB ( IPV4 ( 172, 16, 0, 1 ) ) );
ok ( ! IN_CLASSC ( IPV4 ( 172, 16, 0, 1 ) ) );
ok ( ! IN_CLASSA ( IPV4 ( 192, 168, 0, 1 ) ) );
ok ( ! IN_CLASSB ( IPV4 ( 192, 168, 0, 1 ) ) );
ok ( IN_CLASSC ( IPV4 ( 192, 168, 0, 1 ) ) );
ok ( ! IN_MULTICAST ( IPV4 ( 127, 0, 0, 1 ) ) );
ok ( ! IN_MULTICAST ( IPV4 ( 8, 8, 8, 8 ) ) );
ok ( ! IN_MULTICAST ( IPV4 ( 0, 0, 0, 0 ) ) );
ok ( ! IN_MULTICAST ( IPV4 ( 223, 0, 0, 1 ) ) );
ok ( ! IN_MULTICAST ( IPV4 ( 240, 0, 0, 1 ) ) );
ok ( IN_MULTICAST ( IPV4 ( 224, 0, 0, 1 ) ) );
ok ( IN_MULTICAST ( IPV4 ( 231, 89, 0, 2 ) ) );
ok ( IN_MULTICAST ( IPV4 ( 239, 6, 1, 17 ) ) );
ok ( IN_IS_CLASSA ( IPV4 ( 10, 0, 0, 1 ) ) );
ok ( ! IN_IS_CLASSB ( IPV4 ( 10, 0, 0, 1 ) ) );
ok ( ! IN_IS_CLASSC ( IPV4 ( 10, 0, 0, 1 ) ) );
ok ( ! IN_IS_CLASSA ( IPV4 ( 172, 16, 0, 1 ) ) );
ok ( IN_IS_CLASSB ( IPV4 ( 172, 16, 0, 1 ) ) );
ok ( ! IN_IS_CLASSC ( IPV4 ( 172, 16, 0, 1 ) ) );
ok ( ! IN_IS_CLASSA ( IPV4 ( 192, 168, 0, 1 ) ) );
ok ( ! IN_IS_CLASSB ( IPV4 ( 192, 168, 0, 1 ) ) );
ok ( IN_IS_CLASSC ( IPV4 ( 192, 168, 0, 1 ) ) );
ok ( ! IN_IS_MULTICAST ( IPV4 ( 127, 0, 0, 1 ) ) );
ok ( ! IN_IS_MULTICAST ( IPV4 ( 8, 8, 8, 8 ) ) );
ok ( ! IN_IS_MULTICAST ( IPV4 ( 0, 0, 0, 0 ) ) );
ok ( ! IN_IS_MULTICAST ( IPV4 ( 223, 0, 0, 1 ) ) );
ok ( ! IN_IS_MULTICAST ( IPV4 ( 240, 0, 0, 1 ) ) );
ok ( IN_IS_MULTICAST ( IPV4 ( 224, 0, 0, 1 ) ) );
ok ( IN_IS_MULTICAST ( IPV4 ( 231, 89, 0, 2 ) ) );
ok ( IN_IS_MULTICAST ( IPV4 ( 239, 6, 1, 17 ) ) );

/* inet_ntoa() tests */
inet_ntoa_ok ( IPV4 ( 127, 0, 0, 1 ), "127.0.0.1" );
Expand Down

0 comments on commit 6efcabd

Please sign in to comment.