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