| 
				
			 | 
			
			
				
				@@ -110,10 +110,6 @@ static struct ipv4_miniroute * ipv4_route ( struct in_addr *dest ) { 
			 | 
		
		
	
		
			
			| 
				110
			 | 
			
				110
			 | 
			
			
				
				 	int local; 
			 | 
		
		
	
		
			
			| 
				111
			 | 
			
				111
			 | 
			
			
				
				 	int has_gw; 
			 | 
		
		
	
		
			
			| 
				112
			 | 
			
				112
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				113
			 | 
			
				
			 | 
			
			
				
				-	/* Never attempt to route the broadcast address */ 
			 | 
		
		
	
		
			
			| 
				114
			 | 
			
				
			 | 
			
			
				
				-	if ( dest->s_addr == INADDR_BROADCAST ) 
			 | 
		
		
	
		
			
			| 
				115
			 | 
			
				
			 | 
			
			
				
				-		return NULL; 
			 | 
		
		
	
		
			
			| 
				116
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				117
			 | 
			
				113
			 | 
			
			
				
				 	/* Find first usable route in routing table */ 
			 | 
		
		
	
		
			
			| 
				118
			 | 
			
				114
			 | 
			
			
				
				 	list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) { 
			 | 
		
		
	
		
			
			| 
				119
			 | 
			
				115
			 | 
			
			
				
				 		if ( ! netdev_is_open ( miniroute->netdev ) ) 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -260,15 +256,17 @@ static uint16_t ipv4_pshdr_chksum ( struct io_buffer *iobuf, uint16_t csum ) { 
			 | 
		
		
	
		
			
			| 
				260
			 | 
			
				256
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				261
			 | 
			
				257
			 | 
			
			
				
				  * @v dest		IPv4 destination address 
			 | 
		
		
	
		
			
			| 
				262
			 | 
			
				258
			 | 
			
			
				
				  * @v src		IPv4 source address 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				259
			 | 
			
			
				
				+ * @v netmask		IPv4 subnet mask 
			 | 
		
		
	
		
			
			| 
				263
			 | 
			
				260
			 | 
			
			
				
				  * @v netdev		Network device 
			 | 
		
		
	
		
			
			| 
				264
			 | 
			
				261
			 | 
			
			
				
				  * @v ll_dest		Link-layer destination address buffer 
			 | 
		
		
	
		
			
			| 
				265
			 | 
			
				262
			 | 
			
			
				
				  * @ret rc		Return status code 
			 | 
		
		
	
		
			
			| 
				266
			 | 
			
				263
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				267
			 | 
			
				264
			 | 
			
			
				
				 static int ipv4_ll_addr ( struct in_addr dest, struct in_addr src, 
			 | 
		
		
	
		
			
			| 
				268
			 | 
			
				
			 | 
			
			
				
				-			  struct net_device *netdev, uint8_t *ll_dest ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				265
			 | 
			
			
				
				+			  struct in_addr netmask, struct net_device *netdev, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				266
			 | 
			
			
				
				+			  uint8_t *ll_dest ) { 
			 | 
		
		
	
		
			
			| 
				269
			 | 
			
				267
			 | 
			
			
				
				 	struct ll_protocol *ll_protocol = netdev->ll_protocol; 
			 | 
		
		
	
		
			
			| 
				270
			 | 
			
				268
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				271
			 | 
			
				
			 | 
			
			
				
				-	if ( dest.s_addr == INADDR_BROADCAST ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				269
			 | 
			
			
				
				+	if ( ( ( dest.s_addr ^ INADDR_BROADCAST ) & ~netmask.s_addr ) == 0 ) { 
			 | 
		
		
	
		
			
			| 
				272
			 | 
			
				270
			 | 
			
			
				
				 		/* Broadcast address */ 
			 | 
		
		
	
		
			
			| 
				273
			 | 
			
				271
			 | 
			
			
				
				 		memcpy ( ll_dest, netdev->ll_broadcast, 
			 | 
		
		
	
		
			
			| 
				274
			 | 
			
				272
			 | 
			
			
				
				 			 ll_protocol->ll_addr_len ); 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -306,6 +304,7 @@ static int ipv4_tx ( struct io_buffer *iobuf, 
			 | 
		
		
	
		
			
			| 
				306
			 | 
			
				304
			 | 
			
			
				
				 	struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest ); 
			 | 
		
		
	
		
			
			| 
				307
			 | 
			
				305
			 | 
			
			
				
				 	struct ipv4_miniroute *miniroute; 
			 | 
		
		
	
		
			
			| 
				308
			 | 
			
				306
			 | 
			
			
				
				 	struct in_addr next_hop; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				307
			 | 
			
			
				
				+	struct in_addr netmask = { .s_addr = 0 }; 
			 | 
		
		
	
		
			
			| 
				309
			 | 
			
				308
			 | 
			
			
				
				 	uint8_t ll_dest[MAX_LL_ADDR_LEN]; 
			 | 
		
		
	
		
			
			| 
				310
			 | 
			
				309
			 | 
			
			
				
				 	int rc; 
			 | 
		
		
	
		
			
			| 
				311
			 | 
			
				310
			 | 
			
			
				
				  
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -326,6 +325,7 @@ static int ipv4_tx ( struct io_buffer *iobuf, 
			 | 
		
		
	
		
			
			| 
				326
			 | 
			
				325
			 | 
			
			
				
				 	     ( ! IN_MULTICAST ( ntohl ( next_hop.s_addr ) ) ) && 
			 | 
		
		
	
		
			
			| 
				327
			 | 
			
				326
			 | 
			
			
				
				 	     ( ( miniroute = ipv4_route ( &next_hop ) ) != NULL ) ) { 
			 | 
		
		
	
		
			
			| 
				328
			 | 
			
				327
			 | 
			
			
				
				 		iphdr->src = miniroute->address; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				328
			 | 
			
			
				
				+		netmask = miniroute->netmask; 
			 | 
		
		
	
		
			
			| 
				329
			 | 
			
				329
			 | 
			
			
				
				 		netdev = miniroute->netdev; 
			 | 
		
		
	
		
			
			| 
				330
			 | 
			
				330
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				331
			 | 
			
				331
			 | 
			
			
				
				 	if ( ! netdev ) { 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -343,7 +343,7 @@ static int ipv4_tx ( struct io_buffer *iobuf, 
			 | 
		
		
	
		
			
			| 
				343
			 | 
			
				343
			 | 
			
			
				
				 			       ( ( netdev->rx_stats.good & 0xf ) << 0 ) ); 
			 | 
		
		
	
		
			
			| 
				344
			 | 
			
				344
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				345
			 | 
			
				345
			 | 
			
			
				
				 	/* Determine link-layer destination address */ 
			 | 
		
		
	
		
			
			| 
				346
			 | 
			
				
			 | 
			
			
				
				-	if ( ( rc = ipv4_ll_addr ( next_hop, iphdr->src, netdev, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				346
			 | 
			
			
				
				+	if ( ( rc = ipv4_ll_addr ( next_hop, iphdr->src, netmask, netdev, 
			 | 
		
		
	
		
			
			| 
				347
			 | 
			
				347
			 | 
			
			
				
				 				   ll_dest ) ) != 0 ) { 
			 | 
		
		
	
		
			
			| 
				348
			 | 
			
				348
			 | 
			
			
				
				 		DBG ( "IPv4 has no link-layer address for %s: %s\n", 
			 | 
		
		
	
		
			
			| 
				349
			 | 
			
				349
			 | 
			
			
				
				 		      inet_ntoa ( next_hop ), strerror ( rc ) ); 
			 |