From 5b41381f3386ac70de30edbdcd291cda112d9f64 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 15 Jul 2011 19:21:07 +0100 Subject: [PATCH] [ipv4] Use broadcast link-layer address for all broadcast IPv4 addresses When transmitting, use the broadcast link-layer address for any broadcast address (e.g. 192.168.0.255), not just INADDR_BROADCAST (255.255.255.255). Signed-off-by: Michael Brown --- src/net/ipv4.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/net/ipv4.c b/src/net/ipv4.c index aee3bc35..5bb01a1c 100644 --- a/src/net/ipv4.c +++ b/src/net/ipv4.c @@ -110,10 +110,6 @@ static struct ipv4_miniroute * ipv4_route ( struct in_addr *dest ) { int local; int has_gw; - /* Never attempt to route the broadcast address */ - if ( dest->s_addr == INADDR_BROADCAST ) - return NULL; - /* Find first usable route in routing table */ list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) { if ( ! netdev_is_open ( miniroute->netdev ) ) @@ -260,15 +256,17 @@ static uint16_t ipv4_pshdr_chksum ( struct io_buffer *iobuf, uint16_t csum ) { * * @v dest IPv4 destination address * @v src IPv4 source address + * @v netmask IPv4 subnet mask * @v netdev Network device * @v ll_dest Link-layer destination address buffer * @ret rc Return status code */ static int ipv4_ll_addr ( struct in_addr dest, struct in_addr src, - struct net_device *netdev, uint8_t *ll_dest ) { + struct in_addr netmask, struct net_device *netdev, + uint8_t *ll_dest ) { struct ll_protocol *ll_protocol = netdev->ll_protocol; - if ( dest.s_addr == INADDR_BROADCAST ) { + if ( ( ( dest.s_addr ^ INADDR_BROADCAST ) & ~netmask.s_addr ) == 0 ) { /* Broadcast address */ memcpy ( ll_dest, netdev->ll_broadcast, ll_protocol->ll_addr_len ); @@ -306,6 +304,7 @@ static int ipv4_tx ( struct io_buffer *iobuf, struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest ); struct ipv4_miniroute *miniroute; struct in_addr next_hop; + struct in_addr netmask = { .s_addr = 0 }; uint8_t ll_dest[MAX_LL_ADDR_LEN]; int rc; @@ -326,6 +325,7 @@ static int ipv4_tx ( struct io_buffer *iobuf, ( ! IN_MULTICAST ( ntohl ( next_hop.s_addr ) ) ) && ( ( miniroute = ipv4_route ( &next_hop ) ) != NULL ) ) { iphdr->src = miniroute->address; + netmask = miniroute->netmask; netdev = miniroute->netdev; } if ( ! netdev ) { @@ -343,7 +343,7 @@ static int ipv4_tx ( struct io_buffer *iobuf, ( ( netdev->rx_stats.good & 0xf ) << 0 ) ); /* Determine link-layer destination address */ - if ( ( rc = ipv4_ll_addr ( next_hop, iphdr->src, netdev, + if ( ( rc = ipv4_ll_addr ( next_hop, iphdr->src, netmask, netdev, ll_dest ) ) != 0 ) { DBG ( "IPv4 has no link-layer address for %s: %s\n", inet_ntoa ( next_hop ), strerror ( rc ) );