[rtems commit] network: Fix DHCP client protocol

Sebastian Huber sebh at rtems.org
Thu Jun 8 08:07:10 UTC 2017


Module:    rtems
Branch:    master
Commit:    258534718910c903451f1fe2e8fe1197c224c8e7
Changeset: http://git.rtems.org/rtems/commit/?id=258534718910c903451f1fe2e8fe1197c224c8e7

Author:    Stavros Passas <stavros.passas at movidius.com>
Date:      Fri Jan 20 09:22:46 2017 +0000

network: Fix DHCP client protocol

Close #2877.

---

 cpukit/libnetworking/nfs/bootp_subr.c   |  9 +++++++--
 cpukit/libnetworking/rtems/bootp.h      |  5 ++++-
 cpukit/libnetworking/rtems/rtems_dhcp.c | 28 +++++++++++++++++++++++++---
 3 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/cpukit/libnetworking/nfs/bootp_subr.c b/cpukit/libnetworking/nfs/bootp_subr.c
index 3e71e95..b24ba94 100644
--- a/cpukit/libnetworking/nfs/bootp_subr.c
+++ b/cpukit/libnetworking/nfs/bootp_subr.c
@@ -284,7 +284,9 @@ int
 bootpc_call(
      struct bootp_packet *call,
      struct bootp_packet *reply,	/* output */
-     struct proc *procp)
+     struct proc *procp,
+     const void *exp_vend,
+     size_t exp_vend_len)
 {
 	struct socket *so;
 	struct sockaddr_in *sin;
@@ -450,6 +452,9 @@ bootpc_call(
 			if (bcmp(reply->chaddr,call->chaddr,call->hlen))
 			  continue;
 
+			if (exp_vend_len > 0 && bcmp(exp_vend, reply->vend, exp_vend_len))
+			  continue;
+
 			goto gotreply;	/* break two levels */
 
 		} /* while secs */
@@ -1051,7 +1056,7 @@ bootpc_init(bool update_files, bool forever)
     call.secs = 0;
     call.flags = htons(0x8000); /* We need an broadcast answer */
   
-    error = bootpc_call(&call,&reply,procp);
+    error = bootpc_call(&call,&reply,procp, NULL, 0);
   
     if (!error)
       break;
diff --git a/cpukit/libnetworking/rtems/bootp.h b/cpukit/libnetworking/rtems/bootp.h
index d8eeb76..4891430 100644
--- a/cpukit/libnetworking/rtems/bootp.h
+++ b/cpukit/libnetworking/rtems/bootp.h
@@ -3,6 +3,7 @@
 #if !defined (__RTEMS_BOOTP_H__)
 #define __RTEMS_BOOTP_H__
 
+#include <stddef.h>
 #include <stdbool.h>
 
 #if __cplusplus
@@ -21,7 +22,9 @@ bool bootpc_init(bool, bool);
 int bootpc_call(
      struct bootp_packet *call,
      struct bootp_packet *reply,
-     struct proc *procp);
+     struct proc *procp,
+     const void *exp_vend,
+     size_t exp_vend_len);
 int bootpc_fakeup_interface(struct ifreq *ireq,
                                     struct socket *so,
                                     struct proc *procp);
diff --git a/cpukit/libnetworking/rtems/rtems_dhcp.c b/cpukit/libnetworking/rtems/rtems_dhcp.c
index fa75890..13c06bc 100644
--- a/cpukit/libnetworking/rtems/rtems_dhcp.c
+++ b/cpukit/libnetworking/rtems/rtems_dhcp.c
@@ -760,7 +760,8 @@ dhcp_task (rtems_task_argument _sdl)
       /*
        * Send the Request.
        */
-      error = bootpc_call ((struct bootp_packet *)&call, (struct bootp_packet *)&dhcp_req, procp);
+      error = bootpc_call ((struct bootp_packet *)&call,
+                           (struct bootp_packet *)&dhcp_req, procp, NULL, 0);
       if (error) {
         rtems_bsdnet_semaphore_release ();
         printf ("DHCP call failed -- error %d", error);
@@ -901,6 +902,7 @@ dhcp_init (int update_files)
   struct ifaddr        *ifa;
   struct sockaddr_dl   *sdl = NULL;
   struct proc          *procp = NULL;
+  char expected_dhcp_payload[7];
 
   clean_dns_entries();
 
@@ -957,15 +959,26 @@ dhcp_init (int update_files)
     return -1;
   }
 
+
   /*
    * Build the DHCP Discover
    */
   dhcp_discover_req (&call, sdl, &xid);
 
   /*
+   * Expect a DHCP offer as response to DHCP discover
+   */
+  memcpy(expected_dhcp_payload, dhcp_magic_cookie, sizeof(dhcp_magic_cookie));
+  expected_dhcp_payload[sizeof(dhcp_magic_cookie)  ]=0x35; /* DHCP */
+  expected_dhcp_payload[sizeof(dhcp_magic_cookie)+1]=0x01; /* Length : 1 */
+  expected_dhcp_payload[sizeof(dhcp_magic_cookie)+2]=0x02; /* DHCP_OFFER */
+
+  /*
    * Send the Discover.
    */
-  error = bootpc_call ((struct bootp_packet *)&call, (struct bootp_packet *)&reply, procp);
+  error = bootpc_call ((struct bootp_packet *)&call,
+                       (struct bootp_packet *)&reply, procp,
+                       expected_dhcp_payload, sizeof(expected_dhcp_payload));
   if (error) {
     printf ("BOOTP call failed -- %s\n", strerror(error));
     soclose (so);
@@ -990,11 +1003,20 @@ dhcp_init (int update_files)
   }
 
   /*
+   * Expect a DHCP_ACK as response to the DHCP REQUEST
+   * No need to reinitialize the whole expected_dhcp_payload variable,
+   * header and first two bytes of the payload are filled from DHCP offer
+   */
+  expected_dhcp_payload[sizeof(dhcp_magic_cookie)+2]=0x05; /* DHCP_ACK */
+
+  /*
    * Send a DHCP REQUEST
    */
   dhcp_request_req (&call, &reply, sdl, true);
 
-  error = bootpc_call ((struct bootp_packet *)&call, (struct bootp_packet *)&reply, procp);
+  error = bootpc_call ((struct bootp_packet *)&call,
+                       (struct bootp_packet *)&reply, procp,
+                       expected_dhcp_payload, sizeof(expected_dhcp_payload));
   if (error) {
     printf ("BOOTP call failed -- %s\n", strerror(error));
     soclose (so);



More information about the vc mailing list