|  | @@ -125,6 +125,21 @@ struct dhcp_client_uuid {
 | 
		
	
		
			
			| 125 | 125 |  
 | 
		
	
		
			
			| 126 | 126 |  #define DHCP_CLIENT_UUID_TYPE 0
 | 
		
	
		
			
			| 127 | 127 |  
 | 
		
	
		
			
			|  | 128 | +/** DHCP PXE boot menu item */
 | 
		
	
		
			
			|  | 129 | +struct dhcp_pxe_boot_menu_item {
 | 
		
	
		
			
			|  | 130 | +	/** "Type"
 | 
		
	
		
			
			|  | 131 | +	 *
 | 
		
	
		
			
			|  | 132 | +	 * This field actually identifies the specific boot server (or
 | 
		
	
		
			
			|  | 133 | +	 * cluster of boot servers offering identical boot files).
 | 
		
	
		
			
			|  | 134 | +	 */
 | 
		
	
		
			
			|  | 135 | +	uint16_t type;
 | 
		
	
		
			
			|  | 136 | +	/** "Layer"
 | 
		
	
		
			
			|  | 137 | +	 *
 | 
		
	
		
			
			|  | 138 | +	 * Just don't ask.
 | 
		
	
		
			
			|  | 139 | +	 */
 | 
		
	
		
			
			|  | 140 | +	uint16_t layer;
 | 
		
	
		
			
			|  | 141 | +} __attribute__ (( packed ));
 | 
		
	
		
			
			|  | 142 | +
 | 
		
	
		
			
			| 128 | 143 |  /**
 | 
		
	
		
			
			| 129 | 144 |   * Name a DHCP packet type
 | 
		
	
		
			
			| 130 | 145 |   *
 | 
		
	
	
		
			
			|  | @@ -448,27 +463,30 @@ int dhcp_create_packet ( struct dhcp_packet *dhcppkt,
 | 
		
	
		
			
			| 448 | 463 |   *
 | 
		
	
		
			
			| 449 | 464 |   * @v dhcppkt		DHCP packet structure to fill in
 | 
		
	
		
			
			| 450 | 465 |   * @v netdev		Network device
 | 
		
	
		
			
			| 451 |  | - * @v ciaddr		Client IP address
 | 
		
	
		
			
			| 452 |  | - * @v offer		DHCP offer, if applicable
 | 
		
	
		
			
			|  | 466 | + * @v msgtype		DHCP message type
 | 
		
	
		
			
			|  | 467 | + * @v ciaddr		Client IP address, if applicable
 | 
		
	
		
			
			|  | 468 | + * @v server		Server identifier, if applicable
 | 
		
	
		
			
			|  | 469 | + * @v requested_ip	Requested address, if applicable
 | 
		
	
		
			
			|  | 470 | + * @v menu_item		PXE menu item, if applicable
 | 
		
	
		
			
			| 453 | 471 |   * @v data		Buffer for DHCP packet
 | 
		
	
		
			
			| 454 | 472 |   * @v max_len		Size of DHCP packet buffer
 | 
		
	
		
			
			| 455 | 473 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 456 | 474 |   */
 | 
		
	
		
			
			| 457 | 475 |  int dhcp_create_request ( struct dhcp_packet *dhcppkt,
 | 
		
	
		
			
			| 458 |  | -			  struct net_device *netdev, struct in_addr ciaddr,
 | 
		
	
		
			
			| 459 |  | -			  struct dhcp_packet *offer,
 | 
		
	
		
			
			|  | 476 | +			  struct net_device *netdev, unsigned int msgtype,
 | 
		
	
		
			
			|  | 477 | +			  struct in_addr ciaddr, struct in_addr server,
 | 
		
	
		
			
			|  | 478 | +			  struct in_addr requested_ip,
 | 
		
	
		
			
			|  | 479 | +			  struct dhcp_pxe_boot_menu_item *menu_item,
 | 
		
	
		
			
			| 460 | 480 |  			  void *data, size_t max_len ) {
 | 
		
	
		
			
			| 461 | 481 |  	struct device_description *desc = &netdev->dev->desc;
 | 
		
	
		
			
			| 462 | 482 |  	struct dhcp_netdev_desc dhcp_desc;
 | 
		
	
		
			
			| 463 | 483 |  	struct dhcp_client_id client_id;
 | 
		
	
		
			
			| 464 | 484 |  	struct dhcp_client_uuid client_uuid;
 | 
		
	
		
			
			| 465 |  | -	unsigned int msgtype;
 | 
		
	
		
			
			| 466 | 485 |  	size_t dhcp_features_len;
 | 
		
	
		
			
			| 467 | 486 |  	size_t ll_addr_len;
 | 
		
	
		
			
			| 468 | 487 |  	int rc;
 | 
		
	
		
			
			| 469 | 488 |  
 | 
		
	
		
			
			| 470 | 489 |  	/* Create DHCP packet */
 | 
		
	
		
			
			| 471 |  | -	msgtype = ( offer ? DHCPREQUEST : DHCPDISCOVER );
 | 
		
	
		
			
			| 472 | 490 |  	if ( ( rc = dhcp_create_packet ( dhcppkt, netdev, msgtype,
 | 
		
	
		
			
			| 473 | 491 |  					 &dhcp_request_options, data,
 | 
		
	
		
			
			| 474 | 492 |  					 max_len ) ) != 0 ) {
 | 
		
	
	
		
			
			|  | @@ -480,30 +498,23 @@ int dhcp_create_request ( struct dhcp_packet *dhcppkt,
 | 
		
	
		
			
			| 480 | 498 |  	/* Set client IP address */
 | 
		
	
		
			
			| 481 | 499 |  	dhcppkt->dhcphdr->ciaddr = ciaddr;
 | 
		
	
		
			
			| 482 | 500 |  
 | 
		
	
		
			
			| 483 |  | -	/* Copy any required options from previous server repsonse */
 | 
		
	
		
			
			| 484 |  | -	if ( offer ) {
 | 
		
	
		
			
			| 485 |  | -		struct in_addr server = { 0 };
 | 
		
	
		
			
			| 486 |  | -		struct in_addr *ip = &offer->dhcphdr->yiaddr;
 | 
		
	
		
			
			| 487 |  | -
 | 
		
	
		
			
			| 488 |  | -		/* Copy server identifier, if present */
 | 
		
	
		
			
			| 489 |  | -		if ( ( dhcppkt_fetch ( offer, DHCP_SERVER_IDENTIFIER, &server,
 | 
		
	
		
			
			| 490 |  | -				       sizeof ( server ) ) >= 0 ) &&
 | 
		
	
		
			
			| 491 |  | -		     ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
 | 
		
	
		
			
			| 492 |  | -					      &server,
 | 
		
	
		
			
			| 493 |  | -					      sizeof ( server ) ) ) != 0 ) ) {
 | 
		
	
		
			
			|  | 501 | +	/* Set server ID, if present */
 | 
		
	
		
			
			|  | 502 | +	if ( server.s_addr &&
 | 
		
	
		
			
			|  | 503 | +	     ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
 | 
		
	
		
			
			|  | 504 | +				      &server, sizeof ( server ) ) ) != 0 ) ) {
 | 
		
	
		
			
			| 494 | 505 |  			DBG ( "DHCP could not set server ID: %s\n",
 | 
		
	
		
			
			| 495 | 506 |  			      strerror ( rc ) );
 | 
		
	
		
			
			| 496 | 507 |  			return rc;
 | 
		
	
		
			
			| 497 |  | -		}
 | 
		
	
		
			
			|  | 508 | +	}
 | 
		
	
		
			
			| 498 | 509 |  
 | 
		
	
		
			
			| 499 |  | -		/* Copy requested IP address, if present */
 | 
		
	
		
			
			| 500 |  | -		if ( ( ip->s_addr != 0 ) &&
 | 
		
	
		
			
			| 501 |  | -		     ( ( rc = dhcppkt_store ( dhcppkt, DHCP_REQUESTED_ADDRESS,
 | 
		
	
		
			
			| 502 |  | -					      ip, sizeof ( *ip ) ) ) != 0 ) ) {
 | 
		
	
		
			
			| 503 |  | -			DBG ( "DHCP could not set requested address: %s\n",
 | 
		
	
		
			
			| 504 |  | -			      strerror ( rc ) );
 | 
		
	
		
			
			| 505 |  | -			return rc;
 | 
		
	
		
			
			| 506 |  | -		}
 | 
		
	
		
			
			|  | 510 | +	/* Set requested IP address, if present */
 | 
		
	
		
			
			|  | 511 | +	if ( requested_ip.s_addr &&
 | 
		
	
		
			
			|  | 512 | +	     ( ( rc = dhcppkt_store ( dhcppkt, DHCP_REQUESTED_ADDRESS,
 | 
		
	
		
			
			|  | 513 | +				      &requested_ip,
 | 
		
	
		
			
			|  | 514 | +				      sizeof ( requested_ip ) ) ) != 0 ) ) {
 | 
		
	
		
			
			|  | 515 | +		DBG ( "DHCP could not set requested address: %s\n",
 | 
		
	
		
			
			|  | 516 | +		      strerror ( rc ) );
 | 
		
	
		
			
			|  | 517 | +		return rc;
 | 
		
	
		
			
			| 507 | 518 |  	}
 | 
		
	
		
			
			| 508 | 519 |  
 | 
		
	
		
			
			| 509 | 520 |  	/* Add options to identify the feature list */
 | 
		
	
	
		
			
			|  | @@ -553,6 +564,16 @@ int dhcp_create_request ( struct dhcp_packet *dhcppkt,
 | 
		
	
		
			
			| 553 | 564 |  		}
 | 
		
	
		
			
			| 554 | 565 |  	}
 | 
		
	
		
			
			| 555 | 566 |  
 | 
		
	
		
			
			|  | 567 | +	/* Set PXE boot menu item, if present */
 | 
		
	
		
			
			|  | 568 | +	if ( menu_item && menu_item->type &&
 | 
		
	
		
			
			|  | 569 | +	     ( ( rc = dhcppkt_store ( dhcppkt, DHCP_PXE_BOOT_MENU_ITEM,
 | 
		
	
		
			
			|  | 570 | +				      menu_item,
 | 
		
	
		
			
			|  | 571 | +				      sizeof ( *menu_item ) ) ) != 0 ) ) {
 | 
		
	
		
			
			|  | 572 | +		DBG ( "DHCP could not set PXE menu item: %s\n",
 | 
		
	
		
			
			|  | 573 | +		      strerror ( rc ) );
 | 
		
	
		
			
			|  | 574 | +		return rc;
 | 
		
	
		
			
			|  | 575 | +	}
 | 
		
	
		
			
			|  | 576 | +
 | 
		
	
		
			
			| 556 | 577 |  	return 0;
 | 
		
	
		
			
			| 557 | 578 |  }
 | 
		
	
		
			
			| 558 | 579 |  
 | 
		
	
	
		
			
			|  | @@ -563,11 +584,11 @@ int dhcp_create_request ( struct dhcp_packet *dhcppkt,
 | 
		
	
		
			
			| 563 | 584 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 564 | 585 |   */
 | 
		
	
		
			
			| 565 | 586 |  static int dhcp_tx ( struct dhcp_session *dhcp ) {
 | 
		
	
		
			
			| 566 |  | -	static struct sockaddr_in proxydhcp_server = {
 | 
		
	
		
			
			|  | 587 | +	static struct sockaddr_in dest = {
 | 
		
	
		
			
			| 567 | 588 |  		.sin_family = AF_INET,
 | 
		
	
		
			
			| 568 | 589 |  		.sin_port = htons ( PROXYDHCP_PORT ),
 | 
		
	
		
			
			| 569 | 590 |  	};
 | 
		
	
		
			
			| 570 |  | -	static struct sockaddr_in client = {
 | 
		
	
		
			
			|  | 591 | +	static struct sockaddr_in src = {
 | 
		
	
		
			
			| 571 | 592 |  		.sin_family = AF_INET,
 | 
		
	
		
			
			| 572 | 593 |  		.sin_port = htons ( BOOTPC_PORT ),
 | 
		
	
		
			
			| 573 | 594 |  	};
 | 
		
	
	
		
			
			|  | @@ -576,9 +597,11 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) {
 | 
		
	
		
			
			| 576 | 597 |  	};
 | 
		
	
		
			
			| 577 | 598 |  	struct io_buffer *iobuf;
 | 
		
	
		
			
			| 578 | 599 |  	struct dhcp_packet dhcppkt;
 | 
		
	
		
			
			| 579 |  | -	struct dhcp_packet *offer = NULL;
 | 
		
	
		
			
			| 580 | 600 |  	struct in_addr ciaddr = { 0 };
 | 
		
	
		
			
			| 581 |  | -	int check_len;
 | 
		
	
		
			
			|  | 601 | +	struct in_addr server = { 0 };
 | 
		
	
		
			
			|  | 602 | +	struct in_addr requested_ip = { 0 };
 | 
		
	
		
			
			|  | 603 | +	struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 };
 | 
		
	
		
			
			|  | 604 | +	unsigned int msgtype;
 | 
		
	
		
			
			| 582 | 605 |  	int rc;
 | 
		
	
		
			
			| 583 | 606 |  
 | 
		
	
		
			
			| 584 | 607 |  	/* Start retry timer.  Do this first so that failures to
 | 
		
	
	
		
			
			|  | @@ -589,59 +612,82 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) {
 | 
		
	
		
			
			| 589 | 612 |  	/* Determine packet contents based on current state */
 | 
		
	
		
			
			| 590 | 613 |  	switch ( dhcp->state ) {
 | 
		
	
		
			
			| 591 | 614 |  	case DHCP_STATE_DISCOVER:
 | 
		
	
		
			
			| 592 |  | -		DBGC ( dhcp, "DHCP %p transmitting DHCPDISCOVER\n", dhcp );
 | 
		
	
		
			
			|  | 615 | +		msgtype = DHCPDISCOVER;
 | 
		
	
		
			
			| 593 | 616 |  		break;
 | 
		
	
		
			
			| 594 | 617 |  	case DHCP_STATE_REQUEST:
 | 
		
	
		
			
			| 595 |  | -		DBGC ( dhcp, "DHCP %p transmitting DHCPREQUEST\n", dhcp );
 | 
		
	
		
			
			| 596 | 618 |  		assert ( dhcp->dhcpoffer );
 | 
		
	
		
			
			| 597 |  | -		offer = &dhcp->dhcpoffer->dhcppkt;
 | 
		
	
		
			
			|  | 619 | +		msgtype = DHCPREQUEST;
 | 
		
	
		
			
			|  | 620 | +		dhcppkt_fetch ( &dhcp->dhcpoffer->dhcppkt,
 | 
		
	
		
			
			|  | 621 | +				DHCP_SERVER_IDENTIFIER, &server,
 | 
		
	
		
			
			|  | 622 | +				sizeof ( server ) );
 | 
		
	
		
			
			|  | 623 | +		requested_ip = dhcp->dhcpoffer->dhcppkt.dhcphdr->yiaddr;
 | 
		
	
		
			
			| 598 | 624 |  		break;
 | 
		
	
		
			
			| 599 | 625 |  	case DHCP_STATE_PROXYREQUEST:
 | 
		
	
		
			
			| 600 |  | -		DBGC ( dhcp, "DHCP %p transmitting ProxyDHCPREQUEST\n", dhcp );
 | 
		
	
		
			
			| 601 | 626 |  		assert ( dhcp->dhcpoffer );
 | 
		
	
		
			
			| 602 | 627 |  		assert ( dhcp->proxydhcpoffer );
 | 
		
	
		
			
			| 603 | 628 |  		assert ( dhcp->dhcpack );
 | 
		
	
		
			
			| 604 |  | -		offer = &dhcp->proxydhcpoffer->dhcppkt;
 | 
		
	
		
			
			|  | 629 | +		msgtype = DHCPREQUEST;
 | 
		
	
		
			
			| 605 | 630 |  		ciaddr = dhcp->dhcpoffer->dhcppkt.dhcphdr->yiaddr;
 | 
		
	
		
			
			| 606 |  | -		check_len = dhcppkt_fetch ( offer, DHCP_SERVER_IDENTIFIER,
 | 
		
	
		
			
			| 607 |  | -					    &proxydhcp_server.sin_addr,
 | 
		
	
		
			
			| 608 |  | -					    sizeof(proxydhcp_server.sin_addr));
 | 
		
	
		
			
			| 609 |  | -		meta.dest = ( struct sockaddr * ) &proxydhcp_server;
 | 
		
	
		
			
			| 610 |  | -		assert ( ciaddr.s_addr != 0 );
 | 
		
	
		
			
			| 611 |  | -		assert ( proxydhcp_server.sin_addr.s_addr != 0 );
 | 
		
	
		
			
			| 612 |  | -		assert ( check_len == sizeof ( proxydhcp_server.sin_addr ) );
 | 
		
	
		
			
			|  | 631 | +		dhcppkt_fetch ( &dhcp->proxydhcpoffer->dhcppkt,
 | 
		
	
		
			
			|  | 632 | +				DHCP_SERVER_IDENTIFIER, &dest.sin_addr,
 | 
		
	
		
			
			|  | 633 | +				sizeof ( dest.sin_addr ) );
 | 
		
	
		
			
			|  | 634 | +		meta.dest = ( struct sockaddr * ) &dest;
 | 
		
	
		
			
			|  | 635 | +		server = dest.sin_addr;
 | 
		
	
		
			
			|  | 636 | +		assert ( dest.sin_addr.s_addr );
 | 
		
	
		
			
			|  | 637 | +		assert ( ciaddr.s_addr );
 | 
		
	
		
			
			| 613 | 638 |  		break;
 | 
		
	
		
			
			| 614 | 639 |  	case DHCP_STATE_BSREQUEST:
 | 
		
	
		
			
			| 615 |  | -		DBGC ( dhcp, "DHCP %p transmitting BootServerREQUEST\n",
 | 
		
	
		
			
			| 616 |  | -		       dhcp );
 | 
		
	
		
			
			| 617 | 640 |  		assert ( dhcp->dhcpoffer );
 | 
		
	
		
			
			| 618 | 641 |  		assert ( dhcp->proxydhcpoffer );
 | 
		
	
		
			
			| 619 | 642 |  		assert ( dhcp->dhcpack );
 | 
		
	
		
			
			| 620 | 643 |  		assert ( dhcp->proxydhcpack );
 | 
		
	
		
			
			| 621 |  | -		offer = &dhcp->proxydhcpoffer->dhcppkt;
 | 
		
	
		
			
			|  | 644 | +		msgtype = DHCPREQUEST;
 | 
		
	
		
			
			| 622 | 645 |  		ciaddr = dhcp->dhcpoffer->dhcppkt.dhcphdr->yiaddr;
 | 
		
	
		
			
			| 623 |  | -		check_len = dhcppkt_fetch ( &dhcp->proxydhcpack->dhcppkt,
 | 
		
	
		
			
			| 624 |  | -					    DHCP_PXE_BOOT_SERVER_MCAST,
 | 
		
	
		
			
			| 625 |  | -					    &proxydhcp_server.sin_addr,
 | 
		
	
		
			
			| 626 |  | -					    sizeof(proxydhcp_server.sin_addr));
 | 
		
	
		
			
			| 627 |  | -		meta.dest = ( struct sockaddr * ) &proxydhcp_server;
 | 
		
	
		
			
			| 628 |  | -		assert ( ciaddr.s_addr != 0 );
 | 
		
	
		
			
			| 629 |  | -		assert ( proxydhcp_server.sin_addr.s_addr != 0 );
 | 
		
	
		
			
			| 630 |  | -		assert ( check_len == sizeof ( proxydhcp_server.sin_addr ) );
 | 
		
	
		
			
			|  | 646 | +		dhcppkt_fetch ( &dhcp->proxydhcpack->dhcppkt,
 | 
		
	
		
			
			|  | 647 | +				DHCP_PXE_BOOT_SERVER_MCAST,
 | 
		
	
		
			
			|  | 648 | +				&dest.sin_addr, sizeof ( dest.sin_addr ) );
 | 
		
	
		
			
			|  | 649 | +		meta.dest = ( struct sockaddr * ) &dest;
 | 
		
	
		
			
			|  | 650 | +		dhcppkt_fetch ( &dhcp->proxydhcpack->dhcppkt,
 | 
		
	
		
			
			|  | 651 | +				DHCP_PXE_BOOT_MENU, &menu_item.type,
 | 
		
	
		
			
			|  | 652 | +				sizeof ( menu_item.type ) );
 | 
		
	
		
			
			|  | 653 | +		assert ( dest.sin_addr.s_addr );
 | 
		
	
		
			
			|  | 654 | +		assert ( menu_item.type );
 | 
		
	
		
			
			|  | 655 | +		assert ( ciaddr.s_addr );
 | 
		
	
		
			
			| 631 | 656 |  		break;
 | 
		
	
		
			
			| 632 | 657 |  	default:
 | 
		
	
		
			
			| 633 | 658 |  		assert ( 0 );
 | 
		
	
		
			
			| 634 |  | -		break;
 | 
		
	
		
			
			|  | 659 | +		return -EINVAL;
 | 
		
	
		
			
			| 635 | 660 |  	}
 | 
		
	
		
			
			| 636 | 661 |  
 | 
		
	
		
			
			|  | 662 | +	DBGC ( dhcp, "DHCP %p %s", dhcp, dhcp_msgtype_name ( msgtype ) );
 | 
		
	
		
			
			|  | 663 | +	if ( server.s_addr )
 | 
		
	
		
			
			|  | 664 | +		DBGC ( dhcp, " to %s", inet_ntoa ( server ) );
 | 
		
	
		
			
			|  | 665 | +	if ( meta.dest ) {
 | 
		
	
		
			
			|  | 666 | +		if ( dest.sin_addr.s_addr == server.s_addr ) {
 | 
		
	
		
			
			|  | 667 | +			DBGC ( dhcp, ":%d (unicast)",
 | 
		
	
		
			
			|  | 668 | +			       ntohs ( dest.sin_port ) );
 | 
		
	
		
			
			|  | 669 | +		} else {
 | 
		
	
		
			
			|  | 670 | +			DBGC ( dhcp, " via %s:%d", inet_ntoa ( dest.sin_addr ),
 | 
		
	
		
			
			|  | 671 | +			       ntohs ( dest.sin_port ) );
 | 
		
	
		
			
			|  | 672 | +		}
 | 
		
	
		
			
			|  | 673 | +	} else {
 | 
		
	
		
			
			|  | 674 | +		DBGC ( dhcp, " (broadcast)" );
 | 
		
	
		
			
			|  | 675 | +	}
 | 
		
	
		
			
			|  | 676 | +	if ( requested_ip.s_addr )
 | 
		
	
		
			
			|  | 677 | +		DBGC ( dhcp, " for %s", inet_ntoa ( requested_ip ) );
 | 
		
	
		
			
			|  | 678 | +	if ( menu_item.type )
 | 
		
	
		
			
			|  | 679 | +		DBGC ( dhcp, " for item %04x", ntohs ( menu_item.type ) );
 | 
		
	
		
			
			|  | 680 | +	DBGC ( dhcp, "\n" );
 | 
		
	
		
			
			|  | 681 | +
 | 
		
	
		
			
			| 637 | 682 |  	/* Allocate buffer for packet */
 | 
		
	
		
			
			| 638 | 683 |  	iobuf = xfer_alloc_iob ( &dhcp->xfer, DHCP_MIN_LEN );
 | 
		
	
		
			
			| 639 | 684 |  	if ( ! iobuf )
 | 
		
	
		
			
			| 640 | 685 |  		return -ENOMEM;
 | 
		
	
		
			
			| 641 | 686 |  
 | 
		
	
		
			
			| 642 | 687 |  	/* Create DHCP packet in temporary buffer */
 | 
		
	
		
			
			| 643 |  | -	if ( ( rc = dhcp_create_request ( &dhcppkt, dhcp->netdev,
 | 
		
	
		
			
			| 644 |  | -					  ciaddr, offer, iobuf->data,
 | 
		
	
		
			
			|  | 688 | +	if ( ( rc = dhcp_create_request ( &dhcppkt, dhcp->netdev, msgtype,
 | 
		
	
		
			
			|  | 689 | +					  ciaddr, server, requested_ip,
 | 
		
	
		
			
			|  | 690 | +					  &menu_item, iobuf->data,
 | 
		
	
		
			
			| 645 | 691 |  					  iob_tailroom ( iobuf ) ) ) != 0 ) {
 | 
		
	
		
			
			| 646 | 692 |  		DBGC ( dhcp, "DHCP %p could not construct DHCP request: %s\n",
 | 
		
	
		
			
			| 647 | 693 |  		       dhcp, strerror ( rc ) );
 | 
		
	
	
		
			
			|  | @@ -650,8 +696,8 @@ static int dhcp_tx ( struct dhcp_session *dhcp ) {
 | 
		
	
		
			
			| 650 | 696 |  
 | 
		
	
		
			
			| 651 | 697 |  	/* Explicitly specify source address, if available. */
 | 
		
	
		
			
			| 652 | 698 |  	if ( ciaddr.s_addr ) {
 | 
		
	
		
			
			| 653 |  | -		client.sin_addr = ciaddr;
 | 
		
	
		
			
			| 654 |  | -		meta.src = ( struct sockaddr * ) &client;
 | 
		
	
		
			
			|  | 699 | +		src.sin_addr = ciaddr;
 | 
		
	
		
			
			|  | 700 | +		meta.src = ( struct sockaddr * ) &src;
 | 
		
	
		
			
			| 655 | 701 |  	}
 | 
		
	
		
			
			| 656 | 702 |  
 | 
		
	
		
			
			| 657 | 703 |  	/* Transmit the packet */
 | 
		
	
	
		
			
			|  | @@ -756,7 +802,7 @@ static void dhcp_store_dhcpoffer ( struct dhcp_session *dhcp,
 | 
		
	
		
			
			| 756 | 802 |  			DBGC ( dhcp, "DHCP %p stored DHCPOFFER %p discarded\n",
 | 
		
	
		
			
			| 757 | 803 |  			       dhcp, *stored_dhcpoffer );
 | 
		
	
		
			
			| 758 | 804 |  		}
 | 
		
	
		
			
			| 759 |  | -		DBGC ( dhcp, "DHCP %p received DHCPOFFER %p stored\n",
 | 
		
	
		
			
			|  | 805 | +		DBGC ( dhcp, "DHCP %p DHCPOFFER %p stored\n",
 | 
		
	
		
			
			| 760 | 806 |  		       dhcp, dhcpoffer );
 | 
		
	
		
			
			| 761 | 807 |  		dhcpset_put ( *stored_dhcpoffer );
 | 
		
	
		
			
			| 762 | 808 |  		*stored_dhcpoffer = dhcpset_get ( dhcpoffer );
 | 
		
	
	
		
			
			|  | @@ -781,16 +827,17 @@ static void dhcp_rx_dhcpoffer ( struct dhcp_session *dhcp,
 | 
		
	
		
			
			| 781 | 827 |  	if ( dhcppkt_fetch ( &dhcpoffer->dhcppkt, DHCP_SERVER_IDENTIFIER,
 | 
		
	
		
			
			| 782 | 828 |  			     &server_id, sizeof ( server_id ) )
 | 
		
	
		
			
			| 783 | 829 |  	     != sizeof ( server_id ) ) {
 | 
		
	
		
			
			| 784 |  | -		DBGC ( dhcp, "DHCP %p received DHCPOFFER %p missing server "
 | 
		
	
		
			
			| 785 |  | -		       "identifier\n", dhcp, dhcpoffer );
 | 
		
	
		
			
			|  | 830 | +		DBGC ( dhcp, "DHCP %p DHCPOFFER %p missing server ID\n",
 | 
		
	
		
			
			|  | 831 | +		       dhcp, dhcpoffer );
 | 
		
	
		
			
			| 786 | 832 |  		/* Could be a valid BOOTP offer; do not abort processing */
 | 
		
	
		
			
			| 787 | 833 |  	}
 | 
		
	
		
			
			| 788 | 834 |  
 | 
		
	
		
			
			| 789 | 835 |  	/* If there is an IP address, it's a normal DHCPOFFER */
 | 
		
	
		
			
			| 790 | 836 |  	if ( dhcpoffer->dhcppkt.dhcphdr->yiaddr.s_addr != 0 ) {
 | 
		
	
		
			
			| 791 |  | -		DBGC ( dhcp, "DHCP %p received DHCPOFFER %p from %s has IP "
 | 
		
	
		
			
			| 792 |  | -		       "address\n",
 | 
		
	
		
			
			|  | 837 | +		DBGC ( dhcp, "DHCP %p DHCPOFFER %p from %s",
 | 
		
	
		
			
			| 793 | 838 |  		       dhcp, dhcpoffer, inet_ntoa ( server_id ) );
 | 
		
	
		
			
			|  | 839 | +		DBGC ( dhcp, " has IP %s\n",
 | 
		
	
		
			
			|  | 840 | +		       inet_ntoa ( dhcpoffer->dhcppkt.dhcphdr->yiaddr ) );
 | 
		
	
		
			
			| 794 | 841 |  		dhcp_store_dhcpoffer ( dhcp, dhcpoffer, &dhcp->dhcpoffer );
 | 
		
	
		
			
			| 795 | 842 |  	}
 | 
		
	
		
			
			| 796 | 843 |  
 | 
		
	
	
		
			
			|  | @@ -803,7 +850,7 @@ static void dhcp_rx_dhcpoffer ( struct dhcp_session *dhcp,
 | 
		
	
		
			
			| 803 | 850 |  	if ( ( server_id.s_addr != 0 ) &&
 | 
		
	
		
			
			| 804 | 851 |  	     ( len >= ( int ) sizeof ( vci ) ) &&
 | 
		
	
		
			
			| 805 | 852 |  	     ( strncmp ( "PXEClient", vci, sizeof ( vci ) ) == 0 ) ) {
 | 
		
	
		
			
			| 806 |  | -		DBGC ( dhcp, "DHCP %p received DHCPOFFER %p from %s is a "
 | 
		
	
		
			
			|  | 853 | +		DBGC ( dhcp, "DHCP %p DHCPOFFER %p from %s is a "
 | 
		
	
		
			
			| 807 | 854 |  		       "ProxyDHCPOFFER\n",
 | 
		
	
		
			
			| 808 | 855 |  		       dhcp, dhcpoffer, inet_ntoa ( server_id ) );
 | 
		
	
		
			
			| 809 | 856 |  		dhcp_store_dhcpoffer ( dhcp, dhcpoffer,
 | 
		
	
	
		
			
			|  | @@ -992,7 +1039,7 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
 | 
		
	
		
			
			| 992 | 1039 |  			      struct xfer_metadata *meta ) {
 | 
		
	
		
			
			| 993 | 1040 |  	struct dhcp_session *dhcp =
 | 
		
	
		
			
			| 994 | 1041 |  		container_of ( xfer, struct dhcp_session, xfer );
 | 
		
	
		
			
			| 995 |  | -	struct sockaddr_tcpip *st_src;
 | 
		
	
		
			
			|  | 1042 | +	struct sockaddr_in *sin_src;
 | 
		
	
		
			
			| 996 | 1043 |  	unsigned int src_port;
 | 
		
	
		
			
			| 997 | 1044 |  	struct dhcp_settings *dhcpset;
 | 
		
	
		
			
			| 998 | 1045 |  	struct dhcphdr *dhcphdr;
 | 
		
	
	
		
			
			|  | @@ -1012,8 +1059,8 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
 | 
		
	
		
			
			| 1012 | 1059 |  		rc = -EINVAL;
 | 
		
	
		
			
			| 1013 | 1060 |  		goto err_no_src;
 | 
		
	
		
			
			| 1014 | 1061 |  	}
 | 
		
	
		
			
			| 1015 |  | -	st_src = ( struct sockaddr_tcpip * ) meta->src;
 | 
		
	
		
			
			| 1016 |  | -	src_port = st_src->st_port;
 | 
		
	
		
			
			|  | 1062 | +	sin_src = ( struct sockaddr_in * ) meta->src;
 | 
		
	
		
			
			|  | 1063 | +	src_port = sin_src->sin_port;
 | 
		
	
		
			
			| 1017 | 1064 |  
 | 
		
	
		
			
			| 1018 | 1065 |  	/* Convert packet into a DHCP settings block */
 | 
		
	
		
			
			| 1019 | 1066 |  	dhcpset = dhcpset_create ( iobuf->data, iob_len ( iobuf ) );
 | 
		
	
	
		
			
			|  | @@ -1027,12 +1074,13 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
 | 
		
	
		
			
			| 1027 | 1074 |  	/* Identify message type */
 | 
		
	
		
			
			| 1028 | 1075 |  	dhcppkt_fetch ( &dhcpset->dhcppkt, DHCP_MESSAGE_TYPE, &msgtype,
 | 
		
	
		
			
			| 1029 | 1076 |  			sizeof ( msgtype ) );
 | 
		
	
		
			
			| 1030 |  | -	DBGC ( dhcp, "DHCP %p received %s %p from port %d\n", dhcp,
 | 
		
	
		
			
			| 1031 |  | -	       dhcp_msgtype_name ( msgtype ), dhcpset, ntohs ( src_port ) );
 | 
		
	
		
			
			|  | 1077 | +	DBGC ( dhcp, "DHCP %p %s %p from %s:%d\n", dhcp,
 | 
		
	
		
			
			|  | 1078 | +	       dhcp_msgtype_name ( msgtype ), dhcpset,
 | 
		
	
		
			
			|  | 1079 | +	       inet_ntoa ( sin_src->sin_addr ), ntohs ( src_port ) );
 | 
		
	
		
			
			| 1032 | 1080 |  
 | 
		
	
		
			
			| 1033 | 1081 |  	/* Check for matching transaction ID */
 | 
		
	
		
			
			| 1034 | 1082 |  	if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) {
 | 
		
	
		
			
			| 1035 |  | -		DBGC ( dhcp, "DHCP %p received %s %p has bad transaction ID\n",
 | 
		
	
		
			
			|  | 1083 | +		DBGC ( dhcp, "DHCP %p %s %p has bad transaction ID\n",
 | 
		
	
		
			
			| 1036 | 1084 |  		       dhcp, dhcp_msgtype_name ( msgtype ), dhcpset );
 | 
		
	
		
			
			| 1037 | 1085 |  		rc = -EINVAL;
 | 
		
	
		
			
			| 1038 | 1086 |  		goto err_xid;
 |