summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2011-07-15 20:21:07 +0200
committerMichael Brown2011-07-15 20:21:07 +0200
commit5b41381f3386ac70de30edbdcd291cda112d9f64 (patch)
treecc4084770d664a1c46a32ff6fbdeb75aa5475563 /src
parent[ipv4] Discard unwanted unicast packets (diff)
downloadipxe-5b41381f3386ac70de30edbdcd291cda112d9f64.tar.gz
ipxe-5b41381f3386ac70de30edbdcd291cda112d9f64.tar.xz
ipxe-5b41381f3386ac70de30edbdcd291cda112d9f64.zip
[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 <mcb30@ipxe.org>
Diffstat (limited to 'src')
-rw-r--r--src/net/ipv4.c14
1 files 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 ) );