Пример #1
0
// read configuration either from INI file (if it exists) or from the registry
int DHCPReadConfig ( )
{
int   Ark;
char szBuf[128];

   memset (& sParamDHCP, 0, sizeof sParamDHCP);
   sParamDHCP.nLease = DHCP_DEFAULT_LEASE_TIME;

   for (Ark=0 ; Ark<SizeOfTab (tDHCPd32Entry) ; Ark++)
        ReadKey (  TFTPD32_DHCP_KEY, 
                   tDHCPd32Entry [Ark].szEntry,
                   tDHCPd32Entry [Ark].pValue,
                   tDHCPd32Entry [Ark].nBufSize,
                   tDHCPd32Entry [Ark].nType,
                   szTftpd32IniFile );
    // custom items
   for (Ark=0 ; Ark < SizeOfTab (sParamDHCP.t) ; Ark++)
   {
      wsprintf (szBuf, "%s%d", KEY_DHCP_USER_OPTION_NB, Ark+1);
      ReadKey  (TFTPD32_DHCP_KEY, szBuf, & sParamDHCP.t[Ark].nAddOption, 
                sizeof sParamDHCP.t[Ark].nAddOption, REG_DWORD, szTftpd32IniFile);

       wsprintf (szBuf, "%s%d", KEY_DHCP_USER_OPTION_VALUE, Ark+1);
       ReadKey  (TFTPD32_DHCP_KEY,  szBuf, sParamDHCP.t[Ark].szAddOption, 
                 sizeof sParamDHCP.t[Ark].szAddOption, REG_SZ, szTftpd32IniFile);
   }

   if ( sParamDHCP.nPoolSize!=0 )
   {
	  tFirstIP = malloc (sParamDHCP.nPoolSize * sizeof *tFirstIP[0]) ;
	  tMAC = malloc (sParamDHCP.nPoolSize * sizeof *tMAC[0]) ; 
	  if (tFirstIP == NULL  ||  tMAC == NULL ) 
	   {
			SVC_ERROR ("Can not allocate memory");
			return FALSE;
	   }
	   LoadLeases ();
   }

   if (sParamDHCP.nLease==0)
   {  
      sParamDHCP.nLease=DHCP_DEFAULT_LEASE_TIME;
      LOG (12, "%d, Lease time not specified, set to 2 days", GetCurrentThreadId ());
   }
   // compatability 3 -> 4
   if (sParamDHCP.szWins[0]==0  && sParamDHCP.szDns1[0]!=0)
   {
      lstrcpy (sParamDHCP.szWins, sParamDHCP.szDns1);
      LOG (0, "WINS server copied from DNS servers");
   }

return TRUE;
} // DHCPReadConfig
Пример #2
0
void ListenDhcpMessage (void *lpVoid)
{
struct dhcp_packet      sDhcpPkt;
char szHostname [128], *p;
int                     Rc, nSize;
struct S_WorkerParam   *pParam = lpVoid;
struct sockaddr_in      SockFrom;
int                     nFromLen = sizeof SockFrom;
BOOL                    bUniCast;
int True = 1;

    DHCPReadConfig ();
    Sleep (1000);
    
	 //NJW Prompt to see if we should discover via ping before we start doing DHCP
	 if(scanforleases)
// && IDYES == CMsgBox(pParam->hWnd, "Should I reset the lease file and rediscover devices?", "Discover Devices", MB_YESNO))
	 {
		struct in_addr addr;
		int count;
		SetHourglass(TRUE);
		ReadKey(TFTPD32_DHCP_KEY, KEY_DHCP_POOL, & addr.s_addr, sizeof(addr.s_addr), REG_DWORD, szTftpd32IniFile);
		ReadKey(TFTPD32_DHCP_KEY, KEY_DHCP_POOLSIZE, &count, sizeof(count), REG_DWORD, szTftpd32IniFile);
		SetNumAllocated(0);
		FreeLeases(FALSE);
		if (sSettings.bPersLeases)  LoadLeases ();
		if (sSettings.bPing)        PingRange (&addr, count);
		// DHCPSaveConfig ();
		SetHourglass(FALSE);
		SVC_WARNING ("Lease file updated.\nDiscover Devices");
	 }

   // add broadcast permission to socket
   if (setsockopt (tThreads[TH_DHCP].skt, SOL_SOCKET, SO_BROADCAST, (char *) & True, sizeof True) != 0)
   {
	   LOG (1, "can't set broadcast option.\nPlease, suppress DHCP server in the settings window");
	   LogToMonitor ("can't set broadcast option.\n");
	   tThreads[TH_DHCP].gRunning = FALSE; 
   }

   while ( tThreads[TH_DHCP].gRunning )
   {
        // send leases to GUI
        Dhcp_Send_Leases (tFirstIP, nAllocatedIP);

        memset (& sDhcpPkt, 0, sizeof sDhcpPkt);
        Rc = recvfrom ( tThreads[TH_DHCP].skt,
                        (char *) & sDhcpPkt,
                        sizeof sDhcpPkt,
                        0,
                        (struct sockaddr *) & SockFrom,
                        & nFromLen);
      // recv error
      // since Tftpd32 sends broadcasts, it receives its own message, just ignore it
        if (Rc < 0)
        {
             if (GetLastError () != WSAECONNRESET)
              {
                 LOG (1, "Recv error %d", GetLastError ());
                 Sleep (500);
              }
              continue;
        } // recv failed

        // if msg is too short
        // If all bootP fields have been read
        if (Rc < offsetof ( struct dhcp_packet, options ))
        {
           LOG (5, "Message truncated (length was %d)", Rc);
           if ( tThreads[TH_DHCP].gRunning ) Sleep (500);
           continue;
        }

        // if pool is empty and MAC address not statically assigned : ignore request
        if (    sParamDHCP.nPoolSize == 0  
            &&  DHCP_StaticAssignation (& sDhcpPkt)==INADDR_NONE )
        {
           Sleep (100);
           continue;
        }

        // handle only nul-terminated strings
        sDhcpPkt.sname[sizeof sDhcpPkt.sname - 1] = 0;
        sDhcpPkt.file [sizeof sDhcpPkt.file  - 1] = 0;

        // read host name, truncate it
        if (gethostname (szHostname , sizeof szHostname )==SOCKET_ERROR)
              lstrcpy (szHostname, "Tftpd32DchpServer");
        if ((p=strchr (szHostname, '.'))!=NULL)  *p=0;
        szHostname [sizeof sDhcpPkt.sname - 1] = 0;

        if (sDhcpPkt.sname[0]!=0  && lstrcmp (sDhcpPkt.sname, szHostname)!=0)
        {
           LOG (2, "Packet addressed to %s", sDhcpPkt.sname);
            continue;
        }

        // we have only to answer to BOOTREQUEST msg
        if (sDhcpPkt.op != BOOTREQUEST)
        {
            LOG (2, "%d Request %d not processed", GetCurrentThreadId (),sDhcpPkt.op);
            continue ;
        }

        // if request OK and answer ready
        bUniCast =  (     SockFrom.sin_addr.s_addr!=htonl (INADDR_NONE)
                      &&  SockFrom.sin_addr.s_addr!=htonl (INADDR_ANY)
                      // fix 5/02/2006 : 127.0.0.2 should be handle as a broadcast
                      &&  SockFrom.sin_addr.S_un.S_un_b.s_b1 != 127 ) ; // class A 127
        if (ProcessDHCPMessage ( & sDhcpPkt, & nSize ) )
        {struct servent *lpServEnt;
//            BinDump ((char *)&sDhcpPkt, sizeof sDhcpPkt, "DHCP");
           SockFrom.sin_family = AF_INET;
           // if no source address was specified reply with a broadcast
           if (!bUniCast)  SockFrom.sin_addr.s_addr = htonl (INADDR_NONE);

		   // Added : DHCP relay detection --> send replies to port 67 and 68
		   // Colin and others point ourt that this is wrong. I guess they are right.
		   // However it should not be an issue and i am sure that the host receive an address !
           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") ;
              SockFrom.sin_port =  (lpServEnt != NULL) ?  lpServEnt->s_port : htons (BOOTPC_PORT);
           }

           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)
                LOG (1, "sendto error %d: %s", GetLastError(), LastErrorText ());
        }  // ProcessDHCPMessage

   } // do it eternally

LogToMonitor ("DHCP thread ends here\n");
    _endthread ();
} // ListenDhcpMessage