Jump to content











Photo
- - - - -

tftpd32 v3.35 DHCP relay detect with coding mistake


  • Please log in to reply
1 reply to this topic

#1 Colin

Colin

    Newbie

  • Members
  • 10 posts
  •  
    China

Posted 08 May 2010 - 02:51 AM

tftpd32 v3.35 send dhcp response to both 67/udp and 68/udp, it may be wrong.
According to my understanding of RFC951 section 7.3, response should send to only one destination.

I fould it maybe coding mistake in DHCP relay detect.
The strange coding may be a workaround for certain ill-design dhcp relay or dhcp client, which I have no idea about them.

If it is only a pure bug, I figure out the patch here:
[codebox]// bootpd.c, function ListenDhclMessage if (!bUniCast) SockFrom.sin_addr.s_addr = htonl (INADDR_NONE); ++ LOG (15, "Thread 0x%X: send %d bytes", GetCurrentThreadId(), nSize ); // Added : DHCP relay detection --> send replies to port 67 and 68 -- if (sDhcpPkt.giaddr.s_addr!=htonl(INADDR_ANY) || sDhcpPkt.giaddr.s_addr!=htonl(INADDR_NONE)) ++ if (sDhcpPkt.giaddr.s_addr!=htonl(INADDR_ANY) && sDhcpPkt.giaddr.s_addr!=htonl(INADDR_NONE)) { // sends to port 67 lpServEnt = getservbyname ("bootps", "udp") ; SockFrom.sin_port = (lpServEnt != NULL) ? lpServEnt->s_port : htons (BOOTPS_PORT); Rc = sendto (tThreads[TH_DHCP].skt, (char *) & sDhcpPkt, nSize, 0, (struct sockaddr *) & SockFrom, sizeof SockFrom); // and prepare for port 68 -- lpServEnt = getservbyname ("bootpc", "udp") ; ++ //lpServEnt = getservbyname ("bootpc", "udp") ; -- SockFrom.sin_port = (lpServEnt != NULL) ? lpServEnt->s_port : htons (BOOTPC_PORT); ++ //SockFrom.sin_port = (lpServEnt != NULL) ? lpServEnt->s_port : htons (BOOTPC_PORT); -- } ++ }else{ -- LOG (15, "Thread 0x%X: send %d bytes", GetCurrentThreadId(), nSize );
Rc = sendto (tThreads[TH_DHCP].skt,
(char *) & sDhcpPkt,
nSize,
0,
(struct sockaddr *) & SockFrom,
sizeof SockFrom);
++ }
if (Rc<nSize)[/codebox]

I tried to mail this to email address in homepage, but received no response.

#2 patpat

patpat

    Member

  • Banned
  • 48 posts
  •  
    United States

Posted 10 June 2010 - 08:00 AM

According to RFC1542 there's a situation where the answer should go on port 67
"This action will deliver the BOOTREPLY message directly to the BOOTP relay agent closest to the client; the relay agent will then perform the final delivery to the client."


BOOTREQUEST fields	 BOOTREPLY values for UDP, IP, link-layer

   +-----------------------+-----------------------------------------+

   | &#39;ciaddr&#39;  &#39;giaddr&#39;  B | UDP dest	 IP destination   link dest |

   +-----------------------+-----------------------------------------+

   | non-zero	 X	  X | BOOTPC &#40;68&#41;  &#39;ciaddr&#39;		 normal	|

   | 0.0.0.0   non-zero  X | BOOTPS &#40;67&#41;  &#39;giaddr&#39;		 normal	| <-

   | 0.0.0.0   0.0.0.0   0 | BOOTPC &#40;68&#41;  &#39;yiaddr&#39;		 &#39;chaddr&#39;  |

   | 0.0.0.0   0.0.0.0   1 | BOOTPC &#40;68&#41;  255.255.255.255  broadcast |

   +-----------------------+-----------------------------------------+



		B = BROADCAST flag



		X = Don&#39;t care



   normal = determine from the given IP destination using normal

			IP routing mechanisms and/or ARP as for any other

			normal datagram
What tftpd32 does here it is not RFC1542 compliant.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users