// 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
// Save configuration either in INI file (if it exists) or in registry int DHCPSaveConfig ( const struct S_DHCP_Param *pNewParamDHCP ) { INT Ark; char szBuf[64]; // allocate new array, but keep pointers if ( sParamDHCP.nPoolSize!=pNewParamDHCP->nPoolSize ) { tFirstIP = realloc (tFirstIP, sizeof (tFirstIP[0]) * pNewParamDHCP->nPoolSize); tMAC = realloc (tMAC, sizeof (tMAC[0]) * pNewParamDHCP->nPoolSize); // do not complain if pool is empty if (pNewParamDHCP->nPoolSize!=0 && (tFirstIP==NULL || tMAC==NULL) ) { SVC_ERROR ("Can not allocate memory"); return FALSE; } } nAllocatedIP = min (nAllocatedIP, pNewParamDHCP->nPoolSize); sParamDHCP = *pNewParamDHCP; for (Ark=0 ; Ark<SizeOfTab (tDHCPd32Entry) ; Ark++) AsyncSaveKey ( 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); AsyncSaveKey (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); AsyncSaveKey (TFTPD32_DHCP_KEY, szBuf, sParamDHCP.t[Ark].szAddOption, sizeof sParamDHCP.t[Ark].szAddOption, REG_SZ, szTftpd32IniFile); } return TRUE; } // DHCPSaveConfig
// wait until GUI is connected SOCKET WaitForGuiConnection (void) { static SOCKET sListen = INVALID_SOCKET; SOCKET sDlg = INVALID_SOCKET; SOCKADDR_STORAGE saSockAddr; /* specifications pour le Accept */ int nAddrLen = sizeof saSockAddr; int Rc; do { sSettings.uConsolePort = TFTPD32_TCP_PORT; // sListen is static --> don't reopen if (sListen == INVALID_SOCKET) sListen = TcpGetListenSocket (AF_INET, "tftpd32", & sSettings.uConsolePort); #ifdef STANDALONE_EDITION // second chance (standalone edition):let the system choose its socket // pass the port nb through the sGuiSettings structure Rc = GetLastError(); if (sListen==INVALID_SOCKET && GetLastError()==WSAEADDRINUSE) { sGuiSettings.uConsolePort = 0; sListen = TcpGetListenSocket (AF_INET, NULL, & sGuiSettings.uConsolePort); } #endif if (sListen==INVALID_SOCKET) { SVC_ERROR ("can not create listening socket\nError %d", GetLastError ()); } else {HANDLE tEvents[2]; int nTriggeredEvent; // Create Socket Event to process either wake up or accept tEvents [0] = WSACreateEvent(); WSAEventSelect (sListen, tEvents[0], FD_ACCEPT); // waits either internal sollicitation or msg recpetion tEvents[1] = tThreads[TH_CONSOLE].hEv; nTriggeredEvent = WaitForMultipleObjects (2, tEvents, FALSE, INFINITE); if (nTriggeredEvent==1) { WSACloseEvent (tEvents [0]); closesocket (sListen); continue; } // an accept is ready --> Establish session sDlg = accept (sListen, (struct sockaddr *) &saSockAddr, &nAddrLen); if (sDlg == INVALID_SOCKET) { SVC_ERROR ("accept error %d", GetLastError()); } // free listening socket WSACloseEvent (tEvents [0]); // sListen socket no more necessary closesocket (sListen); sListen = INVALID_SOCKET; } // sListen OK if (sDlg==INVALID_SOCKET && tThreads[TH_CONSOLE].gRunning) Sleep (1000); } while (sDlg==INVALID_SOCKET && tThreads[TH_CONSOLE].gRunning); // detect if the client hangs and does not quit properly if (sDlg != INVALID_SOCKET) {int True=TRUE; Rc = setsockopt (sDlg, SOL_SOCKET, SO_KEEPALIVE, (char *) & True, sizeof True); if (Rc) LogToMonitor ("Error %d during setsockopt\n", GetLastError ()); } // sDlg OK return sDlg; } // WaitForGuiConnection
// bind the thread socket static SOCKET BindServiceSocket (const char *name, int type, const char *service, int def_port, int rfc_port, const char *sz_if) { struct sockaddr_in SockAddr; SOCKET sListenSocket = INVALID_SOCKET; int Rc; struct servent *lpServEnt; sListenSocket = socket (AF_INET, type, 0); if (sListenSocket == INVALID_SOCKET) { SVC_ERROR ("Error : Can't create socket\nError %d (%s)", GetLastError(), LastErrorText() ); return sListenSocket; } // REUSEADDR option in order to allow thread to open 69 port if (sSettings.bPortOption && lstrcmp (service, "tftp")==0) {int True=1; Rc = setsockopt (sListenSocket, SOL_SOCKET, SO_REUSEADDR, (char *) & True, sizeof True); LogToMonitor (Rc==0 ? "Port %d may be reused" : "setsockopt error", sSettings.Port); } memset (& SockAddr, 0, sizeof SockAddr); SockAddr.sin_family = AF_INET; // get the port number: read it from conf or from /etc/services files else take default port if (def_port != rfc_port) // config has modified port SockAddr.sin_port = htons ( (short) def_port ); else { // use /etc/services lpServEnt = getservbyname (service, type==SOCK_DGRAM ? "udp" : "tcp") ; SockAddr.sin_port = (lpServEnt != NULL) ? lpServEnt->s_port : htons ((short) rfc_port); } // bind the socket to the active interface // if no interface has been specified szLocalIP is empty // all interfaces are activated. SockAddr.sin_addr.s_addr = (sz_if==NULL || sz_if[0]==0) ? INADDR_ANY : inet_addr (sz_if); Rc = bind (sListenSocket, (struct sockaddr *) & SockAddr, sizeof SockAddr); if (Rc == INVALID_SOCKET) { // 3 causes : access violation, socket already bound, bind on an adress switch (GetLastError ()) { case WSAEADDRNOTAVAIL : // 10049 SVC_ERROR ("Error %d\n%s\n\n" "Tftpd32 tried to bind the %s port\n" "to the interface %s\nwhich is not available for this host\n" "Either remove the %s service or suppress %s interface assignation", GetLastError (), LastErrorText (), name, sz_if, name, sz_if); break; case WSAEINVAL : case WSAEADDRINUSE : SVC_ERROR ("Error %d\n%s\n\n" "Tftpd32 can not bind the %s port\n" "an application is already listening on this port", GetLastError (), LastErrorText (), name ); break; default : SVC_ERROR ("Bind error %d\n%s", GetLastError (), LastErrorText () ); break; } // switch error type closesocket (sListenSocket); LogToMonitor ("bind port to %s port %d failed\n", inet_ntoa (SockAddr.sin_addr), htons (SockAddr.sin_port) ); return INVALID_SOCKET; } return sListenSocket; } // BindServiceSocket