Browse Source

[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>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
5b41381f33
1 changed files with 7 additions and 7 deletions
  1. 7
    7
      src/net/ipv4.c

+ 7
- 7
src/net/ipv4.c View File

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

Loading…
Cancel
Save