|
@@ -224,6 +224,8 @@ struct dhcp_session {
|
224
|
224
|
int no_pxedhcp;
|
225
|
225
|
/** ProxyDHCP server */
|
226
|
226
|
struct in_addr proxy_server;
|
|
227
|
+ /** ProxyDHCP port */
|
|
228
|
+ uint16_t proxy_port;
|
227
|
229
|
/** ProxyDHCP server priority */
|
228
|
230
|
int proxy_priority;
|
229
|
231
|
|
|
@@ -357,6 +359,8 @@ static void dhcp_discovery_rx ( struct dhcp_session *dhcp,
|
357
|
359
|
vci, sizeof ( vci ) );
|
358
|
360
|
has_pxeclient = ( ( vci_len >= ( int ) sizeof ( vci ) ) &&
|
359
|
361
|
( strncmp ( "PXEClient", vci, sizeof (vci) ) == 0 ));
|
|
362
|
+
|
|
363
|
+ /* Identify presence of vendor-specific options */
|
360
|
364
|
pxeopts_len = dhcppkt_fetch ( dhcppkt, DHCP_VENDOR_ENCAP, NULL, 0 );
|
361
|
365
|
has_pxeopts = ( pxeopts_len >= 0 );
|
362
|
366
|
if ( has_pxeclient )
|
|
@@ -386,9 +390,17 @@ static void dhcp_discovery_rx ( struct dhcp_session *dhcp,
|
386
|
390
|
}
|
387
|
391
|
|
388
|
392
|
/* Select as ProxyDHCP offer, if applicable */
|
389
|
|
- if ( has_pxeclient && ( ! has_pxeopts ) && ( msgtype == DHCPOFFER ) &&
|
|
393
|
+ if ( has_pxeclient && ( msgtype == DHCPOFFER ) &&
|
390
|
394
|
( priority >= dhcp->proxy_priority ) ) {
|
|
395
|
+ /* If the offer already includes the PXE options, then
|
|
396
|
+ * assume that we can send the ProxyDHCPREQUEST to
|
|
397
|
+ * port 67 (since the DHCPDISCOVER that triggered this
|
|
398
|
+ * ProxyDHCPOFFER was sent to port 67). Otherwise,
|
|
399
|
+ * send the ProxyDHCPREQUEST to port 4011.
|
|
400
|
+ */
|
391
|
401
|
dhcp->proxy_server = server_id;
|
|
402
|
+ dhcp->proxy_port = ( has_pxeopts ? htons ( BOOTPS_PORT )
|
|
403
|
+ : htons ( PXE_PORT ) );
|
392
|
404
|
dhcp->proxy_priority = priority;
|
393
|
405
|
}
|
394
|
406
|
|
|
@@ -527,7 +539,11 @@ static void dhcp_request_rx ( struct dhcp_session *dhcp,
|
527
|
539
|
}
|
528
|
540
|
|
529
|
541
|
/* Start ProxyDHCPREQUEST if applicable */
|
530
|
|
- if ( dhcp->proxy_server.s_addr && ( ! dhcp->no_pxedhcp ) ) {
|
|
542
|
+ if ( dhcp->proxy_server.s_addr /* Have ProxyDHCP server */ &&
|
|
543
|
+ ( ! dhcp->no_pxedhcp ) /* ProxyDHCP not disabled */ &&
|
|
544
|
+ ( /* ProxyDHCP server is not just the DHCP server itself */
|
|
545
|
+ ( dhcp->proxy_server.s_addr != dhcp->server.s_addr ) ||
|
|
546
|
+ ( dhcp->proxy_port != htons ( BOOTPS_PORT ) ) ) ) {
|
531
|
547
|
dhcp_set_state ( dhcp, &dhcp_state_proxy );
|
532
|
548
|
return;
|
533
|
549
|
}
|
|
@@ -569,8 +585,8 @@ static int dhcp_proxy_tx ( struct dhcp_session *dhcp,
|
569
|
585
|
struct sockaddr_in *peer ) {
|
570
|
586
|
int rc;
|
571
|
587
|
|
572
|
|
- DBGC ( dhcp, "DHCP %p ProxyDHCP REQUEST to %s:%d\n",
|
573
|
|
- dhcp, inet_ntoa ( dhcp->proxy_server ), PXE_PORT );
|
|
588
|
+ DBGC ( dhcp, "DHCP %p ProxyDHCP REQUEST to %s:%d\n", dhcp,
|
|
589
|
+ inet_ntoa ( dhcp->proxy_server ), ntohs ( dhcp->proxy_port ) );
|
574
|
590
|
|
575
|
591
|
/* Set server ID */
|
576
|
592
|
if ( ( rc = dhcppkt_store ( dhcppkt, DHCP_SERVER_IDENTIFIER,
|
|
@@ -580,7 +596,7 @@ static int dhcp_proxy_tx ( struct dhcp_session *dhcp,
|
580
|
596
|
|
581
|
597
|
/* Set server address */
|
582
|
598
|
peer->sin_addr = dhcp->proxy_server;
|
583
|
|
- peer->sin_port = htons ( PXE_PORT );
|
|
599
|
+ peer->sin_port = dhcp->proxy_port;
|
584
|
600
|
|
585
|
601
|
return 0;
|
586
|
602
|
}
|
|
@@ -608,7 +624,7 @@ static void dhcp_proxy_rx ( struct dhcp_session *dhcp,
|
608
|
624
|
DBGC ( dhcp, "\n" );
|
609
|
625
|
|
610
|
626
|
/* Filter out unacceptable responses */
|
611
|
|
- if ( peer->sin_port != htons ( PXE_PORT ) )
|
|
627
|
+ if ( peer->sin_port != dhcp->proxy_port )
|
612
|
628
|
return;
|
613
|
629
|
if ( msgtype != DHCPACK )
|
614
|
630
|
return;
|