[ECOS] DHCP xid

Hugo Tyson hmt@redhat.com
Thu Jan 31 11:03:00 GMT 2002


Hugo Tyson <hmt@redhat.com> writes:
> Robin Farine <acnrf@dial.eunet.ch> writes:
> > Ahem, forget this if it's already donethe case but, as Martin Buck
> > emphasized in his e-mail, when the DHCP client receives a reply, it
> > should first make sure that the fields 'htype', 'hlen' and 'chaddr'
> > match its own ESA before accepting the reply since the XID doesn't
> > suffice to exclude e.g. broadcasted replies destined to other clients.
> 
> Oh OK, I wasn't sure if you-all were sure you wanted that.
> 
> I'll see if I can slip something in.

Ici...

	- Huge

Index: net/tcpip/current/ChangeLog
===================================================================
RCS file: /home/cvs/ecc/ecc/net/tcpip/current/ChangeLog,v
retrieving revision 1.3
diff -u -5 -p -r1.3 ChangeLog
--- net/tcpip/current/ChangeLog	2002/01/31 16:51:56	1.3
+++ net/tcpip/current/ChangeLog	2002/01/31 18:27:53
@@ -1,7 +1,12 @@
 2002-01-31  Hugo Tyson  <hmt@redhat.com>
 
+	* src/dhcp_prot.c (do_dhcp): Also check the ESA in any received
+	answer matches, in case of an XID clash anyway.
+
+2002-01-31  Hugo Tyson  <hmt@redhat.com>
+
 	* src/dhcp_prot.c (do_dhcp): Generate a new XID (transaction ID)
 	every time this routine is entered.  Use the ESA and a random
 	source to avoid clashes with other net presences.  (The ESA was
 	used uninitialized before this change.)  Also use new macro
 	NEW_XID to increment the XID when we move to a new phase of the
Index: net/tcpip/current/src/lib/dhcp_prot.c
===================================================================
RCS file: /home/cvs/ecc/ecc/net/tcpip/current/src/lib/dhcp_prot.c,v
retrieving revision 1.2
diff -u -5 -p -r1.2 dhcp_prot.c
--- net/tcpip/current/src/lib/dhcp_prot.c	2002/01/31 15:28:54	1.2
+++ net/tcpip/current/src/lib/dhcp_prot.c	2002/01/31 18:27:53
@@ -511,10 +511,17 @@ do_dhcp(const char *intf, struct bootp *
     cyg_uint8 msgtype = 0, seen_bootp_reply = 0;
     unsigned int length;
     
     cyg_uint32 xid;
 
+#define CHECK_XID() (  /* and other details */                                  \
+    received->bp_xid   != xid            || /* not the same transaction */      \
+    received->bp_htype != xmit->bp_htype || /* not the same ESA type    */      \
+    received->bp_hlen  != xmit->bp_hlen  || /* not the same length      */      \
+    bcmp( &received->bp_chaddr, &xmit->bp_chaddr, xmit->bp_hlen )               \
+    )
+
     // IMPORTANT: xmit is the same as res throughout this; *received is a
     // scratch buffer for reception; its contents are always copied to res
     // when we are happy with them.  So we always transmit from the
     // existing state.
     struct bootp rx_local;
@@ -699,11 +706,11 @@ do_dhcp(const char *intf, struct bootp *
                          rx_addr.sin_family,
                          rx_addr.sin_addr.s_addr,
                          rx_addr.sin_port );
             show_bootp( intf, received );
 #endif            
-            if ( received->bp_xid != xid )   // not the same transaction;
+            if ( CHECK_XID() )          // XID and ESA matches?
                 break;                  // listen again...
 
             if ( 0 == received->bp_siaddr.s_addr ) {
                 // then fill in from the options...
                 length = sizeof(received->bp_siaddr.s_addr);
@@ -788,11 +795,11 @@ do_dhcp(const char *intf, struct bootp *
                          rx_addr.sin_family,
                          rx_addr.sin_addr.s_addr,
                          rx_addr.sin_port );
             show_bootp( intf, received );
 #endif            
-            if ( received->bp_xid != xid )   // not the same transaction;
+            if ( CHECK_XID() )          // not the same transaction;
                 break;                  // listen again...
 
             if ( 0 == received->bp_siaddr.s_addr ) {
                 // then fill in from the options...
                 length = sizeof(received->bp_siaddr.s_addr );
@@ -926,11 +933,11 @@ do_dhcp(const char *intf, struct bootp *
                          rx_addr.sin_family,
                          rx_addr.sin_addr.s_addr,
                          rx_addr.sin_port );
             show_bootp( intf, received );
 #endif            
-            if ( received->bp_xid != xid )   // not the same transaction;
+            if ( CHECK_XID() )          // not the same transaction;
                 break;                  // listen again...
 
             if ( 0 == received->bp_siaddr.s_addr ) {
                 // then fill in from the options...
                 length = sizeof(received->bp_siaddr.s_addr);
@@ -1023,11 +1030,11 @@ do_dhcp(const char *intf, struct bootp *
                          rx_addr.sin_family,
                          rx_addr.sin_addr.s_addr,
                          rx_addr.sin_port );
             show_bootp( intf, received );
 #endif            
-            if ( received->bp_xid != xid )   // not the same transaction;
+            if ( CHECK_XID() )          // not the same transaction;
                 break;                  // listen again...
 
             if ( 0 == received->bp_siaddr.s_addr ) {
                 // then fill in from the options...
                 int length = sizeof(received->bp_siaddr.s_addr );



More information about the Ecos-discuss mailing list