|
@@ -108,7 +108,7 @@ static uint32_t dhcp_xid ( struct net_device *netdev ) {
|
108
|
108
|
}
|
109
|
109
|
|
110
|
110
|
/** Options common to all DHCP requests */
|
111
|
|
-struct dhcp_option_block dhcp_request_options = {
|
|
111
|
+static struct dhcp_option_block dhcp_request_options = {
|
112
|
112
|
.data = dhcp_request_options_data,
|
113
|
113
|
.max_len = sizeof ( dhcp_request_options_data ),
|
114
|
114
|
.len = sizeof ( dhcp_request_options_data ),
|
|
@@ -270,8 +270,8 @@ static int copy_dhcp_packet_encap_options ( struct dhcp_packet *dhcppkt,
|
270
|
270
|
* @c options may specify a single options block, or be left as NULL
|
271
|
271
|
* in order to copy options from all registered options blocks.
|
272
|
272
|
*/
|
273
|
|
-int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
|
274
|
|
- struct dhcp_option_block *options ) {
|
|
273
|
+static int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
|
|
274
|
+ struct dhcp_option_block *options ) {
|
275
|
275
|
return copy_dhcp_packet_encap_options ( dhcppkt, options, 0 );
|
276
|
276
|
}
|
277
|
277
|
|
|
@@ -289,9 +289,10 @@ int copy_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
|
289
|
289
|
* dhcp_packet structure that can be passed to
|
290
|
290
|
* set_dhcp_packet_option() or copy_dhcp_packet_options().
|
291
|
291
|
*/
|
292
|
|
-int create_dhcp_packet ( struct net_device *netdev, uint8_t msgtype,
|
293
|
|
- void *data, size_t max_len,
|
294
|
|
- struct dhcp_packet *dhcppkt ) {
|
|
292
|
+static int create_dhcp_packet ( struct net_device *netdev,
|
|
293
|
+ unsigned int msgtype,
|
|
294
|
+ void *data, size_t max_len,
|
|
295
|
+ struct dhcp_packet *dhcppkt ) {
|
295
|
296
|
struct dhcphdr *dhcphdr = data;
|
296
|
297
|
int rc;
|
297
|
298
|
|
|
@@ -473,6 +474,97 @@ static struct dhcp_option_block * dhcp_parse ( const struct dhcphdr *dhcphdr,
|
473
|
474
|
return options;
|
474
|
475
|
}
|
475
|
476
|
|
|
477
|
+/****************************************************************************
|
|
478
|
+ *
|
|
479
|
+ * Whole-packet construction
|
|
480
|
+ *
|
|
481
|
+ */
|
|
482
|
+
|
|
483
|
+/**
|
|
484
|
+ * Create DHCP request
|
|
485
|
+ *
|
|
486
|
+ * @v netdev Network device
|
|
487
|
+ * @v msgtype DHCP message type
|
|
488
|
+ * @v options DHCP server response options, or NULL
|
|
489
|
+ * @v data Buffer for DHCP packet
|
|
490
|
+ * @v max_len Size of DHCP packet buffer
|
|
491
|
+ * @v dhcppkt DHCP packet structure to fill in
|
|
492
|
+ * @ret rc Return status code
|
|
493
|
+ */
|
|
494
|
+int create_dhcp_request ( struct net_device *netdev, int msgtype,
|
|
495
|
+ struct dhcp_option_block *options,
|
|
496
|
+ void *data, size_t max_len,
|
|
497
|
+ struct dhcp_packet *dhcppkt ) {
|
|
498
|
+ int rc;
|
|
499
|
+
|
|
500
|
+ /* Create DHCP packet */
|
|
501
|
+ if ( ( rc = create_dhcp_packet ( netdev, msgtype, data, max_len,
|
|
502
|
+ dhcppkt ) ) != 0 ) {
|
|
503
|
+ DBG ( "DHCP could not create DHCP packet: %s\n",
|
|
504
|
+ strerror ( rc ) );
|
|
505
|
+ return rc;
|
|
506
|
+ }
|
|
507
|
+
|
|
508
|
+ /* Copy in options common to all requests */
|
|
509
|
+ if ( ( rc = copy_dhcp_packet_options ( dhcppkt,
|
|
510
|
+ &dhcp_request_options )) !=0 ){
|
|
511
|
+ DBG ( "DHCP could not set common DHCP options: %s\n",
|
|
512
|
+ strerror ( rc ) );
|
|
513
|
+ return rc;
|
|
514
|
+ }
|
|
515
|
+
|
|
516
|
+ /* Copy any required options from previous server repsonse */
|
|
517
|
+ if ( options ) {
|
|
518
|
+ if ( ( rc = copy_dhcp_packet_option ( dhcppkt, options,
|
|
519
|
+ DHCP_SERVER_IDENTIFIER,
|
|
520
|
+ DHCP_SERVER_IDENTIFIER ) ) != 0 ) {
|
|
521
|
+ DBG ( "DHCP could not set server identifier "
|
|
522
|
+ "option: %s\n", strerror ( rc ) );
|
|
523
|
+ return rc;
|
|
524
|
+ }
|
|
525
|
+ if ( ( rc = copy_dhcp_packet_option ( dhcppkt, options,
|
|
526
|
+ DHCP_EB_YIADDR,
|
|
527
|
+ DHCP_REQUESTED_ADDRESS ) ) != 0 ) {
|
|
528
|
+ DBG ( "DHCP could not set requested address "
|
|
529
|
+ "option: %s\n", strerror ( rc ) );
|
|
530
|
+ return rc;
|
|
531
|
+ }
|
|
532
|
+ }
|
|
533
|
+
|
|
534
|
+ return 0;
|
|
535
|
+}
|
|
536
|
+
|
|
537
|
+/**
|
|
538
|
+ * Create DHCP response
|
|
539
|
+ *
|
|
540
|
+ * @v netdev Network device
|
|
541
|
+ * @v msgtype DHCP message type
|
|
542
|
+ * @v options DHCP options, or NULL
|
|
543
|
+ * @v data Buffer for DHCP packet
|
|
544
|
+ * @v max_len Size of DHCP packet buffer
|
|
545
|
+ * @v dhcppkt DHCP packet structure to fill in
|
|
546
|
+ * @ret rc Return status code
|
|
547
|
+ */
|
|
548
|
+int create_dhcp_response ( struct net_device *netdev, int msgtype,
|
|
549
|
+ struct dhcp_option_block *options,
|
|
550
|
+ void *data, size_t max_len,
|
|
551
|
+ struct dhcp_packet *dhcppkt ) {
|
|
552
|
+ int rc;
|
|
553
|
+
|
|
554
|
+ /* Create packet and copy in options */
|
|
555
|
+ if ( ( rc = create_dhcp_packet ( netdev, msgtype, data, max_len,
|
|
556
|
+ dhcppkt ) ) != 0 ) {
|
|
557
|
+ DBG ( " failed to build packet" );
|
|
558
|
+ return rc;
|
|
559
|
+ }
|
|
560
|
+ if ( ( rc = copy_dhcp_packet_options ( dhcppkt, options ) ) != 0 ) {
|
|
561
|
+ DBG ( " failed to copy options" );
|
|
562
|
+ return rc;
|
|
563
|
+ }
|
|
564
|
+
|
|
565
|
+ return 0;
|
|
566
|
+}
|
|
567
|
+
|
476
|
568
|
/****************************************************************************
|
477
|
569
|
*
|
478
|
570
|
* DHCP to UDP interface
|
|
@@ -556,8 +648,8 @@ static int dhcp_send_request ( struct dhcp_session *dhcp ) {
|
556
|
648
|
struct xfer_metadata meta = {
|
557
|
649
|
.netdev = dhcp->netdev,
|
558
|
650
|
};
|
559
|
|
- struct dhcp_packet dhcppkt;
|
560
|
651
|
struct io_buffer *iobuf;
|
|
652
|
+ struct dhcp_packet dhcppkt;
|
561
|
653
|
int rc;
|
562
|
654
|
|
563
|
655
|
DBGC ( dhcp, "DHCP %p transmitting %s\n",
|
|
@@ -577,40 +669,15 @@ static int dhcp_send_request ( struct dhcp_session *dhcp ) {
|
577
|
669
|
return -ENOMEM;
|
578
|
670
|
|
579
|
671
|
/* Create DHCP packet in temporary buffer */
|
580
|
|
- if ( ( rc = create_dhcp_packet ( dhcp->netdev, dhcp->state,
|
581
|
|
- iobuf->data, iob_tailroom ( iobuf ),
|
582
|
|
- &dhcppkt ) ) != 0 ) {
|
583
|
|
- DBGC ( dhcp, "DHCP %p could not create DHCP packet: %s\n",
|
584
|
|
- dhcp, strerror ( rc ) );
|
585
|
|
- goto done;
|
586
|
|
- }
|
587
|
|
-
|
588
|
|
- /* Copy in options common to all requests */
|
589
|
|
- if ( ( rc = copy_dhcp_packet_options ( &dhcppkt,
|
590
|
|
- &dhcp_request_options ) ) != 0){
|
591
|
|
- DBGC ( dhcp, "DHCP %p could not set common DHCP options: %s\n",
|
|
672
|
+ if ( ( rc = create_dhcp_request ( dhcp->netdev, dhcp->state,
|
|
673
|
+ dhcp->options, iobuf->data,
|
|
674
|
+ iob_tailroom ( iobuf ),
|
|
675
|
+ &dhcppkt ) ) != 0 ) {
|
|
676
|
+ DBGC ( dhcp, "DHCP %p could not construct DHCP request: %s\n",
|
592
|
677
|
dhcp, strerror ( rc ) );
|
593
|
678
|
goto done;
|
594
|
679
|
}
|
595
|
680
|
|
596
|
|
- /* Copy any required options from previous server repsonse */
|
597
|
|
- if ( dhcp->options ) {
|
598
|
|
- if ( ( rc = copy_dhcp_packet_option ( &dhcppkt, dhcp->options,
|
599
|
|
- DHCP_SERVER_IDENTIFIER,
|
600
|
|
- DHCP_SERVER_IDENTIFIER ) ) != 0 ) {
|
601
|
|
- DBGC ( dhcp, "DHCP %p could not set server identifier "
|
602
|
|
- "option: %s\n", dhcp, strerror ( rc ) );
|
603
|
|
- goto done;
|
604
|
|
- }
|
605
|
|
- if ( ( rc = copy_dhcp_packet_option ( &dhcppkt, dhcp->options,
|
606
|
|
- DHCP_EB_YIADDR,
|
607
|
|
- DHCP_REQUESTED_ADDRESS ) ) != 0 ) {
|
608
|
|
- DBGC ( dhcp, "DHCP %p could not set requested address "
|
609
|
|
- "option: %s\n", dhcp, strerror ( rc ) );
|
610
|
|
- goto done;
|
611
|
|
- }
|
612
|
|
- }
|
613
|
|
-
|
614
|
681
|
/* Transmit the packet */
|
615
|
682
|
iob_put ( iobuf, dhcppkt.len );
|
616
|
683
|
rc = xfer_deliver_iob_meta ( &dhcp->xfer, iobuf, &meta );
|