This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Net - Improve DHCP reply handling


Index: net/common/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos-opt/net/net/common/current/ChangeLog,v
retrieving revision 1.4
diff -u -5 -p -r1.4 ChangeLog
--- net/common/current/ChangeLog	31 May 2002 01:05:55 -0000	1.4
+++ net/common/current/ChangeLog	5 Jun 2002 13:14:46 -0000
@@ -1,5 +1,17 @@
+2002-06-05  Gary Thomas  <gary@chez-thomas.org>
+
+	* src/dhcp_prot.c (_dhcp_copy): New function used to better handle
+	replies that can be variable length.
+
+2002-05-30  Gary Thomas  <gthomas@redhat.com>
+
+	* tests/tcp_echo.c: Build with either stack (no libkern.h).
+
+	* tests/bridge.c: Don't do anything (should not even be built,
+	but that's a CDL complication) if no BRIDGE support in system.
+
 2002-05-30  Jesper Skov  <jskov@redhat.com>
 
 	* tests/flood.c (floodsend): Fixed warning.
 
 2002-05-28  Jonathan Larmour  <jlarmour@redhat.com>
Index: net/common/current/src/dhcp_prot.c
===================================================================
RCS file: /cvs/ecos/ecos-opt/net/net/common/current/src/dhcp_prot.c,v
retrieving revision 1.2
diff -u -5 -p -r1.2 dhcp_prot.c
--- net/common/current/src/dhcp_prot.c	29 May 2002 18:28:29 -0000	1.2
+++ net/common/current/src/dhcp_prot.c	5 Jun 2002 13:14:46 -0000
@@ -510,10 +510,30 @@ static void set_default_dhcp_tags( struc
 
     // Explicitly specify our max message size.
     set_fixed_tag( xmit, TAG_DHCP_MAX_MSGSZ, BP_MINPKTSZ, 2 );
 }
 
+//
+// Make a copy of a BOOTP/DHCP record.  Note that this can
+// be [somewhat] arbitrarily long, thus it needs to be allocated
+// dynamically.  Reset certain fields within the record that are
+// supposed to only be returned by the server.
+//
+static struct bootp *
+_dhcp_copy(struct bootp *xmit, int xlen)
+{
+    struct bootp *xmit2;
+    xmit2 = (struct bootp *)cyg_net_malloc(xlen, 0, 0);
+    if (xmit2) {
+        bcopy(xmit, xmit2, xlen);
+        xmit2->bp_yiaddr.s_addr = 0;
+        xmit2->bp_siaddr.s_addr = 0;
+        xmit2->bp_hops = 0;
+    }
+    return xmit2;
+}
+
 // ------------------------------------------------------------------------
 // the DHCP state machine - this does all the work
 
 int
 do_dhcp(const char *intf, struct bootp *res,
@@ -544,11 +564,12 @@ do_dhcp(const char *intf, struct bootp *
     // when we are happy with them.  So we always transmit from the
     // existing state.
     struct bootp rx_local;
     struct bootp *received = &rx_local;
     struct bootp *xmit = res;
-    struct bootp xmit2;
+    struct bootp *xmit2 = (struct bootp *)NULL;
+    int xlen;
 
     // First, get a socket on the interface in question.  But Zeroth, if
     // needs be, bring it to the half-up broadcast only state if needs be.
     
     if ( DHCPSTATE_INIT      == oldstate
@@ -784,15 +805,17 @@ do_dhcp(const char *intf, struct bootp *
             diag_printf( "---------DHCPSTATE_REQUESTING sending:\n" );
             show_bootp( intf, xmit );
 #endif            
             // Send back a [modified] copy.  Note that some fields are explicitly
             // cleared, as per the RFC.  We need the copy because these fields are
-            // still useful to us (and currently stored in the 'result' structure)
-            bcopy(xmit, &xmit2, dhcp_size_for_send(xmit));
-            xmit2.bp_yiaddr.s_addr = 0;
-            xmit2.bp_siaddr.s_addr = 0;
-            if(sendto(s, &xmit2, dhcp_size_for_send(xmit), 0, 
+            // still useful to us (and currently stored in the 'result' structure)            
+            xlen = dhcp_size_for_send(xmit);
+            if ((xmit2 = _dhcp_copy(xmit, xlen)) == (struct bootp *)NULL) {
+                *pstate = DHCPSTATE_FAILED;
+                break;
+            }
+            if(sendto(s, xmit2, xlen, 0, 
                       (struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr)) < 0) {
                 *pstate = DHCPSTATE_FAILED;
                 break;
             }
 
@@ -921,14 +944,16 @@ do_dhcp(const char *intf, struct bootp *
 #endif            
             
             // Send back a [modified] copy.  Note that some fields are explicitly
             // cleared, as per the RFC.  We need the copy because these fields are
             // still useful to us (and currently stored in the 'result' structure)
-            bcopy(xmit, &xmit2, dhcp_size_for_send(xmit));
-            xmit2.bp_yiaddr.s_addr = 0;
-            xmit2.bp_siaddr.s_addr = 0;
-            if(sendto(s, &xmit2, dhcp_size_for_send(xmit), 0, 
+            xlen = dhcp_size_for_send(xmit);
+            if ((xmit2 = _dhcp_copy(xmit, xlen)) == (struct bootp *)NULL) {
+                *pstate = DHCPSTATE_FAILED;
+                break;
+            }
+            if(sendto(s, xmit2, xlen, 0, 
                        // UNICAST address of the server:
                       (struct sockaddr *)&server_addr,
                       sizeof(server_addr)) < 0) {
                 *pstate = DHCPSTATE_FAILED;
                 break;
@@ -1025,14 +1050,16 @@ do_dhcp(const char *intf, struct bootp *
             show_bootp( intf, xmit );
 #endif            
             // Send back a [modified] copy.  Note that some fields are explicitly
             // cleared, as per the RFC.  We need the copy because these fields are
             // still useful to us (and currently stored in the 'result' structure)
-            bcopy(xmit, &xmit2, dhcp_size_for_send(xmit));
-            xmit2.bp_yiaddr.s_addr = 0;
-            xmit2.bp_siaddr.s_addr = 0;
-            if(sendto(s, &xmit2, dhcp_size_for_send(xmit), 0, 
+            xlen = dhcp_size_for_send(xmit);
+            if ((xmit2 = _dhcp_copy(xmit, xlen)) == (struct bootp *)NULL) {
+                *pstate = DHCPSTATE_FAILED;
+                break;
+            }
+            if(sendto(s, xmit2, xlen, 0, 
                       (struct sockaddr *)&broadcast_addr, sizeof(broadcast_addr)) < 0) {
                 *pstate = DHCPSTATE_FAILED;
                 break;
             }
 
@@ -1172,14 +1199,16 @@ do_dhcp(const char *intf, struct bootp *
             show_bootp( intf, xmit );
 #endif            
             // Send back a [modified] copy.  Note that some fields are explicitly
             // cleared, as per the RFC.  We need the copy because these fields are
             // still useful to us (and currently stored in the 'result' structure)
-            bcopy(xmit, &xmit2, dhcp_size_for_send(xmit));
-            xmit2.bp_yiaddr.s_addr = 0;
-            xmit2.bp_siaddr.s_addr = 0;
-            if(sendto(s, &xmit2, dhcp_size_for_send(xmit), 0, 
+            xlen = dhcp_size_for_send(xmit);
+            if ((xmit2 = _dhcp_copy(xmit, xlen)) == (struct bootp *)NULL) {
+                *pstate = DHCPSTATE_FAILED;
+                break;
+            }
+            if(sendto(s, xmit2, xlen, 0, 
                        // UNICAST address of the server:
                       (struct sockaddr *)&server_addr,
                       sizeof(server_addr)) < 0) {
                 *pstate = DHCPSTATE_FAILED;
                 break;
@@ -1190,10 +1219,15 @@ do_dhcp(const char *intf, struct bootp *
 
         default:
             no_lease( lease );
             close(s);
             return false;
+        }
+        // Clean up temporary buffer(s)
+        if (xmit2) {
+            cyg_net_free(xmit2, 0);
+            xmit2 = (struct bootp *)NULL;
         }
     }
     /* NOTREACHED */
     return false;
 }


Attachment: signature.asc
Description: This is a digitally signed message part


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]