|
@@ -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 ) );
|