Преглед на файлове

[ipv4] Discard unwanted unicast packets

Explicitly discard any unicast packets for addresses that we do not
control, to avoid unexpected behaviour when operating in promiscuous
mode (which is now the default, thanks to FCoE).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown преди 13 години
родител
ревизия
dfbb3bd184
променени са 1 файла, в които са добавени 50 реда и са изтрити 10 реда
  1. 50
    10
      src/net/ipv4.c

+ 50
- 10
src/net/ipv4.c Целия файл

@@ -378,6 +378,42 @@ static int ipv4_tx ( struct io_buffer *iobuf,
378 378
 	return rc;
379 379
 }
380 380
 
381
+/**
382
+ * Check if network device has any IPv4 address
383
+ *
384
+ * @v netdev		Network device
385
+ * @ret has_any_addr	Network device has any IPv4 address
386
+ */
387
+static int ipv4_has_any_addr ( struct net_device *netdev ) {
388
+	struct ipv4_miniroute *miniroute;
389
+
390
+	list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
391
+		if ( miniroute->netdev == netdev )
392
+			return 1;
393
+	}
394
+	return 0;
395
+}
396
+
397
+/**
398
+ * Check if network device has a specific IPv4 address
399
+ *
400
+ * @v netdev		Network device
401
+ * @v addr		IPv4 address
402
+ * @ret has_addr	Network device has this IPv4 address
403
+ */
404
+static int ipv4_has_addr ( struct net_device *netdev, struct in_addr addr ) {
405
+	struct ipv4_miniroute *miniroute;
406
+
407
+	list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
408
+		if ( ( miniroute->netdev == netdev ) &&
409
+		     ( miniroute->address.s_addr == addr.s_addr ) ) {
410
+			/* Found matching address */
411
+			return 1;
412
+		}
413
+	}
414
+	return 0;
415
+}
416
+
381 417
 /**
382 418
  * Process incoming packets
383 419
  *
@@ -392,10 +428,10 @@ static int ipv4_tx ( struct io_buffer *iobuf,
392 428
  * and sends it to the transport layer.
393 429
  */
394 430
 static int ipv4_rx ( struct io_buffer *iobuf,
395
-		     struct net_device *netdev __unused,
431
+		     struct net_device *netdev,
396 432
 		     const void *ll_dest __unused,
397 433
 		     const void *ll_source __unused,
398
-		     unsigned int flags __unused ) {
434
+		     unsigned int flags ) {
399 435
 	struct iphdr *iphdr = iobuf->data;
400 436
 	size_t hdrlen;
401 437
 	size_t len;
@@ -451,6 +487,15 @@ static int ipv4_rx ( struct io_buffer *iobuf,
451 487
 	      inet_ntoa ( iphdr->src ), ntohs ( iphdr->len ), iphdr->protocol,
452 488
 	      ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) );
453 489
 
490
+	/* Discard unicast packets not destined for us */
491
+	if ( ( ! ( flags & LL_MULTICAST ) ) &&
492
+	     ipv4_has_any_addr ( netdev ) &&
493
+	     ( ! ipv4_has_addr ( netdev, iphdr->dest ) ) ) {
494
+		DBG ( "IPv4 discarding non-local unicast packet for %s\n",
495
+		      inet_ntoa ( iphdr->dest ) );
496
+		goto err;
497
+	}
498
+
454 499
 	/* Truncate packet to correct length, calculate pseudo-header
455 500
 	 * checksum and then strip off the IPv4 header.
456 501
 	 */
@@ -499,15 +544,10 @@ static int ipv4_rx ( struct io_buffer *iobuf,
499 544
  */
500 545
 static int ipv4_arp_check ( struct net_device *netdev, const void *net_addr ) {
501 546
 	const struct in_addr *address = net_addr;
502
-	struct ipv4_miniroute *miniroute;
503 547
 
504
-	list_for_each_entry ( miniroute, &ipv4_miniroutes, list ) {
505
-		if ( ( miniroute->netdev == netdev ) &&
506
-		     ( miniroute->address.s_addr == address->s_addr ) ) {
507
-			/* Found matching address */
508
-			return 0;
509
-		}
510
-	}
548
+	if ( ipv4_has_addr ( netdev, *address ) )
549
+		return 0;
550
+
511 551
 	return -ENOENT;
512 552
 }
513 553
 

Loading…
Отказ
Запис