"Fossies" - the Fresh Open Source Software Archive

Member "opendhcp/opendhcpd.cpp" (14 Sep 2021, 140209 Bytes) of package /linux/misc/opendhcpV1.80.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "opendhcpd.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: V1.75_vs_V1.80.

A hint: This file contains one or more very long lines, so maybe it is better readable using the pure text view mode that shows the contents as wrapped lines within the browser window.


    1 /**************************************************************************
    2 *   Copyright (C) 2005 by Achal Dhir                                      *
    3 *   achaldhir@gmail.com                                                   *
    4 *                                                                         *
    5 *   This program is free software; you can redistribute it and/or modify  *
    6 *   it under the terms of the GNU General Public License as published by  *
    7 *   the Free Software Foundation; either version 2 of the License, or     *
    8 *   (at your option) any later version.                                   *
    9 *                                                                         *
   10 *   This program is distributed in the hope that it will be useful,       *
   11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
   12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
   13 *   GNU General Public License for more details.                          *
   14 *                                                                         *
   15 *   You should have received a copy of the GNU General Public License     *
   16 *   along with this program; if not, write to the                         *
   17 *   Free Software Foundation, Inc.,                                       *
   18 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
   19 ***************************************************************************/
   20 // opendhcpd.cpp //
   21 #include <string>
   22 #include <math.h>
   23 #include <map>
   24 using namespace std;
   25 #include <sys/types.h>
   26 #include <sys/ioctl.h>
   27 #include <limits.h>
   28 #include <sys/socket.h>
   29 #include <netinet/in.h>
   30 #include <net/if.h>
   31 #include <arpa/inet.h>
   32 #include <netdb.h>
   33 #include <unistd.h>
   34 #include <signal.h>
   35 #include <stdio.h>
   36 #include <fcntl.h>
   37 #include <errno.h>
   38 #include <memory.h>
   39 #include <sys/stat.h>
   40 #include <stdlib.h>
   41 #include <syslog.h>
   42 #include "opendhcpd.h"
   43 
   44 //Global Variables
   45 timeval tv;
   46 fd_set readfds;
   47 fd_set writefds;
   48 data9 dhcpr;
   49 data9 token;
   50 data1 network;
   51 data1 newNetwork;
   52 data2 cfig;
   53 data71 lump;
   54 bool kRunning = true;
   55 dhcpMap dhcpCache;
   56 char serviceName[] = "OpenDHCPServer";
   57 //char tempbuff[512] = "";
   58 //char logBuff[256];
   59 //char extbuff[256] = "";
   60 bool verbatim = false;
   61 char iniFile[256] = "";
   62 char leaFile[256] = "";
   63 char logFile[256] = "";
   64 char filePATH[256] = "";
   65 char htmlTitle[256] = "";
   66 char arpa[] = ".in-addr.arpa";
   67 time_t t = time(NULL);
   68 pthread_mutex_t mutStateFile = PTHREAD_MUTEX_INITIALIZER;
   69 pthread_mutex_t mutLogFile = PTHREAD_MUTEX_INITIALIZER;
   70 struct ifconf Ifc;
   71 struct ifreq IfcBuf[MAX_SERVERS];
   72 
   73 //constants
   74 const char NBSP = 32;
   75 const char RANGESET[] = "RANGE_SET";
   76 const char GLOBALOPTIONS[] = "GLOBAL_OPTIONS";
   77 const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
   78 //const char send200[] = "HTTP/1.1 200 OK\r\nDate: %s\r\nLast-Modified: %s\r\nContent-Type: text/html\r\nConnection: Close\r\nTransfer-Encoding: chunked\r\n";
   79 //const char send200[] = "HTTP/1.1 200 OK\r\nDate: %s\r\nLast-Modified: %s\r\nContent-Type: text/html\r\nConnection: Close\r\nContent-Length:         \r\n\r\n";
   80 //const char send200[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n";
   81 const char send403[] = "HTTP/1.1 403 Forbidden\r\n\r\n<h1>403 Forbidden</h1>";
   82 const char send404[] = "HTTP/1.1 404 Not Found\r\n\r\n<h1>404 Not Found</h1>";
   83 const char td200[] = "<td>%s</td>";
   84 const char tdnowrap200[] = "<td nowrap>%s</td>";
   85 const char sVersion[] = "Open DHCP Server Version 1.80 Linux Build 1054";
   86 const char htmlStart[] = "<html>\n<head>\n<title>%s</title><meta http-equiv=\"refresh\" content=\"60\">\n<meta http-equiv=\"cache-control\" content=\"no-cache\">\n</head>\n";
   87 const char bodyStart[] = "<body bgcolor=\"#cccccc\"><table border=\"0\"><tr><td>\n<table width=\"100%%\" border=\"0\"><tr><td nowrap colspan=\"2\" align=\"center\"><font size=\"6\"><b>%s</b></font></td></tr><tr><td align=\"left\"><b>Server:</b> %s %s</td><td align=\"right\"><a target=\"_new\" href=\"http://dhcpserver.sourceforge.net\">http://dhcpserver.sourceforge.net</td></tr></table>";
   88 //const char htmlStart[] = "<html>\n<head>\n<title>%s</title><meta http-equiv=\"refresh\" content=\"60\">\n<meta http-equiv=\"cache-control\" content=\"no-cache\">\n</head>\n";
   89 //const char bodyStart[] = "<body bgcolor=\"#cccccc\"><table width=\"800\"><tr><td align=\"center\"><font size=\"5\"><b>%s</b></font></b></b></td></tr><tr><td align=\"right\"><a target=\"_new\" href=\"http://dhcp-dns-server.sourceforge.net/\">http://dhcp-dns-server.sourceforge.net/</b></b></td></tr></table>";
   90 //const char bodyStart[] = "<body bgcolor=\"#cccccc\"><table width=640><tr><td align=\"center\"><font size=\"5\"><b>%s</b></font></td></tr><tr><td align=\"right\"><a target=\"_new\" href=\"http://dhcpserver.sourceforge.net\">http://dhcpserver.sourceforge.net</td></tr></table>";
   91 //const char bodyStart[] = "<body bgcolor=\"#cccccc\"><table width=640><tr><td align=\"center\"><font size=\"5\"><b>%s</b></font></td></tr><tr><td align=\"center\"><font size=\"5\">%s</font></td></tr></table>";
   92 const data4 opData[] =
   93     {
   94         { "SubnetMask", 1, 3 , 1},
   95         { "TimeOffset", 2, 4 , 1},
   96         { "Router", 3, 3 , 1},
   97         { "TimeServer", 4, 3 , 1},
   98         { "NameServer", 5, 3 , 1},
   99         { "DomainServer", 6, 3 , 1},
  100         { "LogServer", 7, 3 , 1},
  101         { "QuotesServer", 8, 3 , 1},
  102         { "LPRServer", 9, 3 , 1},
  103         { "ImpressServer", 10, 3 , 1},
  104         { "RLPServer", 11, 3, 1},
  105         { "Hostname", 12, 1, 1},
  106         { "BootFileSize", 13, 5 , 1},
  107         { "MeritDumpFile", 14, 1 , 1},
  108         { "DomainName", 15, 1 , 1},
  109         { "SwapServer", 16, 3 , 1},
  110         { "RootPath", 17, 1 , 1},
  111         { "ExtensionFile", 18, 1 , 1},
  112         { "ForwardOn/Off", 19, 7 , 1},
  113         { "SrcRteOn/Off", 20, 7 , 1},
  114         { "PolicyFilter", 21, 8 , 1},
  115         { "MaxDGAssembly", 22, 5 , 1},
  116         { "DefaultIPTTL", 23, 6 , 1},
  117         { "MTUTimeout", 24, 4 , 1},
  118         { "MTUPlateau", 25, 2 , 1},
  119         { "MTUInterface", 26, 5 , 1},
  120         { "MTUSubnet", 27, 7 , 1},
  121         { "BroadcastAddress", 28, 3 , 1},
  122         { "MaskDiscovery", 29, 7 , 1},
  123         { "MaskSupplier", 30, 7 , 1},
  124         { "RouterDiscovery", 31, 7 , 1},
  125         { "RouterRequest", 32, 3 , 1},
  126         { "StaticRoute", 33, 8 , 1},
  127         { "Trailers", 34, 7 , 1},
  128         { "ARPTimeout", 35, 4 , 1},
  129         { "Ethernet", 36, 7 , 1},
  130         { "DefaultTCPTTL", 37, 6 , 1},
  131         { "KeepaliveTime", 38, 4 , 1},
  132         { "KeepaliveData", 39, 7 , 1},
  133         { "NISDomain", 40, 1 , 1},
  134         { "NISServers", 41, 3 , 1},
  135         { "NTPServers", 42, 3 , 1},
  136         { "VendorSpecificInf", 43, 2 , 0},
  137         { "NETBIOSNameSrv", 44, 3 , 1},
  138         { "NETBIOSDistSrv", 45, 3 , 1},
  139         { "NETBIOSNodeType", 46, 6 , 1},
  140         { "NETBIOSScope", 47, 1 , 1},
  141         { "XWindowFont", 48, 1 , 1},
  142         { "XWindowManager", 49, 3 , 1},
  143         { "AddressRequest", 50, 3, 0},
  144         { "AddressTime", 51, 4 , 1},
  145         { "OverLoad", 52, 7, 0},
  146         { "DHCPMsgType", 53, 6, 0},
  147         { "DHCPServerId", 54, 3, 0},
  148         { "ParameterList", 55, 2 , 0},
  149         { "DHCPMessage", 56, 1, 0},
  150         { "DHCPMaxMsgSize", 57, 5, 0},
  151         { "RenewalTime", 58, 4 , 1},
  152         { "RebindingTime", 59, 4 , 1},
  153         { "ClassId", 60, 1, 0},
  154         { "ClientId", 61, 2, 0},
  155         { "NetWareIPDomain", 62, 1 , 1},
  156         { "NetWareIPOption", 63, 2 , 1},
  157         { "NISDomainName", 64, 1 , 1},
  158         { "NISServerAddr", 65, 3 , 1},
  159         { "TFTPServerName", 66, 1 , 1},
  160         { "BootFileOption", 67, 1 , 1},
  161         { "HomeAgentAddrs", 68, 3 , 1},
  162         { "SMTPServer", 69, 3 , 1},
  163         { "POP3Server", 70, 3 , 1},
  164         { "NNTPServer", 71, 3 , 1},
  165         { "WWWServer", 72, 3 , 1},
  166         { "FingerServer", 73, 3 , 1},
  167         { "IRCServer", 74, 3 , 1},
  168         { "StreetTalkServer", 75, 3 , 1},
  169         { "STDAServer", 76, 3 , 1},
  170         { "UserClass", 77, 1, 0},
  171         { "DirectoryAgent", 78, 1 , 1},
  172         { "ServiceScope", 79, 1 , 1},
  173         { "RapidCommit", 80, 2, 0},
  174         { "ClientFQDN", 81, 2, 0},
  175         { "RelayAgentInformation", 82, 2, 0},
  176         { "iSNS", 83, 1 , 1},
  177         { "NDSServers", 85, 3 , 1},
  178         { "NDSTreeName", 86, 1 , 1},
  179         { "NDSContext", 87, 1 , 1},
  180         { "LDAP", 95, 1 , 1},
  181         { "PCode", 100, 1 , 1},
  182         { "TCode", 101, 1 , 1},
  183         { "NetInfoAddress", 112, 3 , 1},
  184         { "NetInfoTag", 113, 1 , 1},
  185         { "URL", 114, 1 , 1},
  186         { "AutoConfig", 116, 7 , 1},
  187         { "NameServiceSearch", 117, 2 , 1},
  188         { "SubnetSelectionOption", 118, 3 , 1},
  189         { "DomainSearch", 119, 1 , 1},
  190         { "SIPServersDHCPOption", 120, 1 , 1},
  191 //      { "121", 121, 2 , 1},
  192         { "CCC", 122, 1 , 1},
  193         { "TFTPServerIPaddress", 128, 3 , 1},
  194         { "CallServerIPaddress", 129, 3 , 1},
  195         { "DiscriminationString", 130, 1 , 1},
  196         { "RemoteStatisticsServerIPAddress", 131, 3 , 1},
  197         { "HTTPProxyPhone", 135, 3 , 1},
  198         { "OPTION_CAPWAP_AC_V4", 138, 1 , 1},
  199         { "OPTIONIPv4_AddressMoS", 139, 1 , 1},
  200         { "OPTIONIPv4_FQDNMoS", 140, 1 , 1},
  201         { "SIPUAServiceDomains", 141, 1 , 1},
  202         { "OPTIONIPv4_AddressANDSF", 142, 1 , 1},
  203         { "IPTelephone", 176, 1 , 1},
  204         { "ConfigurationFile", 209, 1 , 1},
  205         { "PathPrefix", 210, 1 , 1},
  206         { "RebootTime", 211, 4 , 1},
  207         { "OPTION_6RD", 212, 1 , 1},
  208         { "OPTION_V4_ACCESS_DOMAIN", 213, 1 , 1},
  209         { "BootFileName", 253, 1 , 1},
  210         { "NextServer", 254, 3, 1},
  211     };
  212 
  213 int main(int argc, char **argv)
  214 {
  215     char logBuff[256]="";
  216 
  217     signal(SIGINT, catch_int);
  218     signal(SIGABRT, catch_int);
  219     signal(SIGTERM, catch_int);
  220     signal(SIGQUIT, catch_int);
  221     signal(SIGTSTP, catch_int);
  222     signal(SIGHUP, catch_int);
  223 
  224     //printf("%i\n", argc);
  225 /*
  226     logBuff[0] = 0;
  227     char *ds = strrchr(argv[0], '/');
  228 
  229     if (ds)
  230         ds++;
  231     else
  232         ds = argv[0];
  233 
  234     sprintf(tempbuff, "ps -e | grep -v grep | grep -v \"rc.%s\" | grep \"%s$\" | head -1 | awk '{ print $1 }'", ds, ds);
  235     FILE *p = popen(tempbuff,"r");
  236 
  237     if (p)
  238     {
  239         while (fgets(tempbuff, sizeof(tempbuff), p))
  240         {
  241             if (atoi(tempbuff) != getpid())
  242             {
  243                 sprintf(logBuff, "Error: %s is already running, Pid = %s", ds, tempbuff);
  244                 break;
  245             }
  246         }
  247         pclose(p);
  248     }
  249 */
  250     for (int i = 1; i < argc; i++)
  251     {
  252         if (!strcasecmp(argv[i], "-v"))
  253             verbatim = true;
  254         else if (!strcmp(argv[i], "-i") && argc > i + 1 && argv[i + 1][0] != '-' )
  255         {
  256             myTrim(iniFile, argv[i + 1]);
  257             i++;
  258         }
  259         else if (!strcmp(argv[i], "-l") && argc > i + 1 && argv[i + 1][0] != '-' )
  260         {
  261             myTrim(logFile, argv[i + 1]);
  262             i++;
  263         }
  264         else if (!strcmp(argv[i], "-s") && argc > i + 1 && argv[i + 1][0] != '-' )
  265         {
  266             myTrim(leaFile, argv[i + 1]);
  267             i++;
  268         }
  269         else if (!strncasecmp(argv[i], "-i", 2))
  270             myTrim(iniFile, argv[i] + 2);
  271         else if (!strncasecmp(argv[i], "-l", 2))
  272             myTrim(logFile, argv[i] + 2);
  273         else if (!strncasecmp(argv[i], "-s", 2))
  274             myTrim(leaFile, argv[i] + 2);
  275         else
  276             sprintf(logBuff, "Error: Invalid Argument %s", argv[i]);
  277     }
  278 
  279     if (!leaFile[0])
  280         strcpy(leaFile, "/tmp/opendhcp.state");
  281 
  282     if (!iniFile[0])
  283         strcpy(iniFile, "/etc/opendhcp.ini");
  284 
  285     strcpy(filePATH, iniFile);
  286 
  287     if (strrchr(filePATH, '/'))
  288     {
  289         char *fileExt = strrchr(filePATH, '/');
  290         fileExt++;
  291         *fileExt = 0;
  292     }
  293 
  294     if (verbatim)
  295     {
  296         if (logBuff[0])
  297         {
  298             printf("%s\n", logBuff);
  299             exit(EXIT_FAILURE);
  300         }
  301 
  302         if (getuid())
  303         {
  304             printf("Error: Only root should run this program\n");
  305             exit(EXIT_FAILURE);
  306         }
  307 
  308         //printf("%i\n",sizeof(data7));
  309         memset(&cfig, 0, sizeof(cfig));
  310         cfig.ppid = getpid();
  311         pthread_t threadId;
  312         pthread_attr_t attr;
  313         pthread_attr_init(&attr);
  314         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  315         int errcode = pthread_create(&threadId, &attr, init, NULL);
  316         pthread_attr_destroy(&attr);
  317 
  318         if(errcode)
  319         {
  320             printf("Init thread Creation Failed");
  321             exit(EXIT_FAILURE);
  322         }
  323 
  324         while (kRunning)
  325         {
  326             if (!network.dhcpConn[0].ready || !network.ready)
  327             {
  328                 sleep(1);
  329                 network.busy = false;
  330                 continue;
  331             }
  332 
  333             network.busy = true;
  334             FD_ZERO(&readfds);
  335             tv.tv_sec = 20;
  336             tv.tv_usec = 0;
  337 
  338             if (network.httpConn.ready)
  339                 FD_SET(network.httpConn.sock, &readfds);
  340 
  341             for (int i = 0; i < MAX_SERVERS && network.dhcpConn[i].ready; i++)
  342                 FD_SET(network.dhcpConn[i].sock, &readfds);
  343 
  344             FD_SET(network.dhcpListener.sock, &readfds);
  345 
  346             if (cfig.replication)
  347                 FD_SET(cfig.dhcpReplConn.sock, &readfds);
  348 
  349             //printf("%i\n",select(network.maxFD, &readfds, NULL, NULL, &tv));
  350             if (select(network.maxFD, &readfds, NULL, NULL, &tv))
  351             {
  352                 t = time(NULL);
  353                 network.busy = true;
  354 
  355                 if (network.httpConn.ready && FD_ISSET(network.httpConn.sock, &readfds))
  356                 {
  357                     data19 *req = (data19*)calloc(1, sizeof(data19));
  358 
  359                     if (req)
  360                     {
  361                         req->sockLen = sizeof(req->remote);
  362                         errno = 0;
  363                         req->sock = accept(network.httpConn.sock, (sockaddr*)&req->remote, &req->sockLen);
  364 
  365                         if (errno || req->sock == INVALID_SOCKET)
  366                         {
  367                             sprintf(logBuff, "Accept Failed, Error: %s", strerror(errno));
  368                             logDHCPMess(logBuff, 1);
  369                             free(req);
  370                         }
  371                         else
  372                             procHTTP(req);
  373                     }
  374                     else
  375                     {
  376                         sprintf(logBuff, "Memory Error");
  377                         logDHCPMess(logBuff, 0);
  378                     }
  379                 }
  380 
  381                 for (int i = 0; i < MAX_SERVERS && network.dhcpConn[i].ready; i++)
  382                 {
  383                     if (FD_ISSET(network.dhcpConn[i].sock, &readfds) && gdmess(&dhcpr, i) && sdmess(&dhcpr))
  384                         alad(&dhcpr);
  385                 }
  386 
  387                 if (FD_ISSET(network.dhcpListener.sock, &readfds) && gdmess(&dhcpr, 255) && sdmess(&dhcpr))
  388                     alad(&dhcpr);
  389 
  390                 if (cfig.dhcpReplConn.ready && FD_ISSET(cfig.dhcpReplConn.sock, &readfds))
  391                 {
  392                     errno = 0;
  393                     dhcpr.sockLen = sizeof(dhcpr.remote);
  394                     dhcpr.bytes = recvfrom(cfig.dhcpReplConn.sock,
  395                                            dhcpr.raw,
  396                                            sizeof(dhcpr.raw),
  397                                            0,
  398                                            (sockaddr*)&dhcpr.remote,
  399                                            &dhcpr.sockLen);
  400 
  401                     //errno = WSAGetLastError();
  402 
  403                     if (errno || dhcpr.bytes <= 0)
  404                         cfig.dhcpRepl = 0;
  405                 }
  406             }
  407             else
  408                 t = time(NULL);
  409         }
  410     }
  411     else
  412     {
  413         if(logBuff[0])
  414         {
  415             syslog(LOG_MAKEPRI(LOG_LOCAL1, LOG_CRIT), "%s", logBuff);
  416             exit(EXIT_FAILURE);
  417         }
  418 
  419         if(getuid())
  420         {
  421             syslog(LOG_MAKEPRI(LOG_LOCAL1, LOG_CRIT), "%s", "Only root should run this program");
  422             exit(EXIT_FAILURE);
  423         }
  424 
  425         /* Our process ID and Session ID */
  426         pid_t sid, pid;
  427 
  428         /* Fork off the parent process */
  429         pid = fork();
  430         if (pid < 0)
  431         {
  432             exit(EXIT_FAILURE);
  433         }
  434         /* If we got a good PID, then
  435         we can exit the parent process. */
  436         if (pid > 0)
  437         {
  438             exit(EXIT_SUCCESS);
  439         }
  440 
  441         /* Change the file mode mask */
  442         umask(0);
  443 
  444         /* Open any logs here */
  445 
  446         /* Create a new SID for the child process */
  447         sid = setsid();
  448         if (sid < 0)
  449         {
  450             /* Log the failure */
  451             exit(EXIT_FAILURE);
  452         }
  453 
  454         /* Change the current working directory */
  455         if ((chdir("/")) < 0)
  456         {
  457             /* Log the failure */
  458             exit(EXIT_FAILURE);
  459         }
  460 
  461         /* Close out the standard file descriptors */
  462         close(STDIN_FILENO);
  463         close(STDOUT_FILENO);
  464         close(STDERR_FILENO);
  465 
  466         /* Daemon-specific initialization goes here */
  467         memset(&cfig, 0, sizeof(cfig));
  468         cfig.ppid = getpid();
  469         data9 dhcpr;
  470         pthread_t threadId;
  471         pthread_attr_t attr;
  472         pthread_attr_init(&attr);
  473         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  474         int errcode = pthread_create(&threadId, &attr, init, NULL);
  475         pthread_attr_destroy(&attr);
  476 
  477         if(errcode)
  478         {
  479             syslog(LOG_MAKEPRI(LOG_LOCAL1, LOG_CRIT), "%s", "init thread Creation Failed");
  480             exit(EXIT_FAILURE);
  481         }
  482 
  483         /* The Big Loop */
  484         while (kRunning)
  485         {
  486             if (!network.dhcpConn[0].ready || !network.ready)
  487             {
  488                 sleep(1);
  489                 network.busy = false;
  490                 continue;
  491             }
  492 
  493             network.busy = true;
  494 
  495             FD_ZERO(&readfds);
  496             tv.tv_sec = 20;
  497             tv.tv_usec = 0;
  498 
  499             if (network.httpConn.ready)
  500                 FD_SET(network.httpConn.sock, &readfds);
  501 
  502             for (int i = 0; i < MAX_SERVERS && network.dhcpConn[i].ready; i++)
  503                 FD_SET(network.dhcpConn[i].sock, &readfds);
  504 
  505             FD_SET(network.dhcpListener.sock, &readfds);
  506 
  507             if (cfig.replication)
  508                 FD_SET(cfig.dhcpReplConn.sock, &readfds);
  509 
  510             //printf("%i\n",select(network.maxFD, &readfds, NULL, NULL, &tv));
  511             if (select(network.maxFD, &readfds, NULL, NULL, &tv))
  512             {
  513                 t = time(NULL);
  514                 network.busy = true;
  515 
  516                 if (network.httpConn.ready && FD_ISSET(network.httpConn.sock, &readfds))
  517                 {
  518                     data19 *req = (data19*)calloc(1, sizeof(data19));
  519 
  520                     if (req)
  521                     {
  522                         req->sockLen = sizeof(req->remote);
  523                         errno = 0;
  524                         req->sock = accept(network.httpConn.sock, (sockaddr*)&req->remote, &req->sockLen);
  525 
  526                         if (errno || req->sock == INVALID_SOCKET)
  527                         {
  528                             sprintf(logBuff, "Accept Failed, Error: %s", strerror(errno));
  529                             logDHCPMess(logBuff, 1);
  530                             free(req);
  531                         }
  532                         else
  533                             procHTTP(req);
  534                     }
  535                     else
  536                     {
  537                         sprintf(logBuff, "Memory Error");
  538                         logDHCPMess(logBuff, 0);
  539                     }
  540                 }
  541 
  542                 for (int i = 0; i < MAX_SERVERS && network.dhcpConn[i].ready; i++)
  543                 {
  544                     if (FD_ISSET(network.dhcpConn[i].sock, &readfds) && gdmess(&dhcpr, i) && sdmess(&dhcpr))
  545                         alad(&dhcpr);
  546                 }
  547 
  548                 if (FD_ISSET(network.dhcpListener.sock, &readfds) && gdmess(&dhcpr, 255) && sdmess(&dhcpr))
  549                     alad(&dhcpr);
  550 
  551                 if (cfig.dhcpReplConn.ready && FD_ISSET(cfig.dhcpReplConn.sock, &readfds))
  552                 {
  553                     errno = 0;
  554                     dhcpr.sockLen = sizeof(dhcpr.remote);
  555                     dhcpr.bytes = recvfrom(cfig.dhcpReplConn.sock,
  556                                            dhcpr.raw,
  557                                            sizeof(dhcpr.raw),
  558                                            0,
  559                                            (sockaddr*)&dhcpr.remote,
  560                                            &dhcpr.sockLen);
  561 
  562                     //errno = WSAGetLastError();
  563 
  564                     if (errno || dhcpr.bytes <= 0)
  565                         cfig.dhcpRepl = 0;
  566                 }
  567             }
  568             else
  569                 t = time(NULL);
  570         }
  571     }
  572 
  573     closeConn();
  574 
  575     if (cfig.dhcpReplConn.ready)
  576         close(cfig.dhcpReplConn.sock);
  577 }
  578 
  579 void closeConn()
  580 {
  581     if (network.dhcpListener.ready)
  582         close(network.dhcpListener.sock);
  583 
  584     if (network.httpConn.ready)
  585         close(network.httpConn.sock);
  586 
  587     for (int i = 0; i < MAX_SERVERS && network.dhcpConn[i].loaded; i++)
  588     {
  589         if (network.dhcpConn[i].ready)
  590             close(network.dhcpConn[i].sock);
  591     }
  592 }
  593 
  594 void catch_int(int sig_num)
  595 {
  596     char logBuff[256];
  597 
  598     //printf("%u=%u\n", cfig.ppid, getpid());
  599     if (cfig.ppid == getpid())
  600     {
  601         network.ready = false;
  602         kRunning = false;
  603         sprintf(logBuff, "Closing Network Connections...");
  604         logDHCPMess(logBuff, 1);
  605         sleep(1);
  606 
  607         closeConn();
  608 
  609         if (cfig.dhcpReplConn.ready)
  610             close(cfig.dhcpReplConn.sock);
  611 
  612         close(cfig.fixedSocket);
  613 
  614         sprintf(logBuff, "Open DHCP Server Stopped !\n");
  615         logDHCPMess(logBuff, 1);
  616         sleep(1);
  617 
  618         exit(EXIT_SUCCESS);
  619     }
  620 }
  621 
  622 MYWORD fUShort(void *raw)
  623 {
  624     return ntohs(*((MYWORD*)raw));
  625 }
  626 
  627 MYDWORD fUInt(void *raw)
  628 {
  629     return ntohl(*((MYDWORD*)raw));
  630 }
  631 
  632 MYDWORD fIP(void *raw)
  633 {
  634     return (*((MYDWORD*)raw));
  635 }
  636 
  637 MYBYTE pUShort(void *raw, MYWORD data)
  638 {
  639     *((MYWORD*)raw) = htons(data);
  640     return sizeof(MYWORD);
  641 }
  642 
  643 MYBYTE pUInt(void *raw, MYDWORD data)
  644 {
  645     *((MYDWORD*)raw) = htonl(data);
  646     return sizeof(MYDWORD);
  647 }
  648 
  649 MYBYTE pIP(void *raw, MYDWORD data)
  650 {
  651     *((MYDWORD*)raw) = data;
  652     return sizeof(MYDWORD);
  653 }
  654 
  655 void procHTTP(data19 *req)
  656 {
  657     //debug("procHTTP");
  658     char tempbuff[512];
  659     char logBuff[256];
  660 
  661     req->ling.l_onoff = 1; //0 = off (l_linger ignored), nonzero = on
  662     req->ling.l_linger = 30; //0 = discard data, nonzero = wait for data sent
  663     setsockopt(req->sock, SOL_SOCKET, SO_LINGER, (const char*)&req->ling, sizeof(req->ling));
  664 
  665     timeval tv1;
  666     fd_set readfds1;
  667     FD_ZERO(&readfds1);
  668     tv1.tv_sec = 1;
  669     tv1.tv_usec = 0;
  670     FD_SET(req->sock, &readfds1);
  671 
  672     if (!select((req->sock + 1), &readfds1, NULL, NULL, &tv1))
  673     {
  674         sprintf(logBuff, "HTTP Client %s, Message Receive failed", IP2String(tempbuff, req->remote.sin_addr.s_addr));
  675         logDHCPMess(logBuff, 1);
  676         closesocket(req->sock);
  677         free(req);
  678         return;
  679     }
  680 
  681     errno = 0;
  682     char buffer[1024];
  683     req->bytes = recv(req->sock, buffer, sizeof(buffer), 0);
  684     //errno = WSAGetLastError();
  685 
  686     if (errno || req->bytes <= 0)
  687     {
  688         sprintf(logBuff, "HTTP Client %s, Message Receive failed, Error %s", IP2String(tempbuff, req->remote.sin_addr.s_addr), strerror(errno));
  689         logDHCPMess(logBuff, 1);
  690         closesocket(req->sock);
  691         free(req);
  692         return;
  693     }
  694     else if (verbatim || cfig.dhcpLogLevel >= 2)
  695     {
  696         sprintf(logBuff, "HTTP Client %s, Request Processed", IP2String(tempbuff, req->remote.sin_addr.s_addr));
  697         logDHCPMess(logBuff, 2);
  698         //printf("%s\n", buffer);
  699     }
  700 
  701     if (cfig.httpClients[0] && !findServer(cfig.httpClients, 8, req->remote.sin_addr.s_addr))
  702     {
  703         if (verbatim || cfig.dhcpLogLevel >= 2)
  704         {
  705             sprintf(logBuff, "HTTP Client %s, Access Denied", IP2String(tempbuff, req->remote.sin_addr.s_addr));
  706             logDHCPMess(logBuff, 2);
  707         }
  708 
  709         req->dp = (char*)calloc(1, sizeof(send403));
  710         req->memSize = sizeof(send403);
  711         req->bytes = sprintf(req->dp, "%s", send403);
  712         pthread_t threadId;
  713         pthread_attr_t attr;
  714         pthread_attr_init(&attr);
  715         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  716         int errcode = pthread_create(&threadId, &attr, sendHTTP, (void*)req);
  717         pthread_attr_destroy(&attr);
  718         return;
  719     }
  720 
  721     buffer[sizeof(buffer) - 1] = 0;
  722     char *fp = NULL;
  723     char *end = strchr(buffer, '\n');
  724 
  725     if (end && end > buffer && (*(end - 1) == '\r'))
  726     {
  727         *(end - 1) = 0;
  728 
  729         if (myTokenize(buffer, buffer, " ", true) > 1)
  730             fp = myGetToken(buffer, 1);
  731     }
  732 
  733     if (fp && !strcasecmp(fp, "/"))
  734         sendStatus(req);
  735 //  else if (fp && !strcasecmp(fp, "/scopestatus"))
  736 //      sendScopeStatus(req);
  737     else
  738     {
  739         if (fp && (verbatim || cfig.dhcpLogLevel >= 2))
  740         {
  741             sprintf(logBuff, "HTTP Client %s, %s not found", IP2String(tempbuff, req->remote.sin_addr.s_addr), fp);
  742             logDHCPMess(logBuff, 2);
  743         }
  744         else if (verbatim || cfig.dhcpLogLevel >= 2)
  745         {
  746             sprintf(logBuff, "HTTP Client %s, Invalid request", IP2String(tempbuff, req->remote.sin_addr.s_addr));
  747             logDHCPMess(logBuff, 2);
  748         }
  749 
  750         req->dp = (char*)calloc(1, sizeof(send404));
  751         req->bytes = sprintf(req->dp, "%s", send404);
  752         req->memSize = sizeof(send404);
  753         pthread_t threadId;
  754         pthread_attr_t attr;
  755         pthread_attr_init(&attr);
  756         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  757         int errcode = pthread_create(&threadId, &attr, sendHTTP, (void*)req);
  758         pthread_attr_destroy(&attr);
  759         return;
  760     }
  761 }
  762 
  763 void sendStatus(data19 *req)
  764 {
  765     //debug("sendStatus");
  766     char ipbuff[16];
  767     char extbuff[16];
  768     char logBuff[512];
  769     char tempbuff[512];
  770 
  771     dhcpMap::iterator p;
  772     MYDWORD iip = 0;
  773     data7 *dhcpEntry = NULL;
  774     //data7 *cache = NULL;
  775     //printf("%d=%d\n", dhcpCache.size(), cfig.dhcpSize);
  776     req->memSize = 2048 + (135 * dhcpCache.size()) + (cfig.dhcpSize * 26);
  777     req->dp = (char*)calloc(1, req->memSize);
  778 
  779     if (!req->dp)
  780     {
  781         sprintf(logBuff, "Memory Error");
  782         logDHCPMess(logBuff, 1);
  783         closesocket(req->sock);
  784         free(req);
  785         return;
  786     }
  787 
  788     char *fp = req->dp;
  789     char *maxData = req->dp + (req->memSize - 512);
  790     //tm *ttm = gmtime(&t);
  791     //strftime(tempbuff, sizeof(tempbuff), "%a, %d %b %Y %H:%M:%S GMT", ttm);
  792     //fp += sprintf(fp, send200, tempbuff, tempbuff);
  793     //fp += sprintf(fp, send200);
  794     //char *contentStart = fp;
  795     fp += sprintf(fp, htmlStart, htmlTitle);
  796 
  797     if (cfig.replication == 1)
  798         fp += sprintf(fp, bodyStart, sVersion, cfig.servername, "(Primary)");
  799     else if (cfig.replication == 2)
  800         fp += sprintf(fp, bodyStart, sVersion, cfig.servername, "(Secondary)");
  801     else
  802         fp += sprintf(fp, bodyStart, sVersion, cfig.servername, "");
  803 
  804     fp += sprintf(fp, "\n<table border=\"1\" cellpadding=\"1\" width=\"100%%\" bgcolor=\"#b8b8b8\">\n");
  805 
  806     if (cfig.dhcpRepl > t)
  807     {
  808         fp += sprintf(fp, "<tr><th colspan=\"5\"><font size=\"5\"><i>Active Leases</i></font></th></tr>\n");
  809         fp += sprintf(fp, "<tr><th>Mac Address</th><th>IP</th><th>Lease Expiry</th><th>Hostname (first 20 chars)</th><th>Server</th></tr>\n");
  810     }
  811     else
  812     {
  813         fp += sprintf(fp, "<tr><th colspan=\"4\"><font size=\"5\"><i>Active Leases</i></font></th></tr>\n");
  814         fp += sprintf(fp, "<tr><th>Mac Address</th><th>IP</th><th>Lease Expiry</th><th>Hostname (first 20 chars)</th></tr>\n");
  815     }
  816 
  817     for (p = dhcpCache.begin(); kRunning && p != dhcpCache.end() && fp < maxData; p++)
  818     {
  819         //if ((dhcpEntry = p->second) && dhcpEntry->display)
  820         if ((dhcpEntry = p->second) && dhcpEntry->display && dhcpEntry->expiry >= t)
  821         {
  822             fp += sprintf(fp, "<tr>");
  823             fp += sprintf(fp, td200, dhcpEntry->mapname);
  824             fp += sprintf(fp, td200, IP2String(tempbuff, dhcpEntry->ip));
  825 
  826             if (dhcpEntry->expiry >= MY_MAX_TIME)
  827                 fp += sprintf(fp, td200, "Infinity");
  828             else
  829             {
  830                 tm *ttm = localtime(&dhcpEntry->expiry);
  831                 strftime(tempbuff, sizeof(tempbuff), "%d-%b-%y %X", ttm);
  832                 fp += sprintf(fp, tdnowrap200, tempbuff);
  833             }
  834 
  835             if (dhcpEntry->hostname[0])
  836             {
  837                 strcpy(tempbuff, dhcpEntry->hostname);
  838                 tempbuff[20] = 0;
  839                 fp += sprintf(fp, td200, tempbuff);
  840             }
  841             else
  842                 fp += sprintf(fp, td200, "&nbsp;");
  843 
  844             if (cfig.dhcpRepl > t)
  845             {
  846                 if (dhcpEntry->local && cfig.replication == 1)
  847                     fp += sprintf(fp, td200, "Primary");
  848                 else if (dhcpEntry->local && cfig.replication == 2)
  849                     fp += sprintf(fp, td200, "Secondary");
  850                 else if (cfig.replication == 1)
  851                     fp += sprintf(fp, td200, "Secondary");
  852                 else
  853                     fp += sprintf(fp, td200, "Primary");
  854             }
  855 
  856             fp += sprintf(fp, "</tr>\n");
  857         }
  858     }
  859 
  860     fp += sprintf(fp, "</table>\n<br>\n<table border=\"1\" cellpadding=\"1\" width=\"100%%\" bgcolor=\"#b8b8b8\">\n");
  861     fp += sprintf(fp, "<tr><th colspan=\"4\"><font size=\"5\"><i>Free Dynamic Leases</i></font></th></tr>\n");
  862     fp += sprintf(fp, "<tr><td><b>DHCP Range</b></td><td><b>Mask</b></td><td align=\"right\"><b>Available Leases</b></td><td align=\"right\"><b>Free Leases</b></td></tr>\n");
  863 
  864     for (char rangeInd = 0; kRunning && rangeInd < cfig.rangeCount && fp < maxData; rangeInd++)
  865     {
  866         MYWORD ipused = 0;
  867         MYWORD ipfree = 0;
  868         MYWORD ind = 0;
  869 
  870         for (MYDWORD iip = cfig.dhcpRanges[rangeInd].rangeStart; iip <= cfig.dhcpRanges[rangeInd].rangeEnd; iip++, ind++)
  871         {
  872             if (cfig.dhcpRanges[rangeInd].expiry[ind] < MY_MAX_TIME)
  873             {
  874                 if (cfig.dhcpRanges[rangeInd].expiry[ind] < t)
  875                     ipfree++;
  876                 else
  877                     ipused++;
  878             }
  879         }
  880 
  881         IP2String(tempbuff, ntohl(cfig.dhcpRanges[rangeInd].rangeStart));
  882         IP2String(ipbuff, ntohl(cfig.dhcpRanges[rangeInd].rangeEnd));
  883         IP2String(extbuff, cfig.dhcpRanges[rangeInd].mask);
  884         fp += sprintf(fp, "<tr><td nowrap>%s - %s</td><td nowrap>%s</td><td align=\"right\">%i</td><td align=\"right\">%i</td></tr>\n", tempbuff, ipbuff, extbuff, (ipused + ipfree), ipfree);
  885     }
  886 
  887     fp += sprintf(fp, "</table>\n<br>\n<table border=\"1\" width=\"100%%\" cellpadding=\"1\" bgcolor=\"#b8b8b8\">\n");
  888     fp += sprintf(fp, "<tr><th colspan=\"4\"><font size=\"5\"><i>Free Static Leases</i></font></th></tr>\n");
  889     fp += sprintf(fp, "<tr><th>Mac Address</th><th>IP</th><th>Mac Address</th><th>IP</th></tr>\n");
  890 
  891     MYBYTE colNum = 0;
  892 
  893     for (p = dhcpCache.begin(); kRunning && p != dhcpCache.end() && fp < maxData; p++)
  894     {
  895         if ((dhcpEntry = p->second) && dhcpEntry->fixed && dhcpEntry->expiry < t)
  896         {
  897             if (!colNum)
  898             {
  899                 fp += sprintf(fp, "<tr>");
  900                 colNum = 1;
  901             }
  902             else if (colNum == 1)
  903             {
  904                 colNum = 2;
  905             }
  906             else if (colNum == 2)
  907             {
  908                 fp += sprintf(fp, "</tr>\n<tr>");
  909                 colNum = 1;
  910             }
  911 
  912             fp += sprintf(fp, td200, dhcpEntry->mapname);
  913             fp += sprintf(fp, td200, IP2String(tempbuff, dhcpEntry->ip));
  914         }
  915     }
  916 
  917     if (colNum)
  918         fp += sprintf(fp, "</tr>\n");
  919 
  920     fp += sprintf(fp, "</table></td></tr></table>\n</body>\n</html>");
  921     //MYBYTE x = sprintf(tempbuff, "%u", (fp - contentStart));
  922     //memcpy((contentStart - 12), tempbuff, x);
  923     req->bytes = fp - req->dp;
  924     pthread_t threadId;
  925     pthread_attr_t attr;
  926     pthread_attr_init(&attr);
  927     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  928     int errcode = pthread_create(&threadId, &attr, sendHTTP, (void*)req);
  929     pthread_attr_destroy(&attr);
  930     return;
  931 }
  932 
  933 /*
  934 void sendScopeStatus(data19 *req)
  935 {
  936     //debug("sendScopeStatus");
  937 
  938     MYBYTE rangeCount = 0;
  939     req->memSize = 1536 + (150 * cfig.rangeCount);
  940     req->dp = (char*)calloc(1, req->memSize);
  941 
  942     if (!req->dp)
  943     {
  944         sprintf(logBuff, "Memory Error");
  945         logDHCPMess(logBuff, 1);
  946         closesocket(req->sock);
  947         free(req);
  948         return;
  949     }
  950 
  951     char *fp = req->dp;
  952     char *maxData = req->dp + (req->memSize - 512);
  953     tm *ttm = gmtime(&t);
  954     strftime(tempbuff, sizeof(tempbuff), "%a, %d %b %Y %H:%M:%S GMT", ttm);
  955     fp += sprintf(fp, send200, tempbuff, tempbuff);
  956     char *contentStart = fp;
  957     fp += sprintf(fp, htmlStart, htmlTitle);
  958     fp += sprintf(fp, bodyStart, sVersion);
  959     fp += sprintf(fp, "<table border=\"1\" cellpadding=\"1\" width=\"640\" bgcolor=\"#b8b8b8\">\n");
  960     fp += sprintf(fp, "<tr><th colspan=\"4\"><font size=\"5\"><i>Scope Status</i></font></th></tr>\n");
  961     fp += sprintf(fp, "<tr><td><b>DHCP Range</b></td><td align=\"right\"><b>IPs Used</b></td><td align=\"right\"><b>IPs Free</b></td><td align=\"right\"><b>%% Free</b></td></tr>\n");
  962     MYBYTE colNum = 0;
  963 
  964     for (char rangeInd = 0; kRunning && rangeInd < cfig.rangeCount && fp < maxData; rangeInd++)
  965     {
  966         float ipused = 0;
  967         float ipfree = 0;
  968         int ind = 0;
  969 
  970         for (MYDWORD iip = cfig.dhcpRanges[rangeInd].rangeStart; iip <= cfig.dhcpRanges[rangeInd].rangeEnd; iip++, ind++)
  971         {
  972             if (cfig.dhcpRanges[rangeInd].expiry[ind] > t)
  973                 ipused++;
  974             else
  975                 ipfree++;
  976         }
  977 
  978         IP2String(tempbuff, ntohl(cfig.dhcpRanges[rangeInd].rangeStart));
  979         IP2String(extbuff, ntohl(cfig.dhcpRanges[rangeInd].rangeEnd));
  980         fp += sprintf(fp, "<tr><td>%s - %s</td><td align=\"right\">%5.0f</td><td align=\"right\">%5.0f</td><td align=\"right\">%2.2f</td></tr>\n", tempbuff, extbuff, ipused, ipfree, ((ipfree * 100)/(ipused + ipfree)));
  981     }
  982 
  983     fp += sprintf(fp, "</table>\n</body>\n</html>");
  984     memcpy((contentStart - 12), tempbuff, sprintf(tempbuff, "%u", (fp - contentStart)));
  985     req->bytes = fp - req->dp;
  986 
  987     _beginthread(sendHTTP, 0, (void*)req);
  988     return;
  989 }
  990 */
  991 
  992 /*
  993 void *sendHTTP(void *lpParam)
  994 {
  995     data19 *req = (data19*)lpParam;
  996 
  997     //sprintf(logBuff, "sendHTTP memsize=%d bytes=%d", req->memSize, req->bytes);
  998     //(logBuff);
  999 
 1000     char *dp = req->dp;
 1001     timeval tv1;
 1002     fd_set writefds1;
 1003     char header[16];
 1004     int sent = 0;
 1005     byte sendheader = true;
 1006 
 1007     while (kRunning && req->bytes > 0)
 1008     {
 1009         tv1.tv_sec = 5;
 1010         tv1.tv_usec = 0;
 1011         FD_ZERO(&writefds1);
 1012         FD_SET(req->sock, &writefds1);
 1013 
 1014         if (select((req->sock + 1), NULL, &writefds1, NULL, &tv1))
 1015         {
 1016             if (sendheader)
 1017             {
 1018                 char send200[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n";
 1019                 send(req->sock, send200, strlen(send200), 0);
 1020                 sendheader = false;
 1021             }
 1022             else if (req->bytes > 1024)
 1023             {
 1024                 sprintf(header, "\r\n%04x\r\n", 1024);
 1025                 send(req->sock, header, 8, 0);
 1026                 sent  = send(req->sock, dp, 1024, 0);
 1027             }
 1028             else if (req->bytes > 0)
 1029             {
 1030                 sprintf(header, "\r\n%04x\r\n", req->bytes);
 1031                 send(req->sock, header, 8, 0);
 1032                 sent  = send(req->sock, dp, req->bytes, 0);
 1033             }
 1034             else
 1035             {
 1036                 sprintf(header, "\r\n%04x\r\n", 0);
 1037                 send(req->sock, header, 8, 0);
 1038                 break;
 1039             }
 1040 
 1041             //errno = WSAGetLastError();
 1042 
 1043             if (errno || sent < 0)
 1044                 break;
 1045 
 1046             dp += sent;
 1047             req->bytes -= sent;
 1048         }
 1049         else
 1050             break;
 1051     }
 1052     //Sleep(10*1000);
 1053     //shutdown(req->sock, 2);
 1054     closesocket(req->sock);
 1055     free(req->dp);
 1056     free(req);
 1057     pthread_exit(NULL);
 1058 }
 1059 */
 1060 
 1061 /*
 1062 void *sendHTTP(void *lpParam)
 1063 {
 1064     data19 *req = (data19*)lpParam;
 1065 
 1066     //sprintf(logBuff, "sendHTTP memsize=%d bytes=%d", req->memSize, req->bytes);
 1067     //(logBuff);
 1068 
 1069     char *dp = req->dp;
 1070     timeval tv1;
 1071     fd_set writefds1;
 1072     int sent = 0;
 1073     bool sendheader = true;
 1074 
 1075     while (kRunning && req->bytes > 0)
 1076     {
 1077         tv1.tv_sec = 5;
 1078         tv1.tv_usec = 0;
 1079         FD_ZERO(&writefds1);
 1080         FD_SET(req->sock, &writefds1);
 1081 
 1082         if (select((req->sock + 1), NULL, &writefds1, NULL, &tv1))
 1083         {
 1084             if (sendheader)
 1085             {
 1086                 char send200[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n";
 1087                 send(req->sock, send200, strlen(send200), 0);
 1088                 sendheader = false;
 1089             }
 1090             else if (req->bytes > 1024)
 1091                 sent  = send(req->sock, dp, 1024, 0);
 1092             else if (req->bytes > 0)
 1093                 sent  = send(req->sock, dp, req->bytes, 0);
 1094             else
 1095                 break;
 1096 
 1097             //errno = WSAGetLastError();
 1098 
 1099             if (errno || sent < 0)
 1100                 break;
 1101 
 1102             dp += sent;
 1103             req->bytes -= sent;
 1104         }
 1105         else
 1106             break;
 1107     }
 1108     //Sleep(10*1000);
 1109     //shutdown(req->sock, 2);
 1110     closesocket(req->sock);
 1111     free(req->dp);
 1112     free(req);
 1113     pthread_exit(NULL);
 1114 }
 1115 */
 1116 
 1117 void *sendHTTP(void *lpParam)
 1118 {
 1119     data19 *req = (data19*)lpParam;
 1120 
 1121     //sprintf(logBuff, "sendHTTP memsize=%d bytes=%d", req->memSize, req->bytes);
 1122     //(logBuff);
 1123 
 1124     char *dp = req->dp;
 1125     timeval tv1;
 1126     fd_set writefds1;
 1127     int sent = 0;
 1128     bool sendheader = true;
 1129 
 1130     while (kRunning && req->bytes > 0)
 1131     {
 1132         tv1.tv_sec = 5;
 1133         tv1.tv_usec = 0;
 1134         FD_ZERO(&writefds1);
 1135         FD_SET(req->sock, &writefds1);
 1136 
 1137         if (select((req->sock + 1), NULL, &writefds1, NULL, &tv1))
 1138         {
 1139             if (sendheader)
 1140             {
 1141                 char send200[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: %i\r\n\r\n";
 1142                 char header[256];
 1143                 sprintf(header, send200, req->bytes);
 1144                 send(req->sock, header, strlen(header), 0);
 1145                 sendheader = false;
 1146             }
 1147             else if (req->bytes > 1024)
 1148                 sent  = send(req->sock, dp, 1024, 0);
 1149             else if (req->bytes > 0)
 1150                 sent  = send(req->sock, dp, req->bytes, 0);
 1151             else
 1152                 break;
 1153 
 1154             //errno = WSAGetLastError();
 1155 
 1156             if (errno || sent < 0)
 1157                 break;
 1158 
 1159             dp += sent;
 1160             req->bytes -= sent;
 1161         }
 1162         else
 1163             break;
 1164     }
 1165     //Sleep(10*1000);
 1166     //shutdown(req->sock, 2);
 1167     closesocket(req->sock);
 1168     free(req->dp);
 1169     free(req);
 1170     pthread_exit(NULL);
 1171 }
 1172 
 1173 bool checkRange(data17 *rangeData, char rangeInd)
 1174 {
 1175     //debug("checkRange");
 1176 
 1177     if (!cfig.hasFilter)
 1178         return true;
 1179 
 1180     MYBYTE rangeSetInd = cfig.dhcpRanges[rangeInd].rangeSetInd;
 1181     data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
 1182     //printf("checkRange entering, rangeInd=%i rangeSetInd=%i\n", rangeInd, rangeSetInd);
 1183     //printf("checkRange entered, macFound=%i vendFound=%i userFound=%i\n", macFound, vendFound, userFound);
 1184 
 1185     if((!rangeData->macFound && !rangeSet->macSize[0]) || (rangeData->macFound && rangeData->macArray[rangeSetInd]))
 1186         if((!rangeData->vendFound && !rangeSet->vendClassSize[0]) || (rangeData->vendFound && rangeData->vendArray[rangeSetInd]))
 1187             if((!rangeData->userFound && !rangeSet->userClassSize[0]) || (rangeData->userFound && rangeData->userArray[rangeSetInd]))
 1188                 if((!rangeData->subnetFound && !rangeSet->subnetIP[0]) || (rangeData->subnetFound && rangeData->subnetArray[rangeSetInd]))
 1189                     return true;
 1190 
 1191     //printf("checkRange, returning false rangeInd=%i rangeSetInd=%i\n", rangeInd, rangeSetInd);
 1192     return false;
 1193 }
 1194 
 1195 bool checkIP(data9 *req, data17 *rangeData, MYDWORD ip)
 1196 {
 1197     MYDWORD rangeStart;
 1198     MYDWORD rangeEnd;
 1199 
 1200     char rangeInd = getRangeInd(ip);
 1201 
 1202     if (rangeInd < 0)
 1203         return false;
 1204 
 1205     if (!checkRange(rangeData, rangeInd))
 1206         return false;
 1207 
 1208     MYWORD ind = getIndex(rangeInd, ip);
 1209     data13 *range = &cfig.dhcpRanges[rangeInd];
 1210     data7 *dhcpEntry = range->dhcpEntry[ind];
 1211 
 1212     if ((req->dhcpEntry != dhcpEntry && range->expiry[ind] > t) or range->expiry[ind] >= MY_MAX_TIME)
 1213         return false;
 1214 
 1215     if(req->subnetIP)
 1216     {
 1217         if(cfig.rangeSet[range->rangeSetInd].subnetIP[0])
 1218         {
 1219             rangeStart = range->rangeStart;
 1220             rangeEnd = range->rangeEnd;
 1221         }
 1222         else
 1223         {
 1224             calcRangeLimits(req->subnetIP, range->mask, &rangeStart, &rangeEnd);
 1225 
 1226             if (rangeStart < range->rangeStart)
 1227                 rangeStart = range->rangeStart;
 1228 
 1229             if (rangeEnd > range->rangeEnd)
 1230                 rangeEnd = range->rangeEnd;
 1231         }
 1232 
 1233         if (htonl(ip) >= rangeStart && htonl(ip) <= rangeEnd)
 1234             return true;
 1235     }
 1236     else
 1237     {
 1238         calcRangeLimits(network.dhcpConn[req->sockInd].server, range->mask, &rangeStart, &rangeEnd);
 1239 
 1240         if (rangeStart < range->rangeStart)
 1241             rangeStart = range->rangeStart;
 1242 
 1243         if (rangeEnd > range->rangeEnd)
 1244             rangeEnd = range->rangeEnd;
 1245 
 1246         if (htonl(ip) >= rangeStart && htonl(ip) <= rangeEnd)
 1247             return true;
 1248     }
 1249     return false;
 1250 }
 1251 
 1252 MYDWORD resad(data9 *req)
 1253 {
 1254     //debug("resad");
 1255     char logBuff[512];
 1256     char tempbuff[512];
 1257 
 1258     if (req->dhcpp.header.bp_giaddr)
 1259     {
 1260         lockIP(req->dhcpp.header.bp_giaddr);
 1261         lockIP(req->remote.sin_addr.s_addr);
 1262     }
 1263 
 1264     req->dhcpEntry = findDHCPEntry(req->chaddr);
 1265 
 1266     if (req->dhcpEntry && req->dhcpEntry->fixed)
 1267     {
 1268         if (req->dhcpEntry->ip)
 1269         {
 1270             setTempLease(req->dhcpEntry);
 1271             return req->dhcpEntry->ip;
 1272         }
 1273         else
 1274         {
 1275             if (verbatim || cfig.dhcpLogLevel)
 1276             {
 1277                 sprintf(logBuff, "Static DHCP Host %s (%s) has No IP, DHCPDISCOVER ignored", req->chaddr, req->hostname);
 1278                 logDHCPMess(logBuff, 1);
 1279             }
 1280             return 0;
 1281         }
 1282     }
 1283 
 1284     MYDWORD rangeStart = 0;
 1285     MYDWORD rangeEnd = 0;
 1286     MYDWORD iipNew = 0;
 1287     MYDWORD iipExp = 0;
 1288     bool rangeFound = false;
 1289     data17 rangeData;
 1290     memset(&rangeData, 0, sizeof(data17));
 1291 
 1292     if (cfig.hasFilter)
 1293     {
 1294         for (MYBYTE rangeSetInd = 0; rangeSetInd < MAX_RANGE_SETS && cfig.rangeSet[rangeSetInd].active; rangeSetInd++)
 1295         {
 1296             data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
 1297 
 1298             for (MYBYTE i = 0; i < MAX_RANGE_FILTERS && rangeSet->macSize[i]; i++)
 1299             {
 1300                 //printf("%s\n", hex2String(tempbuff, rangeSet->macStart[i], rangeSet->macSize[i]));
 1301                 //printf("%s\n", hex2String(tempbuff, rangeSet->macEnd[i], rangeSet->macSize[i]));
 1302 
 1303                 if(memcmp(req->dhcpp.header.bp_chaddr, rangeSet->macStart[i], rangeSet->macSize[i]) >= 0 && memcmp(req->dhcpp.header.bp_chaddr, rangeSet->macEnd[i], rangeSet->macSize[i]) <= 0)
 1304                 {
 1305                     rangeData.macArray[rangeSetInd] = 1;
 1306                     rangeData.macFound = true;
 1307                     //printf("mac Found, rangeSetInd=%i\n", rangeSetInd);
 1308                     break;
 1309                 }
 1310             }
 1311 
 1312             for (MYBYTE i = 0; i < MAX_RANGE_FILTERS && req->vendClass.size && rangeSet->vendClassSize[i]; i++)
 1313             {
 1314                 if(rangeSet->vendClassSize[i] == req->vendClass.size && !memcmp(req->vendClass.value, rangeSet->vendClass[i], rangeSet->vendClassSize[i]))
 1315                 {
 1316                     rangeData.vendArray[rangeSetInd] = 1;
 1317                     rangeData.vendFound = true;
 1318                     //printf("vend Found, rangeSetInd=%i\n", rangeSetInd);
 1319                     break;
 1320                 }
 1321             }
 1322 
 1323             for (MYBYTE i = 0; i < MAX_RANGE_FILTERS && req->userClass.size && rangeSet->userClassSize[i]; i++)
 1324             {
 1325                 if(rangeSet->userClassSize[i] == req->userClass.size && !memcmp(req->userClass.value, rangeSet->userClass[i], rangeSet->userClassSize[i]))
 1326                 {
 1327                     rangeData.userArray[rangeSetInd] = 1;
 1328                     rangeData.userFound = true;
 1329                     //printf("user Found, rangeSetInd=%i\n", rangeSetInd);
 1330                     break;
 1331                 }
 1332             }
 1333 
 1334             for (MYBYTE i = 0; i < MAX_RANGE_FILTERS && req->subnetIP && rangeSet->subnetIP[i]; i++)
 1335             {
 1336                 if(req->subnetIP == rangeSet->subnetIP[i])
 1337                 {
 1338                     rangeData.subnetArray[rangeSetInd] = 1;
 1339                     rangeData.subnetFound = true;
 1340                     //printf("subnet Found, rangeSetInd=%i\n", rangeSetInd);
 1341                     break;
 1342                 }
 1343             }
 1344         }
 1345 
 1346     }
 1347 
 1348 //  printArray("macArray", (char*)cfig.macArray);
 1349 //  printArray("vendArray", (char*)cfig.vendArray);
 1350 //  printArray("userArray", (char*)cfig.userArray);
 1351 
 1352     if (!iipNew && req->reqIP && checkIP(req, &rangeData, req->reqIP))
 1353         iipNew = ntohl(req->reqIP);
 1354 
 1355     if (!iipNew && req->dhcpEntry && req->dhcpEntry->ip && checkIP(req, &rangeData, req->dhcpEntry->ip))
 1356         iipNew = ntohl(req->dhcpEntry->ip);
 1357 
 1358     for (char k = 0; !iipNew && k < cfig.rangeCount; k++)
 1359     {
 1360         data13 *range = &cfig.dhcpRanges[k];
 1361 
 1362         if (checkRange(&rangeData, k))
 1363         {
 1364             if (!cfig.rangeSet[range->rangeSetInd].subnetIP[0])
 1365             {
 1366                 if (req->subnetIP)
 1367                     calcRangeLimits(req->subnetIP, range->mask, &rangeStart, &rangeEnd);
 1368                 else
 1369                     calcRangeLimits(network.dhcpConn[req->sockInd].server, network.dhcpConn[req->sockInd].mask, &rangeStart, &rangeEnd);
 1370 
 1371                 if (rangeStart < range->rangeStart)
 1372                     rangeStart = range->rangeStart;
 1373 
 1374                 if (rangeEnd > range->rangeEnd)
 1375                     rangeEnd = range->rangeEnd;
 1376             }
 1377             else
 1378             {
 1379                 rangeStart = range->rangeStart;
 1380                 rangeEnd = range->rangeEnd;
 1381             }
 1382 
 1383             if (rangeStart <= rangeEnd)
 1384             {
 1385                 //sprintf(logBuff, "Start=%u End=%u", rangeStart, rangeEnd);
 1386                 //logMess(logBuff, 1);
 1387                 rangeFound = true;
 1388 
 1389                 if (cfig.replication == 2)
 1390                 {
 1391                     for (MYDWORD m = rangeEnd; m >= rangeStart; m--)
 1392                     {
 1393                         int ind = m - range->rangeStart;
 1394 
 1395                         if (!range->expiry[ind])
 1396                         {
 1397                             iipNew = m;
 1398                             break;
 1399                         }
 1400                         else if (!iipExp && range->expiry[ind] < t)
 1401                         {
 1402                             iipExp = m;
 1403                         }
 1404                     }
 1405                 }
 1406                 else
 1407                 {
 1408                     for (MYDWORD m = rangeStart; m <= rangeEnd; m++)
 1409                     {
 1410                         int ind = m - range->rangeStart;
 1411 
 1412                         //sprintf(logBuff, "Ind=%u Exp=%u", m, range->expiry[ind]);
 1413                         //logMess(logBuff, 1);
 1414 
 1415                         if (!range->expiry[ind])
 1416                         {
 1417                             iipNew = m;
 1418                             break;
 1419                         }
 1420                         else if (!iipExp && range->expiry[ind] < t)
 1421                         {
 1422                             iipExp = m;
 1423                         }
 1424                     }
 1425                 }
 1426             }
 1427         }
 1428     }
 1429 
 1430     //sprintf(logBuff, "New=%u Old=%u", iipNew, iipExp);
 1431     //logMess(logBuff, 1);
 1432 
 1433     if (!iipNew && iipExp)
 1434             iipNew = iipExp;
 1435 
 1436     if (iipNew)
 1437     {
 1438         if (!req->dhcpEntry)
 1439         {
 1440             memset(&lump, 0, sizeof(data71));
 1441             lump.mapname = req->chaddr;
 1442             lump.hostname = req->hostname;
 1443             req->dhcpEntry = createCache(&lump);
 1444 
 1445             if (!req->dhcpEntry)
 1446                 return 0;
 1447 
 1448             dhcpCache[req->dhcpEntry->mapname] = req->dhcpEntry;
 1449         }
 1450 
 1451         req->dhcpEntry->ip = htonl(iipNew);
 1452         req->dhcpEntry->rangeInd = getRangeInd(req->dhcpEntry->ip);
 1453         req->dhcpEntry->subnetFlg = !!req->subnetIP;
 1454         setTempLease(req->dhcpEntry);
 1455         return req->dhcpEntry->ip;
 1456     }
 1457 
 1458     if (verbatim || cfig.dhcpLogLevel)
 1459     {
 1460         if (rangeFound)
 1461         {
 1462             if (req->dhcpp.header.bp_giaddr)
 1463                 sprintf(logBuff, "No free leases for DHCPDISCOVER for %s (%s) from RelayAgent %s", req->chaddr, req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_giaddr));
 1464             else
 1465                 sprintf(logBuff, "No free leases for DHCPDISCOVER for %s (%s) from interface %s", req->chaddr, req->hostname, IP2String(tempbuff, network.dhcpConn[req->sockInd].server));
 1466         }
 1467         else
 1468         {
 1469             if (req->dhcpp.header.bp_giaddr)
 1470                 sprintf(logBuff, "No Matching DHCP Range for DHCPDISCOVER for %s (%s) from RelayAgent %s", req->chaddr, req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_giaddr));
 1471             else
 1472                 sprintf(logBuff, "No Matching DHCP Range for DHCPDISCOVER for %s (%s) from interface %s", req->chaddr, req->hostname, IP2String(tempbuff, network.dhcpConn[req->sockInd].server));
 1473         }
 1474         logDHCPMess(logBuff, 1);
 1475     }
 1476     return 0;
 1477 }
 1478 
 1479 MYDWORD chkaddr(data9 *req)
 1480 {
 1481     //debug("chaddr");
 1482     //debug(req->remote.sin_addr.s_addr);
 1483     //debug(req->dhcpp.header.bp_ciaddr);
 1484 
 1485     req->dhcpEntry = findDHCPEntry(req->chaddr);
 1486 
 1487     if (!req->dhcpEntry || !req->dhcpEntry->ip)
 1488         return 0;
 1489 
 1490     //debug(req->dhcpEntry->subnetFlg);
 1491 
 1492     req->dhcpEntry->rangeInd = getRangeInd(req->dhcpEntry->ip);
 1493 
 1494     if (req->dhcpEntry->fixed)
 1495         return req->dhcpEntry->ip;
 1496 
 1497     MYDWORD rangeStart = 0;
 1498     MYDWORD rangeEnd = 0;
 1499 
 1500     if (req->dhcpEntry->rangeInd >= 0)
 1501     {
 1502         data17 rangeData;
 1503         memset(&rangeData, 0, sizeof(data17));
 1504         data13 *range = &cfig.dhcpRanges[req->dhcpEntry->rangeInd];
 1505         int ind = getIndex(req->dhcpEntry->rangeInd, req->dhcpEntry->ip);
 1506         bool rangeOK = true;
 1507 
 1508         if (cfig.hasFilter)
 1509         {
 1510             for (MYBYTE rangeSetInd = 0; rangeSetInd < MAX_RANGE_SETS && cfig.rangeSet[rangeSetInd].active; rangeSetInd++)
 1511             {
 1512                 data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
 1513 
 1514                 for (MYBYTE i = 0; i < MAX_RANGE_FILTERS && rangeSet->macSize[i]; i++)
 1515                 {
 1516                     //printf("%s\n", hex2String(tempbuff, rangeSet->macStart[i], rangeSet->macSize[i]));
 1517                     //printf("%s\n", hex2String(tempbuff, rangeSet->macEnd[i], rangeSet->macSize[i]));
 1518 
 1519                     if(memcmp(req->dhcpp.header.bp_chaddr, rangeSet->macStart[i], rangeSet->macSize[i]) >= 0 && memcmp(req->dhcpp.header.bp_chaddr, rangeSet->macEnd[i], rangeSet->macSize[i]) <= 0)
 1520                     {
 1521                         rangeData.macArray[rangeSetInd] = 1;
 1522                         rangeData.macFound = true;
 1523                         //printf("mac Found, rangeSetInd=%i\n", rangeSetInd);
 1524                         break;
 1525                     }
 1526                 }
 1527 
 1528                 for (MYBYTE i = 0; i < MAX_RANGE_FILTERS && req->vendClass.size && rangeSet->vendClassSize[i]; i++)
 1529                 {
 1530                     if(rangeSet->vendClassSize[i] == req->vendClass.size && !memcmp(req->vendClass.value, rangeSet->vendClass[i], rangeSet->vendClassSize[i]))
 1531                     {
 1532                         rangeData.vendArray[rangeSetInd] = 1;
 1533                         rangeData.vendFound = true;
 1534                         //printf("vend Found, rangeSetInd=%i\n", rangeSetInd);
 1535                         break;
 1536                     }
 1537                 }
 1538 
 1539                 for (MYBYTE i = 0; i < MAX_RANGE_FILTERS && req->userClass.size && rangeSet->userClassSize[i]; i++)
 1540                 {
 1541                     if(rangeSet->userClassSize[i] == req->userClass.size && !memcmp(req->userClass.value, rangeSet->userClass[i], rangeSet->userClassSize[i]))
 1542                     {
 1543                         rangeData.userArray[rangeSetInd] = 1;
 1544                         rangeData.userFound = true;
 1545                         //printf("user Found, rangeSetInd=%i\n", rangeSetInd);
 1546                         break;
 1547                     }
 1548                 }
 1549 
 1550                 for (MYBYTE i = 0; i < MAX_RANGE_FILTERS && req->subnetIP && rangeSet->subnetIP[i]; i++)
 1551                 {
 1552                     if(req->subnetIP == rangeSet->subnetIP[i])
 1553                     {
 1554                         rangeData.subnetArray[rangeSetInd] = 1;
 1555                         rangeData.subnetFound = true;
 1556                         //printf("subnet Found, rangeSetInd=%i\n", rangeSetInd);
 1557                         break;
 1558                     }
 1559                 }
 1560             }
 1561 
 1562             MYBYTE rangeSetInd = range->rangeSetInd;
 1563             data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
 1564             rangeOK = false;
 1565 
 1566             if((!rangeData.macFound && !rangeSet->macSize[0]) || (rangeData.macFound && rangeData.macArray[rangeSetInd]))
 1567                 if((!rangeData.vendFound && !rangeSet->vendClassSize[0]) || (rangeData.vendFound && rangeData.vendArray[rangeSetInd]))
 1568                     if((!rangeData.userFound && !rangeSet->userClassSize[0]) || (rangeData.userFound && rangeData.userArray[rangeSetInd]))
 1569                         rangeOK = true;
 1570         }
 1571 
 1572         if (range->dhcpEntry[ind] == req->dhcpEntry && rangeOK)
 1573         {
 1574             if(rangeData.subnetFound)
 1575             {
 1576                 if (rangeData.subnetArray[range->rangeSetInd])
 1577                     return req->dhcpEntry->ip;
 1578                 else
 1579                     return 0;
 1580             }
 1581             else if(req->subnetIP)
 1582             {
 1583                 calcRangeLimits(req->subnetIP, range->mask, &rangeStart, &rangeEnd);
 1584 
 1585                 if (rangeStart < range->rangeStart)
 1586                     rangeStart = range->rangeStart;
 1587 
 1588                 if (rangeEnd > range->rangeEnd)
 1589                     rangeEnd = range->rangeEnd;
 1590 
 1591                 if (htonl(req->dhcpEntry->ip) >= rangeStart && htonl(req->dhcpEntry->ip) <= rangeEnd)
 1592                     return req->dhcpEntry->ip;
 1593             }
 1594             else if(!req->dhcpEntry->subnetFlg && !cfig.rangeSet[range->rangeSetInd].subnetIP[0])
 1595             {
 1596                 calcRangeLimits(network.dhcpConn[req->sockInd].server, range->mask, &rangeStart, &rangeEnd);
 1597 
 1598                 if (rangeStart < range->rangeStart)
 1599                     rangeStart = range->rangeStart;
 1600 
 1601                 if (rangeEnd > range->rangeEnd)
 1602                     rangeEnd = range->rangeEnd;
 1603 
 1604                 if (htonl(req->dhcpEntry->ip) >= rangeStart && htonl(req->dhcpEntry->ip) <= rangeEnd)
 1605                     return req->dhcpEntry->ip;
 1606             }
 1607             else if(req->dhcpEntry->subnetFlg)
 1608                 return req->dhcpEntry->ip;
 1609         }
 1610     }
 1611 
 1612     return 0;
 1613 }
 1614 
 1615 MYDWORD sdmess(data9 *req)
 1616 {
 1617     //sprintf(logBuff, "sdmess, Request Type = %u",req->req_type);
 1618     //debug(logBuff);
 1619     char tempbuff[512];
 1620     char logBuff[256];
 1621 
 1622     if (req->req_type == DHCP_MESS_NONE)
 1623     {
 1624         req->dhcpp.header.bp_yiaddr = chkaddr(req);
 1625 
 1626         if (req->dhcpp.header.bp_yiaddr && req->dhcpEntry && req->dhcpEntry->fixed)
 1627             req->lease = UINT_MAX;
 1628         else
 1629         {
 1630             if (verbatim || cfig.dhcpLogLevel)
 1631             {
 1632                 sprintf(logBuff, "No Static Entry found for BOOTPREQUEST from Host %s", req->chaddr);
 1633                 logDHCPMess(logBuff, 1);
 1634             }
 1635 
 1636             return 0;
 1637         }
 1638     }
 1639     else if (req->req_type == DHCP_MESS_DECLINE)
 1640     {
 1641         /* Thanks to Timo for fixing issue here */
 1642         if (req->reqIP && chkaddr(req) == req->reqIP)
 1643         {
 1644             lockIP(req->reqIP);
 1645             req->dhcpEntry->ip = 0;
 1646             req->dhcpEntry->expiry = MY_MAX_TIME;
 1647             req->dhcpEntry->display = false;
 1648             req->dhcpEntry->local = false;
 1649 
 1650             if (verbatim || cfig.dhcpLogLevel)
 1651             {
 1652                 sprintf(logBuff, "IP Address %s declined by Host %s (%s), locked", IP2String(tempbuff, req->reqIP), req->chaddr, req->dhcpEntry->hostname);
 1653                 logDHCPMess(logBuff, 1);
 1654             }
 1655         }
 1656 
 1657         return 0;
 1658     }
 1659     else if (req->req_type == DHCP_MESS_RELEASE)
 1660     {
 1661         if (req->dhcpp.header.bp_ciaddr && chkaddr(req) == req->dhcpp.header.bp_ciaddr)
 1662         {
 1663             req->dhcpEntry->display = false;
 1664             req->dhcpEntry->local = false;
 1665             setLeaseExpiry(req->dhcpEntry, 0);
 1666 
 1667             pthread_t threadId;
 1668             pthread_attr_t attr;
 1669             pthread_attr_init(&attr);
 1670             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 1671             int errcode = pthread_create(&threadId, &attr, updateStateFile, (void*)req->dhcpEntry);
 1672             pthread_attr_destroy(&attr);
 1673 
 1674             if (verbatim || cfig.dhcpLogLevel)
 1675             {
 1676                 sprintf(logBuff, "IP Address %s released by Host %s (%s)", IP2String(tempbuff, req->dhcpp.header.bp_ciaddr), req->chaddr, req->hostname);
 1677                 logDHCPMess(logBuff, 1);
 1678             }
 1679         }
 1680 
 1681         return 0;
 1682     }
 1683     else if (req->req_type == DHCP_MESS_INFORM)
 1684     {
 1685         //printf("repl0=%s\n", IP2String(tempbuff, cfig.zoneServers[0]));
 1686         //printf("repl1=%s\n", IP2String(tempbuff, cfig.zoneServers[1]));
 1687         //printf("IP=%s bytes=%u replication=%i\n", IP2String(tempbuff, req->remote.sin_addr.s_addr), req->bytes, cfig.replication);
 1688 
 1689         if ((cfig.replication == 1 && req->remote.sin_addr.s_addr == cfig.zoneServers[1]) || (cfig.replication == 2 && req->remote.sin_addr.s_addr == cfig.zoneServers[0]))
 1690             recvRepl(req);
 1691 
 1692         return 0;
 1693     }
 1694     //else if (req->req_type == DHCP_MESS_DISCOVER && strcasecmp(req->hostname, cfig.servername))
 1695     else if (req->req_type == DHCP_MESS_DISCOVER)
 1696     {
 1697         req->dhcpp.header.bp_yiaddr = resad(req);
 1698 
 1699         if (!req->dhcpp.header.bp_yiaddr)
 1700             return 0;
 1701 
 1702         req->resp_type = DHCP_MESS_OFFER;
 1703     }
 1704     else if (req->req_type == DHCP_MESS_REQUEST)
 1705     {
 1706         //printf("%s\n", IP2String(tempbuff, req->dhcpp.header.bp_ciaddr));
 1707 
 1708         if (req->server)
 1709         {
 1710             if (req->server == network.dhcpConn[req->sockInd].server)
 1711             {
 1712                 if (req->reqIP && req->reqIP == chkaddr(req) && req->dhcpEntry->expiry > t)
 1713                 {
 1714                     req->resp_type = DHCP_MESS_ACK;
 1715                     req->dhcpp.header.bp_yiaddr = req->reqIP;
 1716                 }
 1717                 else if (req->dhcpp.header.bp_ciaddr && req->dhcpp.header.bp_ciaddr == chkaddr(req) && req->dhcpEntry->expiry > t)
 1718                 {
 1719                     req->resp_type = DHCP_MESS_ACK;
 1720                     req->dhcpp.header.bp_yiaddr = req->dhcpp.header.bp_ciaddr;
 1721                     req->dhcpp.header.bp_ciaddr = 0;
 1722                 }
 1723                 else
 1724                 {
 1725                     req->resp_type = DHCP_MESS_NAK;
 1726                     req->dhcpp.header.bp_yiaddr = 0;
 1727 
 1728                     if (verbatim || cfig.dhcpLogLevel)
 1729                     {
 1730                         sprintf(logBuff, "DHCPREQUEST from Host %s (%s) without Discover, NAKed", req->chaddr, req->hostname);
 1731                         logDHCPMess(logBuff, 1);
 1732                     }
 1733                 }
 1734             }
 1735             else
 1736                 return 0;
 1737         }
 1738         else if (req->dhcpp.header.bp_ciaddr && req->dhcpp.header.bp_ciaddr == chkaddr(req) && req->dhcpEntry->expiry > t)
 1739         {
 1740             req->resp_type = DHCP_MESS_ACK;
 1741             req->dhcpp.header.bp_yiaddr = req->dhcpp.header.bp_ciaddr;
 1742             req->dhcpp.header.bp_ciaddr = 0;
 1743         }
 1744         else if (req->reqIP && req->reqIP == chkaddr(req) && req->dhcpEntry->expiry > t)
 1745         {
 1746             req->resp_type = DHCP_MESS_ACK;
 1747             req->dhcpp.header.bp_yiaddr = req->reqIP;
 1748         }
 1749         else
 1750         {
 1751             req->resp_type = DHCP_MESS_NAK;
 1752             req->dhcpp.header.bp_yiaddr = 0;
 1753 
 1754             if (verbatim || cfig.dhcpLogLevel)
 1755             {
 1756                 sprintf(logBuff, "DHCPREQUEST from Host %s (%s) without Discover, NAKed", req->chaddr, req->hostname);
 1757                 logDHCPMess(logBuff, 1);
 1758             }
 1759         }
 1760     }
 1761     else
 1762         return 0;
 1763 
 1764     addOptions(req);
 1765     int packSize = req->vp - (MYBYTE*)&req->dhcpp;
 1766     packSize++;
 1767 
 1768     if (req->req_type == DHCP_MESS_NONE)
 1769         packSize = req->messsize;
 1770 
 1771     if (req->subnetIP && req->dhcpEntry && req->dhcpEntry->rangeInd >= 0)
 1772     {
 1773         MYBYTE rangeSetInd = cfig.dhcpRanges[req->dhcpEntry->rangeInd].rangeSetInd;
 1774         req->targetIP = cfig.rangeSet[rangeSetInd].targetIP;
 1775     }
 1776 
 1777     if (req->targetIP)
 1778     {
 1779         req->remote.sin_port = htons(IPPORT_DHCPS);
 1780         req->remote.sin_addr.s_addr = req->targetIP;
 1781     }
 1782     else if (req->dhcpp.header.bp_giaddr)
 1783     {
 1784         req->remote.sin_port = htons(IPPORT_DHCPS);
 1785         req->remote.sin_addr.s_addr = req->dhcpp.header.bp_giaddr;
 1786     }
 1787     else if (req->dhcpp.header.bp_broadcast || !req->remote.sin_addr.s_addr)
 1788     {
 1789         req->remote.sin_port = htons(IPPORT_DHCPC);
 1790         req->remote.sin_addr.s_addr = INADDR_BROADCAST;
 1791     }
 1792     else
 1793     {
 1794         req->remote.sin_port = htons(IPPORT_DHCPC);
 1795     }
 1796 
 1797     req->dhcpp.header.bp_op = BOOTP_REPLY;
 1798     errno = 0;
 1799 
 1800     if (req->req_type == DHCP_MESS_DISCOVER && !req->remote.sin_addr.s_addr)
 1801     {
 1802         req->bytes = sendto(network.dhcpConn[req->sockInd].sock,
 1803                             req->raw,
 1804                             packSize,
 1805                             MSG_DONTROUTE,
 1806                             (sockaddr*)&req->remote,
 1807                             sizeof(req->remote));
 1808     }
 1809     else
 1810     {
 1811         req->bytes = sendto(network.dhcpConn[req->sockInd].sock,
 1812                             req->raw,
 1813                             packSize,
 1814                             0,
 1815                             (sockaddr*)&req->remote,
 1816                             sizeof(req->remote));
 1817     }
 1818 
 1819     if (errno || req->bytes <= 0)
 1820         return 0;
 1821 
 1822     //printf("goes=%s %i\n",IP2String(tempbuff, req->dhcpp.header.bp_yiaddr),req->sockInd);
 1823     return req->dhcpp.header.bp_yiaddr;
 1824 }
 1825 
 1826 MYDWORD alad(data9 *req)
 1827 {
 1828     //debug("alad");
 1829     //printf("in alad hostname=%s\n", req->hostname);
 1830     char tempbuff[512];
 1831     char logBuff[256];
 1832 
 1833     if (req->dhcpEntry && (req->req_type == DHCP_MESS_NONE || req->resp_type == DHCP_MESS_ACK))
 1834     {
 1835         MYDWORD hangTime = req->lease;
 1836 
 1837         if (req->rebind > req->lease)
 1838             hangTime = req->rebind;
 1839 
 1840         req->dhcpEntry->display = true;
 1841         req->dhcpEntry->local = true;
 1842         setLeaseExpiry(req->dhcpEntry, hangTime);
 1843 
 1844         pthread_t threadId;
 1845         pthread_attr_t attr;
 1846         pthread_attr_init(&attr);
 1847         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 1848         int errcode = pthread_create(&threadId, &attr, updateStateFile, (void*)req->dhcpEntry);
 1849         pthread_attr_destroy(&attr);
 1850 
 1851         if (verbatim || cfig.dhcpLogLevel >= 1)
 1852         {
 1853             if (req->lease && req->reqIP)
 1854             {
 1855                 sprintf(logBuff, "Host %s (%s) allotted %s for %u seconds", req->chaddr, req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr), req->lease);
 1856             }
 1857             else if (req->req_type)
 1858             {
 1859                 sprintf(logBuff, "Host %s (%s) renewed %s for %u seconds", req->chaddr, req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr), req->lease);
 1860             }
 1861             else
 1862             {
 1863                 sprintf(logBuff, "BOOTP Host %s (%s) allotted %s", req->chaddr, req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr));
 1864             }
 1865             logDHCPMess(logBuff, 1);
 1866         }
 1867 
 1868         if (cfig.replication && cfig.dhcpRepl > t)
 1869             sendRepl(req);
 1870 
 1871         return req->dhcpEntry->ip;
 1872     }
 1873     else if ((verbatim || cfig.dhcpLogLevel >= 2) && req->resp_type == DHCP_MESS_OFFER)
 1874     {
 1875         sprintf(logBuff, "Host %s (%s) offered %s", req->chaddr, req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr));
 1876         logDHCPMess(logBuff, 2);
 1877     }
 1878     //printf("%u=out\n", req->resp_type);
 1879     return 0;
 1880 }
 1881 
 1882 void addOptions(data9 *req)
 1883 {
 1884     //debug("addOptions");
 1885 
 1886     data3 op;
 1887     int i;
 1888 
 1889     if (req->req_type && req->resp_type)
 1890     {
 1891         op.opt_code = DHCP_OPTION_MESSAGETYPE;
 1892         op.size = 1;
 1893         op.value[0] = req->resp_type;
 1894         pvdata(req, &op);
 1895     }
 1896 
 1897     if (req->dhcpEntry && req->resp_type != DHCP_MESS_DECLINE && req->resp_type != DHCP_MESS_NAK)
 1898     {
 1899         strcpy(req->dhcpp.header.bp_sname, cfig.servername);
 1900 
 1901         if (req->dhcpEntry->fixed)
 1902         {
 1903             //printf("%u,%u\n", req->dhcpEntry->options, *req->dhcpEntry->options);
 1904             MYBYTE *opPointer = req->dhcpEntry->options;
 1905 
 1906             if (opPointer)
 1907             {
 1908                 MYBYTE requestedOnly = *opPointer;
 1909                 opPointer++;
 1910 
 1911                 while (*opPointer && *opPointer != DHCP_OPTION_END)
 1912                 {
 1913                     op.opt_code = *opPointer;
 1914                     opPointer++;
 1915                     op.size = *opPointer;
 1916                     opPointer++;
 1917 
 1918                     if (!requestedOnly || req->paramreqlist[*opPointer])
 1919                     {
 1920                         memcpy(op.value, opPointer, op.size);
 1921                         pvdata(req, &op);
 1922                     }
 1923                     opPointer += op.size;
 1924                 }
 1925             }
 1926         }
 1927 
 1928         if (req->req_type && req->resp_type)
 1929         {
 1930             if (req->dhcpEntry->rangeInd >= 0)
 1931             {
 1932                 MYBYTE *opPointer = cfig.dhcpRanges[req->dhcpEntry->rangeInd].options;
 1933                 //printf("Range=%i Pointer=%u\n", req->dhcpEntry->rangeInd,opPointer);
 1934 
 1935                 if (opPointer)
 1936                 {
 1937                     MYBYTE requestedOnly = *opPointer;
 1938                     opPointer++;
 1939 
 1940                     while (*opPointer && *opPointer != DHCP_OPTION_END)
 1941                     {
 1942                         op.opt_code = *opPointer;
 1943                         opPointer++;
 1944                         op.size = *opPointer;
 1945                         opPointer++;
 1946 
 1947                         if (!requestedOnly || req->paramreqlist[*opPointer])
 1948                         {
 1949                             memcpy(op.value, opPointer, op.size);
 1950                             pvdata(req, &op);
 1951                         }
 1952                         opPointer += op.size;
 1953                     }
 1954                 }
 1955             }
 1956 
 1957             MYBYTE *opPointer = cfig.options;
 1958 
 1959             if (opPointer)
 1960             {
 1961                 MYBYTE requestedOnly = *opPointer;
 1962 
 1963                 opPointer++;
 1964                 while (*opPointer && *opPointer != DHCP_OPTION_END)
 1965                 {
 1966                     op.opt_code = *opPointer;
 1967                     opPointer++;
 1968                     op.size = *opPointer;
 1969                     opPointer++;
 1970 
 1971                     if (!requestedOnly || req->paramreqlist[*opPointer])
 1972                     {
 1973                         memcpy(op.value, opPointer, op.size);
 1974                         pvdata(req, &op);
 1975                     }
 1976                     opPointer += op.size;
 1977                 }
 1978             }
 1979 
 1980             op.opt_code = DHCP_OPTION_SERVERID;
 1981             op.size = 4;
 1982             pIP(op.value, network.dhcpConn[req->sockInd].server);
 1983             pvdata(req, &op);
 1984 
 1985             if (!req->opAdded[DHCP_OPTION_IPADDRLEASE])
 1986             {
 1987                 op.opt_code = DHCP_OPTION_IPADDRLEASE;
 1988                 op.size = 4;
 1989                 pUInt(op.value, cfig.lease);
 1990                 pvdata(req, &op);
 1991             }
 1992 
 1993             if (!req->opAdded[DHCP_OPTION_NETMASK])
 1994             {
 1995                 op.opt_code = DHCP_OPTION_NETMASK;
 1996                 op.size = 4;
 1997 
 1998                 if (req->dhcpEntry->rangeInd >= 0)
 1999                     pIP(op.value, cfig.dhcpRanges[req->dhcpEntry->rangeInd].mask);
 2000                 else
 2001                     pIP(op.value, cfig.mask);
 2002 
 2003                 pvdata(req, &op);
 2004             }
 2005 
 2006 /*
 2007             if (!req->opAdded[DHCP_OPTION_ROUTER])
 2008             {
 2009                 op.opt_code = DHCP_OPTION_ROUTER;
 2010                 op.size = 4;
 2011                 pIP(op.value, network.dhcpConn[req->sockInd].server);
 2012                 pvdata(req, &op);
 2013             }
 2014 
 2015             if (req->clientId.opt_code == DHCP_OPTION_CLIENTID)
 2016                 pvdata(req, &req->clientId);
 2017 */
 2018             if (req->subnet.opt_code == DHCP_OPTION_SUBNETSELECTION)
 2019                 pvdata(req, &req->subnet);
 2020 
 2021             if (req->agentOption.opt_code == DHCP_OPTION_RELAYAGENTINFO)
 2022                 pvdata(req, &req->agentOption);
 2023         }
 2024 
 2025         if (req->hostname[0])
 2026             strcpy(req->dhcpEntry->hostname, req->hostname);
 2027         else if (req->dhcpEntry->hostname[0])
 2028             strcpy(req->hostname, req->dhcpEntry->hostname);
 2029         else
 2030         {
 2031             genHostName(req->hostname, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen);
 2032             strcpy(req->dhcpEntry->hostname, req->hostname);
 2033         }
 2034     }
 2035 
 2036     *(req->vp) = DHCP_OPTION_END;
 2037 }
 2038 
 2039 void pvdata(data9 *req, data3 *op)
 2040 {
 2041     //debug("pvdata");
 2042     MYBYTE opsize = op->size;
 2043 
 2044     if (!req->opAdded[op->opt_code] && ((req->vp - (MYBYTE*)&req->dhcpp) + opsize < req->messsize))
 2045     {
 2046         if (op->opt_code == DHCP_OPTION_NEXTSERVER)
 2047             req->dhcpp.header.bp_siaddr = fIP(op->value);
 2048         else if (op->opt_code == DHCP_OPTION_BP_FILE)
 2049         {
 2050             if (opsize <= 128)
 2051                 memcpy(req->dhcpp.header.bp_file, op->value, opsize);
 2052         }
 2053         else if(opsize)
 2054         {
 2055             if (op->opt_code == DHCP_OPTION_IPADDRLEASE)
 2056             {
 2057                 if (!req->lease || req->lease > fUInt(op->value))
 2058                     req->lease = fUInt(op->value);
 2059 
 2060                 if (req->lease >= MY_MAX_TIME)
 2061                     req->lease = UINT_MAX;
 2062 
 2063                 pUInt(op->value, req->lease);
 2064             }
 2065             else if (op->opt_code == DHCP_OPTION_REBINDINGTIME)
 2066                 req->rebind = fUInt(op->value);
 2067             else if (op->opt_code == DHCP_OPTION_HOSTNAME)
 2068             {
 2069                 memcpy(req->hostname, op->value, opsize);
 2070                 req->hostname[opsize] = 0;
 2071                 req->hostname[64] = 0;
 2072 
 2073                 if (char *ptr = strchr(req->hostname, '.'))
 2074                     *ptr = 0;
 2075 
 2076                 opsize = strlen(req->hostname) + 1;
 2077                 memcpy(op->value, req->hostname, opsize);
 2078             }
 2079 
 2080             opsize += 2;
 2081             memcpy(req->vp, op, opsize);
 2082             (req->vp) += opsize;
 2083         }
 2084         req->opAdded[op->opt_code] = true;
 2085     }
 2086 }
 2087 
 2088 void setTempLease(data7 *dhcpEntry)
 2089 {
 2090     if (dhcpEntry && dhcpEntry->ip)
 2091     {
 2092         dhcpEntry->display = false;
 2093         dhcpEntry->local = false;
 2094         dhcpEntry->expiry = t + 20;
 2095         setLeaseExpiry(dhcpEntry);
 2096     }
 2097 }
 2098 
 2099 void setLeaseExpiry(data7 *dhcpEntry, MYDWORD lease)
 2100 {
 2101     //printf("%d=%d\n", t, lease);
 2102     if (dhcpEntry && dhcpEntry->ip)
 2103     {
 2104         if (lease > (MYDWORD)(MY_MAX_TIME - t))
 2105             dhcpEntry->expiry = MY_MAX_TIME;
 2106         else
 2107             dhcpEntry->expiry = t + lease;
 2108 
 2109         setLeaseExpiry(dhcpEntry);
 2110     }
 2111 }
 2112 
 2113 void setLeaseExpiry(data7 *dhcpEntry)
 2114 {
 2115     if (dhcpEntry && dhcpEntry->ip)
 2116     {
 2117         int ind = getIndex(dhcpEntry->rangeInd, dhcpEntry->ip);
 2118 
 2119         if (ind >= 0)
 2120         {
 2121             cfig.dhcpRanges[dhcpEntry->rangeInd].dhcpEntry[ind] = dhcpEntry;
 2122 
 2123             if (cfig.dhcpRanges[dhcpEntry->rangeInd].expiry[ind] < MY_MAX_TIME)
 2124                 cfig.dhcpRanges[dhcpEntry->rangeInd].expiry[ind] = dhcpEntry->expiry;
 2125         }
 2126     }
 2127 }
 2128 
 2129 void lockIP(MYDWORD ip)
 2130 {
 2131     MYDWORD iip = htonl(ip);
 2132 
 2133     for (char rangeInd = 0; rangeInd < cfig.rangeCount; rangeInd++)
 2134     {
 2135         if (iip >= cfig.dhcpRanges[rangeInd].rangeStart && iip <= cfig.dhcpRanges[rangeInd].rangeEnd)
 2136         {
 2137             int ind = iip - cfig.dhcpRanges[rangeInd].rangeStart;
 2138 
 2139             if (cfig.dhcpRanges[rangeInd].expiry[ind] < MY_MAX_TIME)
 2140                 cfig.dhcpRanges[rangeInd].expiry[ind] = MY_MAX_TIME;
 2141 
 2142             break;
 2143         }
 2144     }
 2145 }
 2146 
 2147 void holdIP(MYDWORD ip)
 2148 {
 2149     if (ip)
 2150     {
 2151         MYDWORD iip = htonl(ip);
 2152 
 2153         for (char rangeInd = 0; rangeInd < cfig.rangeCount; rangeInd++)
 2154         {
 2155             if (iip >= cfig.dhcpRanges[rangeInd].rangeStart && iip <= cfig.dhcpRanges[rangeInd].rangeEnd)
 2156             {
 2157                 int ind = iip - cfig.dhcpRanges[rangeInd].rangeStart;
 2158 
 2159                 if (cfig.dhcpRanges[rangeInd].expiry[ind] == 0)
 2160                     cfig.dhcpRanges[rangeInd].expiry[ind] = 1;
 2161 
 2162                 break;
 2163             }
 2164         }
 2165     }
 2166 }
 2167 
 2168 void *sendToken(void *lpParam)
 2169 {
 2170     //debug("Send Token");
 2171     sleep(10);
 2172 
 2173     while (true)
 2174     {
 2175         errno = 0;
 2176 
 2177         sendto(cfig.dhcpReplConn.sock,
 2178                 token.raw,
 2179                 token.bytes,
 2180                 0,
 2181                 (sockaddr*)&token.remote,
 2182                 sizeof(token.remote));
 2183 
 2184 //      errno = WSAGetLastError();
 2185 //
 2186 //      if (!errno && verbatim || cfig.dhcpLogLevel >= 2)
 2187 //      {
 2188 //          sprintf(logBuff, "Token Sent");
 2189 //          logDHCPMess(logBuff, 2);
 2190 //      }
 2191 
 2192         sleep(300);
 2193     }
 2194 
 2195     pthread_exit(NULL);
 2196 }
 2197 
 2198 
 2199 MYDWORD sendRepl(data9 *req)
 2200 {
 2201     char ipBuff[16];
 2202     char logBuff[256];
 2203 
 2204     data3 op;
 2205 
 2206     MYBYTE *opPointer = req->dhcpp.vend_data;
 2207 
 2208     while ((*opPointer) != DHCP_OPTION_END && opPointer < req->vp)
 2209     {
 2210         if ((*opPointer) == DHCP_OPTION_MESSAGETYPE)
 2211         {
 2212             *(opPointer + 2) = DHCP_MESS_INFORM;
 2213             break;
 2214         }
 2215         opPointer = opPointer + *(opPointer + 1) + 2;
 2216     }
 2217 
 2218     if (!req->opAdded[DHCP_OPTION_MESSAGETYPE])
 2219     {
 2220         op.opt_code = DHCP_OPTION_MESSAGETYPE;
 2221         op.size = 1;
 2222         op.value[0] = DHCP_MESS_INFORM;
 2223         pvdata(req, &op);
 2224     }
 2225 
 2226     if (req->hostname[0] && !req->opAdded[DHCP_OPTION_HOSTNAME])
 2227     {
 2228         op.opt_code = DHCP_OPTION_HOSTNAME;
 2229         op.size = strlen(req->hostname) + 1;
 2230         memcpy(op.value, req->hostname, op.size);
 2231         pvdata(req, &op);
 2232     }
 2233 
 2234 //  op.opt_code = DHCP_OPTION_SERIAL;
 2235 //  op.size = 4;
 2236 //  pUInt(op.value, cfig.serial1);
 2237 //  pvdata(req, &op);
 2238 
 2239     *(req->vp) = DHCP_OPTION_END;
 2240     req->vp++;
 2241     req->bytes = req->vp - (MYBYTE*)req->raw;
 2242 
 2243     req->dhcpp.header.bp_op = BOOTP_REQUEST;
 2244     errno = 0;
 2245 
 2246     req->bytes = sendto(cfig.dhcpReplConn.sock,
 2247                         req->raw,
 2248                         req->bytes,
 2249                         0,
 2250                         (sockaddr*)&token.remote,
 2251                         sizeof(token.remote));
 2252 
 2253     //errno = WSAGetLastError();
 2254 
 2255     if (errno || req->bytes <= 0)
 2256     {
 2257         cfig.dhcpRepl = 0;
 2258 
 2259         if (verbatim || cfig.dhcpLogLevel >= 1)
 2260         {
 2261             if (cfig.replication == 1)
 2262                 sprintf(logBuff, "Error %s Sending DHCP Update to Secondary Server", strerror(errno));
 2263             else
 2264                 sprintf(logBuff, "Error %s Sending DHCP Update to Primary Server", strerror(errno));
 2265 
 2266             logDHCPMess(logBuff, 1);
 2267         }
 2268 
 2269         return 0;
 2270     }
 2271     else if (verbatim || cfig.dhcpLogLevel >= 2)
 2272     {
 2273         if (cfig.replication == 1)
 2274             sprintf(logBuff, "DHCP Update for host %s (%s) sent to Secondary Server", req->dhcpEntry->mapname, IP2String(ipBuff, req->dhcpEntry->ip));
 2275         else
 2276             sprintf(logBuff, "DHCP Update for host %s (%s) sent to Primary Server", req->dhcpEntry->mapname, IP2String(ipBuff, req->dhcpEntry->ip));
 2277 
 2278         logDHCPMess(logBuff, 2);
 2279     }
 2280 
 2281     return req->dhcpp.header.bp_yiaddr;
 2282 }
 2283 
 2284 /*
 2285 MYDWORD sendRepl(data7 *dhcpEntry)
 2286 {
 2287     data9 req;
 2288     memset(&req, 0, sizeof(data9));
 2289     req.vp = req.dhcpp.vend_data;
 2290     req.messsize = sizeof(dhcp_packet);
 2291     req.dhcpEntry = dhcpEntry;
 2292 
 2293     req.dhcpp.header.bp_op = BOOTP_REQUEST;
 2294     req.dhcpp.header.bp_xid = t;
 2295     req.dhcpp.header.bp_ciaddr = dhcpEntry->ip;
 2296     req.dhcpp.header.bp_yiaddr = dhcpEntry->ip;
 2297     req.dhcpp.header.bp_hlen = 16;
 2298     getHexValue(req.dhcpp.header.bp_chaddr, req.dhcpEntry->mapname, &(req.dhcpp.header.bp_hlen));
 2299     req.dhcpp.header.bp_magic_num[0] = 99;
 2300     req.dhcpp.header.bp_magic_num[1] = 130;
 2301     req.dhcpp.header.bp_magic_num[2] = 83;
 2302     req.dhcpp.header.bp_magic_num[3] = 99;
 2303     strcpy(req.hostname, dhcpEntry->hostname);
 2304 
 2305     return sendRepl(&req);
 2306 }
 2307 */
 2308 
 2309 void recvRepl(data9 *req)
 2310 {
 2311     char ipbuff[32];
 2312     char logBuff[512];
 2313     cfig.dhcpRepl = t + 650;
 2314 
 2315     MYDWORD ip = req->dhcpp.header.bp_yiaddr ? req->dhcpp.header.bp_yiaddr : req->dhcpp.header.bp_ciaddr;
 2316 
 2317     if (!ip && !req->dhcpp.header.bp_hlen)
 2318     {
 2319 //      if (verbatim || cfig.dhcpLogLevel >= 2)
 2320 //      {
 2321 //          sprintf(logBuff, "Token Received");
 2322 //          logDHCPMess(logBuff, 2);
 2323 //      }
 2324 
 2325         if (cfig.replication == 1)
 2326         {
 2327             errno = 0;
 2328 
 2329             sendto(cfig.dhcpReplConn.sock,
 2330                     token.raw,
 2331                     token.bytes,
 2332                     0,
 2333                     (sockaddr*)&token.remote,
 2334                     sizeof(token.remote));
 2335 
 2336 //          errno = WSAGetLastError();
 2337 //
 2338 //          if (!errno && (verbatim || cfig.dhcpLogLevel >= 2))
 2339 //          {
 2340 //              sprintf(logBuff, "Token Responded");
 2341 //              logDHCPMess(logBuff, 2);
 2342 //          }
 2343         }
 2344 
 2345         return;
 2346     }
 2347 
 2348     char rInd = getRangeInd(ip);
 2349     req->dhcpEntry = findDHCPEntry(req->chaddr);
 2350 
 2351     if (req->dhcpEntry && req->dhcpEntry->ip != ip)
 2352     {
 2353         if (req->dhcpEntry->fixed || rInd < 0)
 2354         {
 2355             if (cfig.replication == 1)
 2356                 sprintf(logBuff, "DHCP Update ignored for %s (%s) from Secondary Server", req->chaddr, IP2String(ipbuff, ip));
 2357             else
 2358                 sprintf(logBuff, "DHCP Update ignored for %s (%s) from Primary Server", req->chaddr, IP2String(ipbuff, ip));
 2359 
 2360             logDHCPMess(logBuff, 1);
 2361             return;
 2362         }
 2363         else if (req->dhcpEntry->rangeInd >= 0)
 2364         {
 2365             int ind  = getIndex(req->dhcpEntry->rangeInd, req->dhcpEntry->ip);
 2366 
 2367             if (ind >= 0)
 2368                 cfig.dhcpRanges[req->dhcpEntry->rangeInd].dhcpEntry[ind] = 0;
 2369         }
 2370     }
 2371 
 2372     if (!req->dhcpEntry && rInd >= 0)
 2373     {
 2374         memset(&lump, 0, sizeof(data71));
 2375         lump.mapname = req->chaddr;
 2376         lump.hostname = req->hostname;
 2377         req->dhcpEntry = createCache(&lump);
 2378 
 2379         if (req->dhcpEntry)
 2380             dhcpCache[req->dhcpEntry->mapname] = req->dhcpEntry;
 2381 /*
 2382         req->dhcpEntry = (data7*)calloc(1, sizeof(data7));
 2383 
 2384         if (!req->dhcpEntry)
 2385         {
 2386             sprintf(logBuff, "Memory Allocation Error");
 2387             logDHCPMess(logBuff, 1);
 2388             return;
 2389         }
 2390 
 2391         req->dhcpEntry->mapname = cloneString(req->chaddr);
 2392 
 2393         if (!req->dhcpEntry->mapname)
 2394         {
 2395             sprintf(logBuff, "Memory Allocation Error");
 2396             free(req->dhcpEntry);
 2397             logDHCPMess(logBuff, 1);
 2398             return;
 2399         }
 2400 */
 2401     }
 2402 
 2403     if (req->dhcpEntry)
 2404     {
 2405         req->dhcpEntry->ip = ip;
 2406         req->dhcpEntry->rangeInd = rInd;
 2407         req->dhcpEntry->display = true;
 2408         req->dhcpEntry->local = false;
 2409 
 2410         MYDWORD hangTime = req->lease;
 2411 
 2412         if (hangTime)
 2413         {
 2414             if (req->rebind > hangTime)
 2415                 hangTime = req->rebind;
 2416         }
 2417         else
 2418             hangTime = UINT_MAX;
 2419 
 2420         setLeaseExpiry(req->dhcpEntry, hangTime);
 2421         strcpy(req->dhcpEntry->hostname, req->hostname);
 2422 
 2423         pthread_t threadId;
 2424         pthread_attr_t attr;
 2425         pthread_attr_init(&attr);
 2426         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 2427         int errcode = pthread_create(&threadId, &attr, updateStateFile, (void*)req->dhcpEntry);
 2428         pthread_attr_destroy(&attr);
 2429 
 2430         if (verbatim || cfig.dhcpLogLevel >= 2)
 2431         {
 2432             if (cfig.replication == 1)
 2433                 sprintf(logBuff, "DHCP Update received for %s (%s) from Secondary Server", req->chaddr, IP2String(ipbuff, ip));
 2434             else
 2435                 sprintf(logBuff, "DHCP Update received for %s (%s) from Primary Server", req->chaddr, IP2String(ipbuff, ip));
 2436 
 2437             logDHCPMess(logBuff, 2);
 2438         }
 2439     }
 2440     else
 2441     {
 2442         if (cfig.replication == 1)
 2443             sprintf(logBuff, "DHCP Update ignored for %s (%s) from Secondary Server", req->chaddr, IP2String(ipbuff, ip));
 2444         else
 2445             sprintf(logBuff, "DHCP Update ignored for %s (%s) from Primary Server", req->chaddr, IP2String(ipbuff, ip));
 2446 
 2447         logDHCPMess(logBuff, 1);
 2448         return;
 2449     }
 2450 }
 2451 
 2452 char getRangeInd(MYDWORD ip)
 2453 {
 2454     if (ip)
 2455     {
 2456         MYDWORD iip = htonl(ip);
 2457 
 2458         for (char k = 0; k < cfig.rangeCount; k++)
 2459             if (iip >= cfig.dhcpRanges[k].rangeStart && iip <= cfig.dhcpRanges[k].rangeEnd)
 2460                 return k;
 2461     }
 2462     return -1;
 2463 }
 2464 
 2465 int getIndex(char rangeInd, MYDWORD ip)
 2466 {
 2467     if (ip && rangeInd >= 0 && rangeInd < cfig.rangeCount)
 2468     {
 2469         MYDWORD iip = htonl(ip);
 2470         if (iip >= cfig.dhcpRanges[rangeInd].rangeStart && iip <= cfig.dhcpRanges[rangeInd].rangeEnd)
 2471             return (iip - cfig.dhcpRanges[rangeInd].rangeStart);
 2472     }
 2473     return -1;
 2474 }
 2475 
 2476 void loadOptions(FILE *f, const char *sectionName, data20 *optionData)
 2477 {
 2478     optionData->ip = 0;
 2479     optionData->mask = 0;
 2480     MYBYTE maxInd = sizeof(opData) / sizeof(data4);
 2481     MYWORD buffsize = sizeof(dhcp_packet) - sizeof(dhcp_header);
 2482     MYBYTE *dp = optionData->options;
 2483     MYBYTE op_specified[256];
 2484 
 2485     memset(op_specified, 0, 256);
 2486     *dp = 0;
 2487     dp++;
 2488 
 2489     char raw[512];
 2490     char name[512];
 2491     char value[512];
 2492     char logBuff[512];
 2493 
 2494     while (readSection(raw, f))
 2495     {
 2496         MYBYTE *ddp = dp;
 2497         MYBYTE hoption[256];
 2498         MYBYTE valSize = sizeof(hoption) - 1;
 2499         MYBYTE opTag = 0;
 2500         MYBYTE opType = 0;
 2501         MYBYTE valType = 0;
 2502         bool tagFound = false;
 2503 
 2504         mySplit(name, value, raw, '=');
 2505 
 2506         //printf("%s=%s\n", name, value);
 2507 
 2508         if (!name[0])
 2509         {
 2510             sprintf(logBuff, "Warning: section [%s] invalid option %s ignored", sectionName, raw);
 2511             logDHCPMess(logBuff, 1);
 2512             continue;
 2513         }
 2514 
 2515         if (!strcasecmp(name, "DHCPRange"))
 2516         {
 2517             if (!strcasecmp(sectionName, RANGESET))
 2518                 addDHCPRange(value);
 2519             else
 2520             {
 2521                 sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, raw);
 2522                 logDHCPMess(logBuff, 1);
 2523             }
 2524             continue;
 2525         }
 2526         else if (!strcasecmp(name, "IP"))
 2527         {
 2528             if (!strcasecmp(sectionName, GLOBALOPTIONS) || !strcasecmp(sectionName, RANGESET))
 2529             {
 2530                 sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, raw);
 2531                 logDHCPMess(logBuff, 1);
 2532             }
 2533             else if (!isIP(value) && strcasecmp(value, "0.0.0.0"))
 2534             {
 2535                 sprintf(logBuff, "Warning: section [%s] option Invalid IP Addr %s option ignored", sectionName, value);
 2536                 logDHCPMess(logBuff, 1);
 2537             }
 2538             else
 2539                 optionData->ip = inet_addr(value);
 2540 
 2541             continue;
 2542         }
 2543         else if (!strcasecmp(name, "FilterMacRange"))
 2544         {
 2545             if (!strcasecmp(sectionName, RANGESET))
 2546                 addMacRange(optionData->rangeSetInd, value);
 2547             else
 2548             {
 2549                 sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, raw);
 2550                 logDHCPMess(logBuff, 1);
 2551             }
 2552             continue;
 2553         }
 2554 
 2555         if (!value[0])
 2556             valType = 9;
 2557         else if (value[0] == '"' && value[strlen(value)-1] == '"')
 2558         {
 2559             valType = 2;
 2560             value[0] = NBSP;
 2561             value[strlen(value) - 1] = NBSP;
 2562             myTrim(value, value);
 2563 
 2564             if (strlen(value) <= UCHAR_MAX)
 2565                 valSize = strlen(value);
 2566             else
 2567             {
 2568                 sprintf(logBuff, "Warning: section [%s] option %s value too big, option ignored", sectionName, raw);
 2569                 logDHCPMess(logBuff, 1);
 2570                 continue;
 2571             }
 2572         }
 2573         else if (strchr(value, ':'))
 2574         {
 2575             valType = 2;
 2576             valSize = sizeof(hoption) - 1;
 2577             char *errorPos = getHexValue(hoption, value, &valSize);
 2578 
 2579             if (errorPos)
 2580             {
 2581                 valType = 1;
 2582                 valSize = strlen(value);
 2583             }
 2584             else
 2585                 memcpy(value, hoption, valSize);
 2586         }
 2587         else if (isInt(value) && atol(value) > USHRT_MAX)
 2588             valType = 4;
 2589         else if (isInt(value) && atoi(value) > UCHAR_MAX)
 2590             valType = 5;
 2591         else if (isInt(value))
 2592             valType = 6;
 2593         else if (strchr(value, '.') || strchr(value, ','))
 2594         {
 2595             valType = 2;
 2596             char buff[1024];
 2597             int numbytes = myTokenize(buff, value, "/,.", true);
 2598 
 2599             if (numbytes > 255)
 2600             {
 2601                 sprintf(logBuff, "Warning: section [%s] option %s, too many bytes, entry ignored", sectionName, raw);
 2602                 logDHCPMess(logBuff, 1);
 2603                 continue;
 2604             }
 2605             else
 2606             {
 2607                 char *ptr = buff;
 2608                 valSize = 0;
 2609 
 2610                 for (; *ptr; ptr = myGetToken(ptr, 1))
 2611                 {
 2612                     //printf("%s:", ptr);
 2613                     if (isInt(ptr) && atoi(ptr) <= UCHAR_MAX)
 2614                     {
 2615                         hoption[valSize] = atoi(ptr);
 2616                         valSize++;
 2617                     }
 2618                     else
 2619                         break;
 2620                 }
 2621 
 2622                 if (!(*ptr))
 2623                     memcpy(value, hoption, valSize);
 2624                 else
 2625                 {
 2626                     valType = 1;
 2627                     valSize = strlen(value);
 2628                 }
 2629             }
 2630         }
 2631         else
 2632         {
 2633             if (strlen(value) <= UCHAR_MAX)
 2634             {
 2635                 valSize = strlen(value);
 2636                 valType = 1;
 2637             }
 2638             else
 2639             {
 2640                 sprintf(logBuff, "Warning: section [%s] option %s value too long, option ignored", sectionName, raw);
 2641                 logDHCPMess(logBuff, 1);
 2642                 continue;
 2643             }
 2644         }
 2645 
 2646         if (!strcasecmp(name, "FilterVendorClass"))
 2647         {
 2648             if (!strcasecmp(sectionName, RANGESET))
 2649                 addVendClass(optionData->rangeSetInd, value, valSize);
 2650             else
 2651             {
 2652                 sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, raw);
 2653                 logDHCPMess(logBuff, 1);
 2654             }
 2655             continue;
 2656         }
 2657         else if (!strcasecmp(name, "FilterUserClass"))
 2658         {
 2659             if (!strcasecmp(sectionName, RANGESET))
 2660                 addUserClass(optionData->rangeSetInd, value, valSize);
 2661             else
 2662             {
 2663                 sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, raw);
 2664                 logDHCPMess(logBuff, 1);
 2665             }
 2666             continue;
 2667         }
 2668         else if (!strcasecmp(name, "FilterSubnetSelection"))
 2669         {
 2670             if (valSize != 4)
 2671             {
 2672                 sprintf(logBuff, "Warning: section [%s] invalid value %s, option ignored", sectionName, raw);
 2673                 logDHCPMess(logBuff, 1);
 2674             }
 2675             else if (!strcasecmp(sectionName, RANGESET))
 2676             {
 2677                 addServer(cfig.rangeSet[optionData->rangeSetInd].subnetIP, MAX_RANGE_FILTERS, fIP(value));
 2678                 cfig.hasFilter = 1;
 2679             }
 2680             else
 2681             {
 2682                 sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, raw);
 2683                 logDHCPMess(logBuff, 1);
 2684             }
 2685             continue;
 2686         }
 2687         else if (!strcasecmp(name, "TargetRelayAgent"))
 2688         {
 2689             if (valSize != 4)
 2690             {
 2691                 sprintf(logBuff, "Warning: section [%s] invalid value %s, option ignored", sectionName, raw);
 2692                 logDHCPMess(logBuff, 1);
 2693             }
 2694             else if (!strcasecmp(sectionName, RANGESET))
 2695             {
 2696                 cfig.rangeSet[optionData->rangeSetInd].targetIP = fIP(value);
 2697                 //printf("TARGET IP %s set RangeSetInd  %d\n", IP2String(ipbuff, cfig.rangeSet[optionData->rangeSetInd].targetIP), optionData->rangeSetInd);
 2698             }
 2699             else
 2700             {
 2701                 sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, raw);
 2702                 logDHCPMess(logBuff, 1);
 2703             }
 2704             continue;
 2705         }
 2706 
 2707         opTag = 0;
 2708 
 2709         if (isInt(name))
 2710         {
 2711             if (atoi(name) < 1 || atoi(name) >= 254)
 2712             {
 2713                 sprintf(logBuff, "Warning: section [%s] invalid option %s, ignored", sectionName, raw);
 2714                 logDHCPMess(logBuff, 1);
 2715                 continue;
 2716             }
 2717 
 2718             opTag = atoi(name);
 2719             opType = 0;
 2720         }
 2721 
 2722         for (MYBYTE i = 0; i < maxInd; i++)
 2723             if (!strcasecmp(name, opData[i].opName) || (opTag && opTag == opData[i].opTag))
 2724             {
 2725                 opTag = opData[i].opTag;
 2726                 opType = opData[i].opType;
 2727                 tagFound = true;
 2728                 break;
 2729             }
 2730 
 2731         if (!opTag)
 2732         {
 2733             sprintf(logBuff, "Warning: section [%s] invalid option %s, ignored", sectionName, raw);
 2734             logDHCPMess(logBuff, 1);
 2735             continue;
 2736         }
 2737 
 2738         if (!opType)
 2739             opType = valType;
 2740 
 2741         //sprintf(logBuff, "Tag %i ValType %i opType %i value=%s size=%u", opTag, valType, opType, value, valSize);
 2742         //logDHCPMess(logBuff, 1);
 2743 
 2744         if (op_specified[opTag])
 2745         {
 2746             sprintf(logBuff, "Warning: section [%s] duplicate option %s, ignored", sectionName, raw);
 2747             logDHCPMess(logBuff, 1);
 2748             continue;
 2749         }
 2750 
 2751         //printf("Option=%u opType=%u valueType=%u valSize=%u\n", opTag, opType, valType, valSize);
 2752 
 2753         op_specified[opTag] = true;
 2754 
 2755         if (valType == 9)
 2756         {
 2757             if (buffsize > 2)
 2758             {
 2759                 *dp = opTag;
 2760                 dp++;
 2761                 *dp = 0;
 2762                 dp++;
 2763                 buffsize -= 2;
 2764             }
 2765             else
 2766             {
 2767                 sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, raw);
 2768                 logDHCPMess(logBuff, 1);
 2769             }
 2770             continue;
 2771         }
 2772 
 2773         switch (opType)
 2774         {
 2775             case 1:
 2776             {
 2777                 value[valSize] = 0;
 2778                 valSize++;
 2779 
 2780                 if (valType != 1 && valType != 2)
 2781                 {
 2782                     sprintf(logBuff, "Warning: section [%s] option %s, need string value, option ignored", sectionName, raw);
 2783                     logDHCPMess(logBuff, 1);
 2784                 }
 2785                 else if (!strcasecmp(serviceName, "DUALServer") && opTag == DHCP_OPTION_DOMAINNAME)
 2786                 {
 2787                     sprintf(logBuff, "Warning: section [%s] option %u should be under [DOMAIN_NAME], ignored", sectionName, opTag);
 2788                     logDHCPMess(logBuff, 1);
 2789                     continue;
 2790                 }
 2791                 else if (buffsize > valSize + 2)
 2792                 {
 2793                     *dp = opTag;
 2794                     dp++;
 2795                     *dp = valSize;
 2796                     dp++;
 2797                     memcpy(dp, value, valSize);
 2798                     dp += valSize;
 2799                     buffsize -= (valSize + 2);
 2800                 }
 2801                 else
 2802                 {
 2803                     sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, raw);
 2804                     logDHCPMess(logBuff, 1);
 2805                 }
 2806             }
 2807             break;
 2808 
 2809             case 3:
 2810             case 8:
 2811             {
 2812                 if (valType == 2)
 2813                 {
 2814                     if (opType == 3 && valSize % 4)
 2815                     {
 2816                         sprintf(logBuff, "Warning: section [%s] option %s, missing/extra bytes/octates in IP, option ignored", sectionName, raw);
 2817                         logDHCPMess(logBuff, 1);
 2818                         continue;
 2819                     }
 2820                     else if (opType == 8 && valSize % 8)
 2821                     {
 2822                         sprintf(logBuff, "Warning: section [%s] option %s, some values not in IP/Mask form, option ignored", sectionName, raw);
 2823                         logDHCPMess(logBuff, 1);
 2824                         continue;
 2825                     }
 2826 
 2827                     if (opTag == DHCP_OPTION_NETMASK)
 2828                     {
 2829                         if (valSize != 4 || !checkMask(fIP(value)))
 2830                         {
 2831                             sprintf(logBuff, "Warning: section [%s] Invalid subnetmask %s, option ignored", sectionName, raw);
 2832                             logDHCPMess(logBuff, 1);
 2833                             continue;
 2834                         }
 2835                         else
 2836                             optionData->mask = fIP(value);
 2837                     }
 2838 
 2839                     if (buffsize > valSize + 2)
 2840                     {
 2841                         *dp = opTag;
 2842                         dp++;
 2843                         *dp = valSize;
 2844                         dp++;
 2845                         memcpy(dp, value, valSize);
 2846                         dp += valSize;
 2847                         buffsize -= (valSize + 2);
 2848                     }
 2849                     else
 2850                     {
 2851                         sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, raw);
 2852                         logDHCPMess(logBuff, 1);
 2853                     }
 2854                 }
 2855                 else
 2856                 {
 2857                     sprintf(logBuff, "Warning: section [%s] option %s, Invalid value, should be one or more IP/4 Bytes", sectionName, raw);
 2858                     logDHCPMess(logBuff, 1);
 2859                 }
 2860             }
 2861             break;
 2862 
 2863             case 4:
 2864             {
 2865                 MYDWORD j;
 2866 
 2867                 if (valType == 2 && valSize == 4)
 2868                     j = fUInt(value);
 2869                 else if (valType >= 4 && valType <= 6)
 2870                     j = atol(value);
 2871                 else
 2872                 {
 2873                     sprintf(logBuff, "Warning: section [%s] option %s, value should be integer between 0 & %u or 4 bytes, option ignored", sectionName, name, UINT_MAX);
 2874                     logDHCPMess(logBuff, 1);
 2875                     continue;
 2876                 }
 2877 
 2878                 if (opTag == DHCP_OPTION_IPADDRLEASE)
 2879                 {
 2880                     if (j == 0)
 2881                         j = UINT_MAX;
 2882 
 2883                     if (!strcasecmp(serviceName, "DUALServer"))
 2884                     {
 2885                         if (!strcasecmp(sectionName, GLOBALOPTIONS))
 2886                         {
 2887                             sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, please set it in [TIMINGS] section", sectionName, raw);
 2888                             logDHCPMess(logBuff, 1);
 2889                             continue;
 2890                         }
 2891                         else if (j < cfig.lease)
 2892                         {
 2893                             sprintf(logBuff, "Warning: section [%s] option %s value should be more then %u (Default Lease), ignored", sectionName, name, cfig.lease);
 2894                             logDHCPMess(logBuff, 1);
 2895                             continue;
 2896                         }
 2897                     }
 2898                     else if (!strcasecmp(serviceName, "OpenDHCPServer") && !strcasecmp(sectionName, GLOBALOPTIONS))
 2899                         cfig.lease = j;
 2900                 }
 2901 
 2902                 if (buffsize > 6)
 2903                 {
 2904                     *dp = opTag;
 2905                     dp++;
 2906                     *dp = 4;
 2907                     dp++;
 2908                     dp += pUInt(dp, j);
 2909                     buffsize -= 6;
 2910                     //printf("%s=%u=%u\n",opData[op_index].opName,opData[op_index].opType,htonl(j));
 2911                 }
 2912                 else
 2913                 {
 2914                     sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, raw);
 2915                     logDHCPMess(logBuff, 1);
 2916                 }
 2917             }
 2918             break;
 2919 
 2920             case 5:
 2921             {
 2922                 MYWORD j;
 2923 
 2924                 if (valType == 2 && valSize == 2)
 2925                     j = fUShort(value);
 2926                 else if (valType == 5 || valType == 6)
 2927                     j = atol(value);
 2928                 else
 2929                 {
 2930                     sprintf(logBuff, "Warning: section [%s] option %s, value should be between 0 & %u or 2 bytes, option ignored", sectionName, name, USHRT_MAX);
 2931                     logDHCPMess(logBuff, 1);
 2932                     continue;
 2933                 }
 2934 
 2935                 if (buffsize > 4)
 2936                 {
 2937                     *dp = opTag;
 2938                     dp++;
 2939                     *dp = 2;
 2940                     dp++;
 2941                     dp += pUShort(dp, j);
 2942                     buffsize -= 4;
 2943                 }
 2944                 else
 2945                 {
 2946                     sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, raw);
 2947                     logDHCPMess(logBuff, 1);
 2948                 }
 2949             }
 2950             break;
 2951 
 2952             case 6:
 2953             {
 2954                 MYBYTE j;
 2955 
 2956                 if (valType == 2 && valSize == 1)
 2957                     j = *value;
 2958                 else if (valType == 6)
 2959                     j = atol(value);
 2960                 else
 2961                 {
 2962                     sprintf(logBuff, "Warning: section [%s] option %s, value should be between 0 & %u or single byte, option ignored", sectionName, name, UCHAR_MAX);
 2963                     logDHCPMess(logBuff, 1);
 2964                     continue;
 2965                 }
 2966 
 2967                 if (buffsize > 3)
 2968                 {
 2969                     *dp = opTag;
 2970                     dp++;
 2971                     *dp = 1;
 2972                     dp++;
 2973                     *dp = j;
 2974                     dp++;
 2975                     buffsize -= 3;
 2976                 }
 2977                 else
 2978                 {
 2979                     sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, raw);
 2980                     logDHCPMess(logBuff, 1);
 2981                 }
 2982             }
 2983             break;
 2984 
 2985             case 7:
 2986             {
 2987                 MYBYTE j;
 2988 
 2989                 if (valType == 2 && valSize == 1 && *value < 2)
 2990                     j = *value;
 2991                 else if (valType == 1 && (!strcasecmp(value, "yes") || !strcasecmp(value, "on") || !strcasecmp(value, "true")))
 2992                     j = 1;
 2993                 else if (valType == 1 && (!strcasecmp(value, "no") || !strcasecmp(value, "off") || !strcasecmp(value, "false")))
 2994                     j = 0;
 2995                 else if (valType == 6 && atoi(value) < 2)
 2996                     j = atoi(value);
 2997                 else
 2998                 {
 2999                     sprintf(logBuff, "Warning: section [%s] option %s, value should be yes/on/true/1 or no/off/false/0, option ignored", sectionName, raw);
 3000                     logDHCPMess(logBuff, 1);
 3001                     continue;
 3002                 }
 3003 
 3004                 if (buffsize > 3)
 3005                 {
 3006                     *dp = opTag;
 3007                     dp++;
 3008                     *dp = 1;
 3009                     dp++;
 3010                     *dp = j;
 3011                     dp++;
 3012                     buffsize -= 3;
 3013                 }
 3014                 else
 3015                 {
 3016                     sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, raw);
 3017                     logDHCPMess(logBuff, 1);
 3018                 }
 3019             }
 3020             break;
 3021 
 3022             default:
 3023             {
 3024                 if (valType == 6)
 3025                 {
 3026                     valType = 2;
 3027                     valSize = 1;
 3028                     *value = atoi(value);
 3029                 }
 3030 
 3031                 if (opType == 2 && valType != 2)
 3032                 {
 3033                     sprintf(logBuff, "Warning: section [%s] option %s, value should be comma separated bytes or hex string, option ignored", sectionName, raw);
 3034                     logDHCPMess(logBuff, 1);
 3035                     continue;
 3036                 }
 3037                 else if (buffsize > valSize + 2)
 3038                 {
 3039                     *dp = opTag;
 3040                     dp++;
 3041                     *dp = valSize;
 3042                     dp++;
 3043                     memcpy(dp, value, valSize);
 3044                     dp += valSize;
 3045                     buffsize -= (valSize + 2);
 3046                 }
 3047                 else
 3048                 {
 3049                     sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, raw);
 3050                     logDHCPMess(logBuff, 1);
 3051                 }
 3052             }
 3053             break;
 3054         }
 3055 
 3056         //printf("%s Option=%u opType=%u valType=%u  valSize=%u\n", raw, opTag, opType, valType, valSize);
 3057         //printf("%s %s\n", name, hex2String(tempbuff, ddp, valSize+2, ':'));
 3058     }
 3059 
 3060     //printf("%s=%s\n", sectionName, optionData->vendClass);
 3061 
 3062     *dp = DHCP_OPTION_END;
 3063     dp++;
 3064     optionData->optionSize = (dp - optionData->options);
 3065     //printf("section=%s buffersize = %u option size=%u\n", sectionName, buffsize, optionData->optionSize);
 3066 }
 3067 
 3068 void lockOptions(FILE *f)
 3069 {
 3070     char raw[512];
 3071     char name[512];
 3072     char value[512];
 3073 
 3074     while (readSection(raw, f))
 3075     {
 3076         mySplit(name, value, raw, '=');
 3077 
 3078         if (!name[0] || !value[0])
 3079             continue;
 3080 
 3081         int op_index;
 3082         MYBYTE n = sizeof(opData) / sizeof(data4);
 3083 
 3084         for (op_index = 0; op_index < n; op_index++)
 3085             if (!strcasecmp(name, opData[op_index].opName) || (opData[op_index].opTag && atoi(name) == opData[op_index].opTag))
 3086                 break;
 3087 
 3088         if (op_index >= n)
 3089             continue;
 3090 
 3091         if (opData[op_index].opType == 3)
 3092         {
 3093             if (myTokenize(value, value, "/,.", true))
 3094             {
 3095                 char *ptr = value;
 3096                 char hoption[256];
 3097                 MYBYTE valueSize = 0;
 3098 
 3099                 for (; *ptr; ptr = myGetToken(ptr, 1))
 3100                 {
 3101                     if (valueSize >= UCHAR_MAX)
 3102                         break;
 3103                     else if (isInt(ptr) && atoi(ptr) <= UCHAR_MAX)
 3104                     {
 3105                         hoption[valueSize] = atoi(ptr);
 3106                         valueSize++;
 3107                     }
 3108                     else
 3109                         break;
 3110                 }
 3111 
 3112                 if (*ptr)
 3113                     continue;
 3114 
 3115                 if (valueSize % 4)
 3116                     continue;
 3117 
 3118                 for (MYBYTE i = 0; i < valueSize; i += 4)
 3119                 {
 3120                     MYDWORD ip = *((MYDWORD*)&(hoption[i]));
 3121 
 3122                     if (ip != INADDR_ANY && ip != INADDR_NONE)
 3123                         lockIP(ip);
 3124                 }
 3125             }
 3126         }
 3127     }
 3128 }
 3129 
 3130 void addDHCPRange(char *dp)
 3131 {
 3132     char logBuff[256];
 3133 
 3134     MYDWORD rs = 0;
 3135     MYDWORD re = 0;
 3136     char name[512];
 3137     char value[512];
 3138     mySplit(name, value, dp, '-');
 3139 
 3140     if (isIP(name) && isIP(value))
 3141     {
 3142         rs = htonl(inet_addr(name));
 3143         re = htonl(inet_addr(value));
 3144 
 3145         if (rs && re && rs <= re)
 3146         {
 3147             data13 *range;
 3148             MYBYTE m = 0;
 3149 
 3150             for (; m < MAX_DHCP_RANGES && cfig.dhcpRanges[m].rangeStart; m++)
 3151             {
 3152                 range = &cfig.dhcpRanges[m];
 3153 
 3154                 if ((rs >= range->rangeStart && rs <= range->rangeEnd)
 3155                         || (re >= range->rangeStart && re <= range->rangeEnd)
 3156                         || (range->rangeStart >= rs && range->rangeStart <= re)
 3157                         || (range->rangeEnd >= rs && range->rangeEnd <= re))
 3158                 {
 3159                     sprintf(logBuff, "Warning: DHCP Range %s overlaps with another range, ignored", dp);
 3160                     logDHCPMess(logBuff, 1);
 3161                     return;
 3162                 }
 3163             }
 3164 
 3165             if (m < MAX_DHCP_RANGES)
 3166             {
 3167                 cfig.dhcpSize += (re - rs + 1);
 3168                 range = &cfig.dhcpRanges[m];
 3169                 range->rangeStart = rs;
 3170                 range->rangeEnd = re;
 3171                 range->expiry = (time_t*)calloc((re - rs + 1), sizeof(time_t));
 3172                 range->dhcpEntry = (data7**)calloc((re - rs + 1), sizeof(data7*));
 3173 
 3174                 if (!range->expiry || !range->dhcpEntry)
 3175                 {
 3176                     if (range->expiry)
 3177                         free(range->expiry);
 3178 
 3179                     if (range->dhcpEntry)
 3180                         free(range->dhcpEntry);
 3181 
 3182                     sprintf(logBuff, "DHCP Ranges Load, Memory Allocation Error");
 3183                     logDHCPMess(logBuff, 1);
 3184                     return;
 3185                 }
 3186             }
 3187         }
 3188         else
 3189         {
 3190             sprintf(logBuff, "Section [%s] Invalid DHCP range %s in ini file, ignored", RANGESET, dp);
 3191             logDHCPMess(logBuff, 1);
 3192         }
 3193     }
 3194     else
 3195     {
 3196         sprintf(logBuff, "Section [%s] Invalid DHCP range %s in ini file, ignored", RANGESET, dp);
 3197         logDHCPMess(logBuff, 1);
 3198     }
 3199 }
 3200 
 3201 void addVendClass(MYBYTE rangeSetInd, char *vendClass, MYBYTE vendClassSize)
 3202 {
 3203     char logBuff[256];
 3204 
 3205     data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
 3206 
 3207     MYBYTE i = 0;
 3208 
 3209     for (; i <= MAX_RANGE_FILTERS && rangeSet->vendClassSize[i]; i++);
 3210 
 3211     if (i >= MAX_RANGE_FILTERS || !vendClassSize)
 3212         return;
 3213 
 3214     rangeSet->vendClass[i] = (MYBYTE*)calloc(vendClassSize, 1);
 3215 
 3216     if(!rangeSet->vendClass[i])
 3217     {
 3218         sprintf(logBuff, "Vendor Class Load, Memory Allocation Error");
 3219         logDHCPMess(logBuff, 1);
 3220     }
 3221     else
 3222     {
 3223         cfig.hasFilter = true;
 3224         rangeSet->vendClassSize[i] = vendClassSize;
 3225         memcpy(rangeSet->vendClass[i], vendClass, vendClassSize);
 3226         //printf("Loaded Vendor Class %s Size=%i rangeSetInd=%i Ind=%i\n", rangeSet->vendClass[i], rangeSet->vendClassSize[i], rangeSetInd, i);
 3227         //printf("Loaded Vendor Class %s Size=%i rangeSetInd=%i Ind=%i\n", hex2String(tempbuff, rangeSet->vendClass[i], rangeSet->vendClassSize[i], ':'), rangeSet->vendClassSize[i], rangeSetInd, i);
 3228     }
 3229 }
 3230 
 3231 void addUserClass(MYBYTE rangeSetInd, char *userClass, MYBYTE userClassSize)
 3232 {
 3233     char logBuff[256];
 3234 
 3235     data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
 3236 
 3237     MYBYTE i = 0;
 3238 
 3239     for (; i <= MAX_RANGE_FILTERS && rangeSet->userClassSize[i]; i++);
 3240 
 3241     if (i >= MAX_RANGE_FILTERS || !userClassSize)
 3242         return;
 3243 
 3244     rangeSet->userClass[i] = (MYBYTE*)calloc(userClassSize, 1);
 3245 
 3246     if(!rangeSet->userClass[i])
 3247     {
 3248         sprintf(logBuff, "Vendor Class Load, Memory Allocation Error");
 3249         logDHCPMess(logBuff, 1);
 3250     }
 3251     else
 3252     {
 3253         cfig.hasFilter = true;
 3254         rangeSet->userClassSize[i] = userClassSize;
 3255         memcpy(rangeSet->userClass[i], userClass, userClassSize);
 3256         //printf("Loaded User Class %s Size=%i rangeSetInd=%i Ind=%i\n", hex2String(tempbuff, rangeSet->userClass[i], rangeSet->userClassSize[i], ':'), rangeSet->vendClassSize[i], rangeSetInd, i);
 3257     }
 3258 }
 3259 
 3260 void addMacRange(MYBYTE rangeSetInd, char *macRange)
 3261 {
 3262     char logBuff[256];
 3263 
 3264     if (macRange[0])
 3265     {
 3266         data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
 3267 
 3268         MYBYTE i = 0;
 3269 
 3270         for (; i <= MAX_RANGE_FILTERS && rangeSet->macSize[i]; i++);
 3271 
 3272         if (i >= MAX_RANGE_FILTERS)
 3273             return;
 3274 
 3275         char name[256];
 3276         char value[256];
 3277 
 3278         mySplit(name, value, macRange, '-');
 3279 
 3280         //printf("%s=%s\n", name, value);
 3281 
 3282         if(!name[0] || !value[0])
 3283         {
 3284             sprintf(logBuff, "Section [%s], invalid Filter_Mac_Range %s, ignored", RANGESET, macRange);
 3285             logDHCPMess(logBuff, 1);
 3286         }
 3287         else
 3288         {
 3289             MYBYTE macSize1 = 16;
 3290             MYBYTE macSize2 = 16;
 3291             MYBYTE *macStart = (MYBYTE*)calloc(1, macSize1);
 3292             MYBYTE *macEnd = (MYBYTE*)calloc(1, macSize2);
 3293 
 3294             if(!macStart || !macEnd)
 3295             {
 3296                 sprintf(logBuff, "DHCP Range Load, Memory Allocation Error");
 3297                 logDHCPMess(logBuff, 1);
 3298             }
 3299             else if (getHexValue(macStart, name, &macSize1) || getHexValue(macEnd, value, &macSize2))
 3300             {
 3301                 sprintf(logBuff, "Section [%s], Invalid character in Filter_Mac_Range %s", RANGESET, macRange);
 3302                 logDHCPMess(logBuff, 1);
 3303                 free(macStart);
 3304                 free(macEnd);
 3305             }
 3306             else if (memcmp(macStart, macEnd, 16) > 0)
 3307             {
 3308                 sprintf(logBuff, "Section [%s], Invalid Filter_Mac_Range %s, (higher bound specified on left), ignored", RANGESET, macRange);
 3309                 logDHCPMess(logBuff, 1);
 3310                 free(macStart);
 3311                 free(macEnd);
 3312             }
 3313             else if (macSize1 != macSize2)
 3314             {
 3315                 sprintf(logBuff, "Section [%s], Invalid Filter_Mac_Range %s, (start/end size mismatched), ignored", RANGESET, macRange);
 3316                 logDHCPMess(logBuff, 1);
 3317                 free(macStart);
 3318                 free(macEnd);
 3319             }
 3320             else
 3321             {
 3322                 cfig.hasFilter = true;
 3323                 rangeSet->macSize[i] = macSize1;
 3324                 rangeSet->macStart[i] = macStart;
 3325                 rangeSet->macEnd[i] = macEnd;
 3326                 //printf("Mac Loaded, Size=%i Start=%s rangeSetInd=%i Ind=%i\n", rangeSet->macSize[i], hex2String(tempbuff, rangeSet->macStart[i], rangeSet->macSize[i]), rangeSetInd, i);
 3327             }
 3328         }
 3329     }
 3330 }
 3331 
 3332 void loadDHCP()
 3333 {
 3334     char ipbuff[32];
 3335     char logBuff[512];
 3336     data7 *dhcpEntry = NULL;
 3337     data8 dhcpData;
 3338     char mapname[64];
 3339     FILE *f = NULL;
 3340     FILE *ff = NULL;
 3341 
 3342     if (f = openSection(GLOBALOPTIONS, 1))
 3343     {
 3344         data20 optionData;
 3345         loadOptions(f, GLOBALOPTIONS, &optionData);
 3346         cfig.options = (MYBYTE*)calloc(1, optionData.optionSize);
 3347         memcpy(cfig.options, optionData.options, optionData.optionSize);
 3348         cfig.mask = optionData.mask;
 3349     }
 3350 
 3351     if (!cfig.mask)
 3352         cfig.mask = inet_addr("255.255.255.0");
 3353 
 3354     for (MYBYTE i = 1; i <= MAX_RANGE_SETS ; i++)
 3355     {
 3356         if (f = openSection(RANGESET, i))
 3357         {
 3358             MYBYTE m = cfig.rangeCount;
 3359             data20 optionData;
 3360             optionData.rangeSetInd = i - 1;
 3361             loadOptions(f, RANGESET, &optionData);
 3362             MYBYTE *options = NULL;
 3363             cfig.rangeSet[optionData.rangeSetInd].active = true;
 3364 
 3365             if (optionData.optionSize > 3)
 3366             {
 3367                 options = (MYBYTE*)calloc(1, optionData.optionSize);
 3368                 memcpy(options, optionData.options, optionData.optionSize);
 3369             }
 3370 
 3371             for (; m < MAX_DHCP_RANGES && cfig.dhcpRanges[m].rangeStart; m++)
 3372             {
 3373                 cfig.dhcpRanges[m].rangeSetInd = optionData.rangeSetInd;
 3374                 cfig.dhcpRanges[m].options = options;
 3375                 cfig.dhcpRanges[m].mask = optionData.mask;
 3376             }
 3377             cfig.rangeCount = m;
 3378         }
 3379         else
 3380             break;
 3381     }
 3382 
 3383     //printf("%s\n", IP2String(ipbuff, cfig.mask));
 3384 
 3385     for (char rangeInd = 0; rangeInd < cfig.rangeCount; rangeInd++)
 3386     {
 3387         if (!cfig.dhcpRanges[rangeInd].mask)
 3388             cfig.dhcpRanges[rangeInd].mask = cfig.mask;
 3389 
 3390         for (MYDWORD iip = cfig.dhcpRanges[rangeInd].rangeStart; iip <= cfig.dhcpRanges[rangeInd].rangeEnd; iip++)
 3391         {
 3392             MYDWORD ip = htonl(iip);
 3393 
 3394             if ((cfig.dhcpRanges[rangeInd].mask | (~ip)) == UINT_MAX || (cfig.dhcpRanges[rangeInd].mask | ip) == UINT_MAX)
 3395                 cfig.dhcpRanges[rangeInd].expiry[iip - cfig.dhcpRanges[rangeInd].rangeStart] = MY_MAX_TIME;
 3396         }
 3397     }
 3398 
 3399     if (f = openSection(GLOBALOPTIONS, 1))
 3400         lockOptions(f);
 3401 
 3402     for (MYBYTE i = 1; i <= MAX_RANGE_SETS ;i++)
 3403     {
 3404         if (f = openSection(RANGESET, i))
 3405             lockOptions(f);
 3406         else
 3407             break;
 3408     }
 3409 
 3410     ff = fopen(iniFile, "rt");
 3411 
 3412     if (ff)
 3413     {
 3414         char sectionName[512];
 3415 
 3416         while (fgets(sectionName, 510, ff))
 3417         {
 3418             if (*sectionName == '[')
 3419             {
 3420                 char *secend = strchr(sectionName, ']');
 3421 
 3422                 if (secend)
 3423                 {
 3424                     *secend = 0;
 3425                     sectionName[0] = NBSP;
 3426                     myTrim(sectionName, sectionName);
 3427                 }
 3428                 else
 3429                     continue;
 3430             }
 3431             else
 3432                 continue;
 3433 
 3434             if (!strchr(sectionName, ':'))
 3435                 continue;
 3436 
 3437             //printf("%s\n", sectionName);
 3438 
 3439             MYBYTE hexValue[UCHAR_MAX];
 3440             MYBYTE hexValueSize = sizeof(hexValue);
 3441             data20 optionData;
 3442 
 3443             if (strlen(sectionName) <= 48 && !getHexValue(hexValue, sectionName, &hexValueSize))
 3444             {
 3445                 if (hexValueSize <= 16)
 3446                 {
 3447                     dhcpEntry = findDHCPEntry(hex2String(mapname, hexValue, hexValueSize));
 3448 
 3449                     if (!dhcpEntry)
 3450                     {
 3451                         if (f = openSection(sectionName, 1))
 3452                             loadOptions(f, sectionName, &optionData);
 3453                         if (f = openSection(sectionName, 1))
 3454                             lockOptions(f);
 3455 
 3456                         dhcpMap::iterator p = dhcpCache.begin();
 3457 
 3458                         for (; p != dhcpCache.end(); p++)
 3459                         {
 3460                             if (p->second && p->second->ip && p->second->ip == optionData.ip)
 3461                                 break;
 3462                         }
 3463 
 3464                         if (p == dhcpCache.end())
 3465                         {
 3466                             memset(&lump, 0, sizeof(data71));
 3467                             lump.mapname = mapname;
 3468                             lump.optionSize = optionData.optionSize;
 3469                             lump.options = optionData.options;
 3470                             dhcpEntry = createCache(&lump);
 3471 
 3472                             if (!dhcpEntry)
 3473                                 return;
 3474 
 3475                             dhcpEntry->ip = optionData.ip;
 3476                             dhcpEntry->rangeInd = getRangeInd(optionData.ip);
 3477                             dhcpEntry->fixed = 1;
 3478                             dhcpEntry->expiry = 0;
 3479                             dhcpCache[dhcpEntry->mapname] = dhcpEntry;
 3480                             setLeaseExpiry(dhcpEntry);
 3481                             lockIP(optionData.ip);
 3482                             //printf("%s=%s=%s size=%u %u\n", mapname, dhcpEntry->mapname, IP2String(ipbuff, optionData.ip), optionData.optionSize, dhcpEntry->options);
 3483                         }
 3484                         else
 3485                         {
 3486                             sprintf(logBuff, "Static DHCP Host [%s] Duplicate IP Address %s, Entry ignored", sectionName, IP2String(ipbuff, optionData.ip));
 3487                             logDHCPMess(logBuff, 1);
 3488                         }
 3489                     }
 3490                     else
 3491                     {
 3492                         sprintf(logBuff, "Duplicate Static DHCP Host [%s] ignored", sectionName);
 3493                         logDHCPMess(logBuff, 1);
 3494                     }
 3495                 }
 3496                 else
 3497                 {
 3498                     sprintf(logBuff, "Invalid Static DHCP Host MAC Addr size, ignored", sectionName);
 3499                     logDHCPMess(logBuff, 1);
 3500                 }
 3501             }
 3502             else
 3503             {
 3504                 sprintf(logBuff, "Invalid Static DHCP Host MAC Addr [%s] ignored", sectionName);
 3505                 logDHCPMess(logBuff, 1);
 3506             }
 3507 
 3508             if (!optionData.ip)
 3509             {
 3510                 sprintf(logBuff, "Warning: No IP Address for DHCP Static Host %s specified", sectionName);
 3511                 logDHCPMess(logBuff, 1);
 3512             }
 3513         }
 3514 
 3515         fclose(ff);
 3516     }
 3517 
 3518     f = fopen(leaFile, "rb");
 3519 
 3520     if (f)
 3521     {
 3522         while (fread(&dhcpData, sizeof(data8), 1, f))
 3523         {
 3524             char rangeInd = -1;
 3525             int ind = -1;
 3526             //sprintf(logBuff, "Loading %s=%s", dhcpData.hostname, IP2String(ipbuff, dhcpData.ip));
 3527             //logDHCPMess(logBuff, 1);
 3528 
 3529             if (dhcpData.expiry > (t - 31*24*3600) && dhcpData.bp_hlen <= 16 && !findServer(network.allServers, MAX_SERVERS, dhcpData.ip))
 3530             {
 3531                 hex2String(mapname, dhcpData.bp_chaddr, dhcpData.bp_hlen);
 3532 
 3533                 dhcpMap::iterator p = dhcpCache.begin();
 3534 
 3535                 for (; p != dhcpCache.end(); p++)
 3536                 {
 3537                     dhcpEntry = p->second;
 3538 
 3539                     if (!dhcpEntry || (!strcasecmp(mapname, dhcpEntry->mapname) || dhcpEntry->ip == dhcpData.ip))
 3540                         break;
 3541                 }
 3542 
 3543                 if ((p != dhcpCache.end()) && (strcasecmp(mapname, dhcpEntry->mapname) || dhcpEntry->ip != dhcpData.ip))
 3544                     continue;
 3545 
 3546                 dhcpEntry = findDHCPEntry(mapname);
 3547                 rangeInd = getRangeInd(dhcpData.ip);
 3548 
 3549                 if(!dhcpEntry && rangeInd >= 0)
 3550                 {
 3551                     memset(&lump, 0, sizeof(data71));
 3552                     lump.mapname = mapname;
 3553                     dhcpEntry = createCache(&lump);
 3554                 }
 3555 
 3556                 if (dhcpEntry)
 3557                 {
 3558                     dhcpCache[dhcpEntry->mapname] = dhcpEntry;
 3559                     dhcpEntry->subnetFlg = dhcpData.subnetFlg;
 3560                     dhcpEntry->ip = dhcpData.ip;
 3561                     dhcpEntry->rangeInd = rangeInd;
 3562                     dhcpEntry->expiry = dhcpData.expiry;
 3563                     dhcpEntry->local = dhcpData.local;
 3564                     dhcpEntry->display = true;
 3565                     strcpy(dhcpEntry->hostname, dhcpData.hostname);
 3566                     setLeaseExpiry(dhcpEntry);
 3567 
 3568                     //printf("Loaded %s=%s\n", dhcpData.hostname, IP2String(ipbuff, dhcpData.ip));
 3569                 }
 3570             }
 3571         }
 3572 
 3573         fclose(f);
 3574     }
 3575 
 3576     f = fopen(leaFile, "wb");
 3577     fclose(f);
 3578     f = fopen(leaFile, "rb+");
 3579 
 3580     if (f)
 3581     {
 3582         dhcpMap::iterator p = dhcpCache.begin();
 3583 
 3584         for (; p != dhcpCache.end(); p++)
 3585         {
 3586             if ((dhcpEntry = p->second)  && dhcpEntry->expiry > (t - 31*24*3600))
 3587             {
 3588                 memset(&dhcpData, 0, sizeof(data8));
 3589                 MYBYTE bp_hlen = 16;
 3590                 getHexValue(dhcpData.bp_chaddr, dhcpEntry->mapname, &bp_hlen);
 3591                 dhcpData.bp_hlen = bp_hlen;
 3592                 dhcpData.ip = dhcpEntry->ip;
 3593                 dhcpData.subnetFlg = dhcpEntry->subnetFlg;
 3594                 dhcpData.expiry = dhcpEntry->expiry;
 3595                 dhcpData.local = dhcpEntry->local;
 3596                 strcpy(dhcpData.hostname, dhcpEntry->hostname);
 3597                 cfig.dhcpInd += 1;
 3598                 dhcpEntry->dhcpInd = cfig.dhcpInd;
 3599                 dhcpData.dhcpInd = dhcpEntry->dhcpInd;
 3600 
 3601                 if (fseek(f, (dhcpData.dhcpInd - 1)*sizeof(data8), SEEK_SET) >= 0)
 3602                     fwrite(&dhcpData, sizeof(data8), 1, f);
 3603             }
 3604         }
 3605 
 3606         fclose(f);
 3607     }
 3608 }
 3609 
 3610 bool getSection(const char *sectionName, char *buffer, MYBYTE serial, char *fileName)
 3611 {
 3612     //printf("%s=%s\n",fileName,sectionName);
 3613     char section[128];
 3614     sprintf(section, "[%s]", sectionName);
 3615     myUpper(section);
 3616     FILE *f = fopen(fileName, "rt");
 3617     char buff[512];
 3618     MYBYTE found = 0;
 3619 
 3620     if (f)
 3621     {
 3622         while (fgets(buff, 511, f))
 3623         {
 3624             myUpper(buff);
 3625             myTrim(buff, buff);
 3626 
 3627             if (strstr(buff, section) == buff)
 3628             {
 3629                 found++;
 3630                 if (found == serial)
 3631                 {
 3632                     //printf("%s=%s\n",fileName,sectionName);
 3633                     while (fgets(buff, 511, f))
 3634                     {
 3635                         myTrim(buff, buff);
 3636 
 3637                         if (strstr(buff, "[") == buff)
 3638                             break;
 3639 
 3640                         if ((*buff) >= '0' && (*buff) <= '9' || (*buff) >= 'A' && (*buff) <= 'Z' || (*buff) >= 'a' && (*buff) <= 'z' || ((*buff) && strchr("/\\?*", (*buff))))
 3641                         {
 3642                             buffer += sprintf(buffer, "%s", buff);
 3643                             buffer++;
 3644                         }
 3645                     }
 3646                     break;
 3647                 }
 3648             }
 3649         }
 3650         fclose(f);
 3651     }
 3652 
 3653     *buffer = 0;
 3654     *(buffer + 1) = 0;
 3655     return (found == serial);
 3656 }
 3657 
 3658 FILE *openSection(const char *sectionName, MYBYTE serial)
 3659 {
 3660     char tempbuff[512];
 3661     char logBuff[256];
 3662     char section[128];
 3663     sprintf(section, "[%s]", sectionName);
 3664     myUpper(section);
 3665     FILE *f = NULL;
 3666     f = fopen(iniFile, "rt");
 3667 
 3668     if (f)
 3669     {
 3670         //printf("opened %s=%d\n", tempbuff, f);
 3671         char buff[512];
 3672         MYBYTE found = 0;
 3673 
 3674         while (fgets(buff, 511, f))
 3675         {
 3676             myUpper(buff);
 3677             myTrim(buff, buff);
 3678 
 3679             if (strstr(buff, section) == buff)
 3680             {
 3681                 found++;
 3682 
 3683                 if (found == serial)
 3684                 {
 3685                     MYDWORD fpos = ftell(f);
 3686 
 3687                     if (fgets(buff, 511, f))
 3688                     {
 3689                         myTrim(buff, buff);
 3690 
 3691                         if (buff[0] == '@')
 3692                         {
 3693                             fclose(f);
 3694                             f = NULL;
 3695 
 3696                             buff[0] = NBSP;
 3697                             myTrim(buff, buff);
 3698 
 3699                             if (strchr(buff, '\\') || strchr(buff, '/'))
 3700                                 strcpy(tempbuff, buff);
 3701                             else
 3702                                 sprintf(tempbuff, "%s%s", filePATH, buff);
 3703 
 3704                             f = fopen(tempbuff, "rt");
 3705 
 3706                             if (f)
 3707                                 return f;
 3708                             else
 3709                             {
 3710                                 sprintf(logBuff, "Error: Section [%s], file %s not found", sectionName, tempbuff);
 3711                                 logDHCPMess(logBuff, 1);
 3712                                 return NULL;
 3713                             }
 3714                         }
 3715                         else
 3716                         {
 3717                             fseek(f, fpos, SEEK_SET);
 3718                             return f;
 3719                         }
 3720                     }
 3721                 }
 3722             }
 3723         }
 3724         fclose(f);
 3725     }
 3726     return NULL;
 3727 }
 3728 
 3729 char *readSection(char* buff, FILE *f)
 3730 {
 3731     while (fgets(buff, 511, f))
 3732     {
 3733         myTrim(buff, buff);
 3734 
 3735         if (*buff == '[')
 3736             break;
 3737 
 3738         if ((*buff) >= '0' && (*buff) <= '9' || (*buff) >= 'A' && (*buff) <= 'Z' || (*buff) >= 'a' && (*buff) <= 'z' || ((*buff) && strchr("/\\?*", (*buff))))
 3739             return buff;
 3740     }
 3741 
 3742     fclose(f);
 3743     return NULL;
 3744 }
 3745 
 3746 char* myGetToken(char* buff, MYBYTE index)
 3747 {
 3748     while (*buff)
 3749     {
 3750         if (index)
 3751             index--;
 3752         else
 3753             break;
 3754 
 3755         buff += strlen(buff) + 1;
 3756     }
 3757 
 3758     return buff;
 3759 }
 3760 
 3761 MYWORD myTokenize(char *target, char *source, const char *sep, bool whiteSep)
 3762 {
 3763     bool found = true;
 3764     char *dp = target;
 3765     MYWORD kount = 0;
 3766 
 3767     while (*source)
 3768     {
 3769         if (sep && sep[0] && strchr(sep, (*source)))
 3770         {
 3771             found = true;
 3772             source++;
 3773             continue;
 3774         }
 3775         else if (whiteSep && (*source) <= NBSP)
 3776         {
 3777             found = true;
 3778             source++;
 3779             continue;
 3780         }
 3781 
 3782         if (found)
 3783         {
 3784             if (target != dp)
 3785             {
 3786                 *dp = 0;
 3787                 dp++;
 3788             }
 3789             kount++;
 3790         }
 3791 
 3792         found = false;
 3793         *dp = *source;
 3794         dp++;
 3795         source++;
 3796     }
 3797 
 3798     *dp = 0;
 3799     dp++;
 3800     *dp = 0;
 3801 
 3802     //printf("%s\n", target);
 3803 
 3804     return kount;
 3805 }
 3806 
 3807 char* myTrim(char *target, char *source)
 3808 {
 3809     while ((*source) && (*source) <= NBSP)
 3810         source++;
 3811 
 3812     int i = 0;
 3813 
 3814     for (; i < 511 && source[i]; i++)
 3815         target[i] = source[i];
 3816 
 3817     target[i] = source[i];
 3818     i--;
 3819 
 3820     for (; i >= 0 && target[i] <= NBSP; i--)
 3821         target[i] = 0;
 3822 
 3823     return target;
 3824 }
 3825 
 3826 void mySplit(char *name, char *value, char *source, char splitChar)
 3827 {
 3828     int i = 0;
 3829     int j = 0;
 3830     int k = 0;
 3831 
 3832     for (; source[i] && j <= 510 && source[i] != splitChar; i++, j++)
 3833     {
 3834         name[j] = source[i];
 3835     }
 3836 
 3837     if (source[i])
 3838     {
 3839         i++;
 3840         for (; k <= 510 && source[i]; i++, k++)
 3841         {
 3842             value[k] = source[i];
 3843         }
 3844     }
 3845 
 3846     name[j] = 0;
 3847     value[k] = 0;
 3848 
 3849     myTrim(name, name);
 3850     myTrim(value, value);
 3851     //printf("%s %s\n", name, value);
 3852 }
 3853 
 3854 MYDWORD getClassNetwork(MYDWORD ip)
 3855 {
 3856     data15 data;
 3857     data.ip = ip;
 3858     data.octate[3] = 0;
 3859 
 3860     if (data.octate[0] < 192)
 3861         data.octate[2] = 0;
 3862 
 3863     if (data.octate[0] < 128)
 3864         data.octate[1] = 0;
 3865 
 3866     return data.ip;
 3867 }
 3868 
 3869 /*
 3870 char *IP2Auth(MYDWORD ip)
 3871 {
 3872 data15 data;
 3873 data.ip = ip;
 3874 
 3875 if (data.octate[0] >= 192)
 3876 sprintf(tempbuff, "%u.%u.%u", data.octate[2], data.octate[1], data.octate[0]);
 3877 else if (data.octate[0] >= 128)
 3878 sprintf(tempbuff, "%u.%u", data.octate[1], data.octate[0]);
 3879 else
 3880 sprintf(tempbuff, "%u", data.octate[0]);
 3881 
 3882 strcat(tempbuff, arpa);
 3883 return tempbuff;
 3884 }
 3885 */
 3886 
 3887 char *IP2String(char *target, MYDWORD ip)
 3888 {
 3889     data15 inaddr;
 3890     inaddr.ip = ip;
 3891     sprintf(target, "%u.%u.%u.%u", inaddr.octate[0], inaddr.octate[1], inaddr.octate[2], inaddr.octate[3]);
 3892     //MYBYTE *octate = (MYBYTE*)&ip;
 3893     //sprintf(target, "%u.%u.%u.%u", octate[0], octate[1], octate[2], octate[3]);
 3894     return target;
 3895 }
 3896 
 3897 MYBYTE addServer(MYDWORD *array, MYBYTE maxServers, MYDWORD ip)
 3898 {
 3899     if (ip)
 3900     {
 3901         for (MYBYTE i = 0; i < maxServers; i++)
 3902         {
 3903             if (array[i] == ip)
 3904                 return i;
 3905             else if (!array[i])
 3906             {
 3907                 array[i] = ip;
 3908                 return i;
 3909             }
 3910         }
 3911     }
 3912     return maxServers;
 3913 }
 3914 
 3915 MYDWORD *findServer(MYDWORD *array, MYBYTE kount, MYDWORD ip)
 3916 {
 3917     if (ip)
 3918     {
 3919         for (MYBYTE i = 0; i < kount && array[i]; i++)
 3920         {
 3921             if (array[i] == ip)
 3922                 return &(array[i]);
 3923         }
 3924     }
 3925     return 0;
 3926 }
 3927 
 3928 bool isInt(char *str)
 3929 {
 3930     if (!str || !(*str))
 3931         return false;
 3932 
 3933     for(; *str; str++)
 3934         if (*str <  '0' || *str > '9')
 3935             return false;
 3936 
 3937     return true;
 3938 }
 3939 
 3940 bool isIP(char *str)
 3941 {
 3942     if (!str || !(*str))
 3943         return false;
 3944 
 3945     MYDWORD ip = inet_addr(str);
 3946     int j = 0;
 3947 
 3948     for (; *str; str++)
 3949     {
 3950         if (*str == '.' && *(str + 1) != '.')
 3951             j++;
 3952         else if (*str < '0' || *str > '9')
 3953             return false;
 3954     }
 3955 
 3956     if (j == 3)
 3957      {
 3958         if (ip == INADDR_NONE || ip == INADDR_ANY)
 3959             return false;
 3960         else
 3961             return true;
 3962     }
 3963     else
 3964         return false;
 3965 }
 3966 
 3967 /*
 3968 char *toBase64(MYBYTE *source, MYBYTE length)
 3969 {
 3970     MYBYTE a = 0, b = 0, i = 0;
 3971     char *dp = tempbuff;
 3972 
 3973     for (; length; length--, source++)
 3974     {
 3975         i += 2;
 3976         a = (*source) >> i;
 3977         *dp = base64[a + b];
 3978         dp++;
 3979         b = (*source) << (8 - i);
 3980         b >>= 2;
 3981         if (i == 6)
 3982         {
 3983             *dp = base64[b];
 3984             dp++;
 3985             i = b = 0;
 3986         }
 3987     }
 3988     if (i)
 3989     {
 3990         *dp = base64[b];
 3991         dp++;
 3992     }
 3993     *dp = 0;
 3994     //printf("%s\n",tempbuff);
 3995     return tempbuff;
 3996 }
 3997 
 3998 MYBYTE getBaseValue(MYBYTE a)
 3999 {
 4000     if (a >= 'A' && a <= 'Z')
 4001         a -= 'A';
 4002     else if (a >= 'a' && a <= 'z')
 4003         a = a - 'a' + 26;
 4004     else if (a >= '0' && a <= '9')
 4005         a = a - '0' + 52;
 4006     else if (a == '+')
 4007         a = 62;
 4008     else if (a == '/')
 4009         a = 63;
 4010     else
 4011         a = UCHAR_MAX;
 4012 
 4013     return a;
 4014 }
 4015 
 4016 MYBYTE fromBase64(MYBYTE *target, char *source)
 4017 {
 4018     //printf("SOURCE=%s\n", source);
 4019     MYBYTE b = 0;
 4020     MYBYTE shift = 4;
 4021     MYBYTE bp_hlen = (3 * strlen(source))/4;
 4022     *target = 0;
 4023 
 4024     if (*source)
 4025     {
 4026         b = getBaseValue(*source);
 4027         *target = b << 2;
 4028         source++;
 4029 
 4030         while (*source)
 4031         {
 4032             b = getBaseValue(*source);
 4033             (*target) += (b >> (8 - shift));
 4034             target++;
 4035             (*target) = (b << shift);
 4036             shift += 2;
 4037 
 4038             if (shift > 8)
 4039             {
 4040                 source++;
 4041 
 4042                 if (*source)
 4043                 {
 4044                     b = getBaseValue(*source);
 4045                     *target = b << 2;
 4046                     shift = 4;
 4047                 }
 4048                 else
 4049                     break;
 4050             }
 4051 
 4052             source++;
 4053         }
 4054     }
 4055     //printf("SIZE=%u\n", bp_hlen);
 4056     return bp_hlen;
 4057 }
 4058 
 4059 char *toUUE(char *tempbuff, MYBYTE *source, MYBYTE length)
 4060 {
 4061     MYBYTE a = 0, b = 0, i = 0;
 4062     char *dp = tempbuff;
 4063 
 4064     for (; length; length--, source++)
 4065     {
 4066         i += 2;
 4067         a = (*source) >> i;
 4068         *dp = a + b + NBSP;
 4069         dp++;
 4070         b = (*source) << (8 - i);
 4071         b >>= 2;
 4072         if (i == 6)
 4073         {
 4074             *dp = b + NBSP;
 4075             dp++;
 4076             i = b = 0;
 4077         }
 4078     }
 4079     if (i)
 4080     {
 4081         *dp = b + NBSP;
 4082         dp++;
 4083     }
 4084     *dp = 0;
 4085     //printf("%s\n",tempbuff);
 4086     return tempbuff;
 4087 }
 4088 
 4089 MYBYTE fromUUE(MYBYTE *target, char *source)
 4090 {
 4091     //printf("SOURCE=%s\n", source);
 4092     MYBYTE b = 0;
 4093     MYBYTE shift = 4;
 4094     MYBYTE bp_hlen = (3 * strlen(source))/4;
 4095     *target = 0;
 4096 
 4097     if (*source)
 4098     {
 4099         b = *source - NBSP;
 4100         *target = b << 2;
 4101         source++;
 4102 
 4103         while (*source)
 4104         {
 4105             b = *source - NBSP;
 4106             (*target) += (b >> (8 - shift));
 4107             target++;
 4108             (*target) = (b << shift);
 4109             shift += 2;
 4110 
 4111             if (shift > 8)
 4112             {
 4113                 source++;
 4114 
 4115                 if (*source)
 4116                 {
 4117                     b = *source - NBSP;
 4118                     *target = b << 2;
 4119                     shift = 4;
 4120                 }
 4121                 else
 4122                     break;
 4123             }
 4124 
 4125             source++;
 4126         }
 4127     }
 4128     //printf("SIZE=%u\n", bp_hlen);
 4129     return bp_hlen;
 4130 }
 4131 */
 4132 
 4133 char *hex2String(char *target, MYBYTE *hex, MYBYTE bytes)
 4134 {
 4135     char *dp = target;
 4136 
 4137     if (bytes)
 4138         dp += sprintf(target, "%02x", *hex);
 4139     else
 4140         *target = 0;
 4141 
 4142     for (MYBYTE i = 1; i < bytes; i++)
 4143             dp += sprintf(dp, ":%02x", *(hex + i));
 4144 
 4145     return target;
 4146 }
 4147 
 4148 char *genHostName(char *target, MYBYTE *hex, MYBYTE bytes)
 4149 {
 4150     char *dp = target;
 4151 
 4152     if (bytes)
 4153         dp += sprintf(target, "Host%02x", *hex);
 4154     else
 4155         *target = 0;
 4156 
 4157     for (MYBYTE i = 1; i < bytes; i++)
 4158             dp += sprintf(dp, "%02x", *(hex + i));
 4159 
 4160     return target;
 4161 }
 4162 
 4163 /*
 4164 char *IP62String(char *target, MYBYTE *source)
 4165 {
 4166     MYWORD *dw = (MYWORD*)source;
 4167     char *dp = target;
 4168     MYBYTE markbyte;
 4169 
 4170     for (markbyte = 4; markbyte > 0 && !dw[markbyte - 1]; markbyte--);
 4171 
 4172     for (MYBYTE i = 0; i < markbyte; i++)
 4173         dp += sprintf(dp, "%x:", ntohs(dw[i]));
 4174 
 4175     for (markbyte = 4; markbyte < 8 && !dw[markbyte]; markbyte++);
 4176 
 4177     for (MYBYTE i = markbyte; i < 8; i++)
 4178         dp += sprintf(dp, ":%x", htons(dw[i]));
 4179 
 4180     return target;
 4181 }
 4182 */
 4183 
 4184 char *IP62String(char *target, MYBYTE *source)
 4185 {
 4186     char *dp = target;
 4187     bool zerostarted = false;
 4188     bool zeroended = false;
 4189 
 4190     for (MYBYTE i = 0; i < 16; i += 2, source += 2)
 4191     {
 4192         if (source[0])
 4193         {
 4194             if (zerostarted)
 4195                 zeroended = true;
 4196 
 4197             if (zerostarted && zeroended)
 4198             {
 4199                 dp += sprintf(dp, "::");
 4200                 zerostarted = false;
 4201             }
 4202             else if (dp != target)
 4203                 dp += sprintf(dp, ":");
 4204 
 4205             dp += sprintf(dp, "%x", source[0]);
 4206             dp += sprintf(dp, "%02x", source[1]);
 4207         }
 4208         else if (source[1])
 4209         {
 4210             if (zerostarted)
 4211                 zeroended = true;
 4212 
 4213             if (zerostarted && zeroended)
 4214             {
 4215                 dp += sprintf(dp, "::");
 4216                 zerostarted = false;
 4217             }
 4218             else if (dp != target)
 4219                 dp += sprintf(dp, ":");
 4220 
 4221             dp += sprintf(dp, "%0x", source[1]);
 4222         }
 4223         else if (!zeroended)
 4224             zerostarted = true;
 4225     }
 4226 
 4227     return target;
 4228 }
 4229 
 4230 char *getHexValue(MYBYTE *target, char *source, MYBYTE *size)
 4231 {
 4232     if (*size)
 4233         memset(target, 0, (*size));
 4234 
 4235     for ((*size) = 0; (*source) && (*size) < UCHAR_MAX; (*size)++, target++)
 4236     {
 4237         if ((*source) >= '0' && (*source) <= '9')
 4238         {
 4239             (*target) = (*source) - '0';
 4240         }
 4241         else if ((*source) >= 'a' && (*source) <= 'f')
 4242         {
 4243             (*target) = (*source) - 'a' + 10;
 4244         }
 4245         else if ((*source) >= 'A' && (*source) <= 'F')
 4246         {
 4247             (*target) = (*source) - 'A' + 10;
 4248         }
 4249         else
 4250         {
 4251             return source;
 4252         }
 4253 
 4254         source++;
 4255 
 4256         if ((*source) >= '0' && (*source) <= '9')
 4257         {
 4258             (*target) *= 16;
 4259             (*target) += (*source) - '0';
 4260         }
 4261         else if ((*source) >= 'a' && (*source) <= 'f')
 4262         {
 4263             (*target) *= 16;
 4264             (*target) += (*source) - 'a' + 10;
 4265         }
 4266         else if ((*source) >= 'A' && (*source) <= 'F')
 4267         {
 4268             (*target) *= 16;
 4269             (*target) += (*source) - 'A' + 10;
 4270         }
 4271         else if ((*source) == ':' || (*source) == '-')
 4272         {
 4273             source++;
 4274             continue;
 4275         }
 4276         else if (*source)
 4277         {
 4278             return source;
 4279         }
 4280         else
 4281         {
 4282             continue;
 4283         }
 4284 
 4285         source++;
 4286 
 4287         if ((*source) == ':' || (*source) == '-')
 4288         {
 4289             source++;
 4290         }
 4291         else if (*source)
 4292             return source;
 4293     }
 4294 
 4295     if (*source)
 4296         return source;
 4297 
 4298     return NULL;
 4299 }
 4300 
 4301 char *myUpper(char *string)
 4302 {
 4303     char diff = 'a' - 'A';
 4304     MYWORD len = strlen(string);
 4305     for (int i = 0; i < len; i++)
 4306         if (string[i] >= 'a' && string[i] <= 'z')
 4307             string[i] -= diff;
 4308     return string;
 4309 }
 4310 
 4311 char *myLower(char *string)
 4312 {
 4313     char diff = 'a' - 'A';
 4314     MYWORD len = strlen(string);
 4315     for (int i = 0; i < len; i++)
 4316         if (string[i] >= 'A' && string[i] <= 'Z')
 4317             string[i] += diff;
 4318     return string;
 4319 }
 4320 
 4321 bool wildcmp(char *string, char *wild)
 4322 {
 4323     // Written by Jack Handy - jakkhandy@hotmail.com
 4324     // slightly modified
 4325     char *cp = NULL;
 4326     char *mp = NULL;
 4327 
 4328     while ((*string) && (*wild != '*'))
 4329     {
 4330         if ((*wild != *string) && (*wild != '?'))
 4331         {
 4332             return 0;
 4333         }
 4334         wild++;
 4335         string++;
 4336     }
 4337 
 4338     while (*string)
 4339     {
 4340         if (*wild == '*')
 4341         {
 4342             if (!*++wild)
 4343                 return 1;
 4344 
 4345             mp = wild;
 4346             cp = string + 1;
 4347         }
 4348         else if ((*wild == *string) || (*wild == '?'))
 4349         {
 4350             wild++;
 4351             string++;
 4352         }
 4353         else
 4354         {
 4355             wild = mp;
 4356             string = cp++;
 4357         }
 4358     }
 4359 
 4360     while (*wild == '*')
 4361         wild++;
 4362 
 4363     return !(*wild);
 4364 }
 4365 
 4366 /*
 4367 void checkSize()
 4368 {
 4369     data7 *dhcpEntry = NULL;
 4370 
 4371     //printf("checksize dhcpdhcpEntry[%d]=%d dhcpAge[%d]=%d\n", currentInd, dhcpdhcpEntry.size(), currentInd, dhcpAge.size());
 4372     expiryMap::iterator p = dhcpAge.begin();
 4373     expiryMap::iterator q;
 4374 
 4375     while (p != dhcpAge.end() && p->first < t)
 4376     {
 4377         dhcpEntry = p->second;
 4378         //printf("processing %s=%d\n", dhcpEntry->mapname, p->first - t);
 4379 
 4380         if (dhcpEntry->expiry < t)
 4381         {
 4382             sprintf(logBuff, "Lease %s Being Released", IP2String(tempbuff, dhcpEntry->ip));
 4383             logDHCPMess(logBuff, 2);
 4384             q = p;
 4385             p++;
 4386 
 4387             dhcpAge.erase(q);
 4388             dhcpEntry->hanged = false;
 4389             updateDHCP(dhcpEntry, 0);
 4390         }
 4391         else if (dhcpEntry->expiry > p->first)
 4392         {
 4393             q = p;
 4394             p++;
 4395             dhcpAge.erase(q);
 4396             dhcpAge.insert(pair<time_t, data7*>(dhcpEntry->expiry, dhcpEntry));
 4397         }
 4398         else
 4399             p++;
 4400     }
 4401     //printf("Done %u=%u\n",dnsdhcpEntry[ind].size(),dnsAge[currentInd].size());
 4402 }
 4403 */
 4404 
 4405 void *updateStateFile(void *lpParam)
 4406 {
 4407     pthread_mutex_lock( &mutStateFile );
 4408 
 4409     data7 *dhcpEntry = (data7*)lpParam;
 4410     data8 dhcpData;
 4411     memset(&dhcpData, 0, sizeof(data8));
 4412     MYBYTE bp_hlen =  16;
 4413     getHexValue(dhcpData.bp_chaddr, dhcpEntry->mapname, &bp_hlen);
 4414     dhcpData.bp_hlen =  bp_hlen;
 4415     dhcpData.ip = dhcpEntry->ip;
 4416     dhcpData.subnetFlg = dhcpEntry->subnetFlg;
 4417     dhcpData.expiry = dhcpEntry->expiry;
 4418     dhcpData.local = dhcpEntry->local;
 4419     strcpy(dhcpData.hostname, dhcpEntry->hostname);
 4420 
 4421     if (!dhcpEntry->dhcpInd)
 4422     {
 4423         cfig.dhcpInd += 1;
 4424         dhcpEntry->dhcpInd = cfig.dhcpInd;
 4425     }
 4426 
 4427     dhcpData.dhcpInd = dhcpEntry->dhcpInd;
 4428     FILE *f = fopen(leaFile, "rb+");
 4429 
 4430     if (f)
 4431     {
 4432         if (fseek(f, (dhcpData.dhcpInd - 1)*sizeof(data8), SEEK_SET) >= 0)
 4433             fwrite(&dhcpData, sizeof(data8), 1, f);
 4434 
 4435         fclose(f);
 4436     }
 4437 
 4438     pthread_mutex_unlock( &mutStateFile );
 4439     pthread_exit(NULL);
 4440 }
 4441 
 4442 void calcRangeLimits(MYDWORD ip, MYDWORD mask, MYDWORD *rangeStart, MYDWORD *rangeEnd)
 4443 {
 4444     *rangeStart = htonl(ip & mask) + 1;
 4445     *rangeEnd = htonl(ip | (~mask)) - 1;
 4446 }
 4447 
 4448 data7 *findDHCPEntry(char *key)
 4449 {
 4450     //printf("finding %u=%s\n",ind,key);
 4451     myLower(key);
 4452     dhcpMap::iterator it = dhcpCache.find(key);
 4453 
 4454     if (it == dhcpCache.end())
 4455         return NULL;
 4456     else
 4457         return it->second;
 4458 }
 4459 
 4460 bool checkMask(MYDWORD mask)
 4461 {
 4462     mask = htonl(mask);
 4463 
 4464     while (mask)
 4465     {
 4466         if (mask < (mask << 1))
 4467             return false;
 4468 
 4469         mask <<= 1;
 4470     }
 4471 
 4472     return true;
 4473 }
 4474 
 4475 MYDWORD calcMask(MYDWORD rangeStart, MYDWORD rangeEnd)
 4476 {
 4477     data15 ip1, ip2, mask;
 4478 
 4479     ip1.ip = htonl(rangeStart);
 4480     ip2.ip = htonl(rangeEnd);
 4481 
 4482     for (MYBYTE i = 0; i < 4; i++)
 4483     {
 4484         mask.octate[i] = ip1.octate[i] ^ ip2.octate[i];
 4485 
 4486         if (i && mask.octate[i - 1] < 255)
 4487             mask.octate[i] = 0;
 4488         else if (mask.octate[i] == 0)
 4489             mask.octate[i] = 255;
 4490         else if (mask.octate[i] < 2)
 4491             mask.octate[i] = 254;
 4492         else if (mask.octate[i] < 4)
 4493             mask.octate[i] = 252;
 4494         else if (mask.octate[i] < 8)
 4495             mask.octate[i] = 248;
 4496         else if (mask.octate[i] < 16)
 4497             mask.octate[i] = 240;
 4498         else if (mask.octate[i] < 32)
 4499             mask.octate[i] = 224;
 4500         else if (mask.octate[i] < 64)
 4501             mask.octate[i] = 192;
 4502         else if (mask.octate[i] < 128)
 4503             mask.octate[i] = 128;
 4504         else
 4505             mask.octate[i] = 0;
 4506     }
 4507     return mask.ip;
 4508 }
 4509 
 4510 char *cloneString(char *string)
 4511 {
 4512     if (!string)
 4513         return NULL;
 4514 
 4515     char *s = (char*)calloc(1, strlen(string) + 1);
 4516 
 4517     if (s)
 4518     {
 4519         strcpy(s, string);
 4520     }
 4521     return s;
 4522 }
 4523 
 4524 void *init(void *lparam)
 4525 {
 4526     char tempbuff[512];
 4527     char logBuff[256];
 4528     char raw[512];
 4529     char name[512];
 4530     char value[512];
 4531     FILE *f = NULL;
 4532 
 4533     if (f = openSection("LOGGING", 1))
 4534     {
 4535         cfig.dhcpLogLevel = 1;
 4536         tempbuff[0] = 0;
 4537 
 4538         while (readSection(raw, f))
 4539         {
 4540             mySplit(name, value, raw, '=');
 4541 
 4542             if (name[0] && value[0])
 4543             {
 4544                 if (!strcasecmp(name, "LogLevel"))
 4545                 {
 4546                     if (!strcasecmp(value, "None"))
 4547                         cfig.dhcpLogLevel = 0;
 4548                     else if (!strcasecmp(value, "Normal"))
 4549                         cfig.dhcpLogLevel = 1;
 4550                     else if (!strcasecmp(value, "All"))
 4551                         cfig.dhcpLogLevel = 2;
 4552                     else
 4553                         sprintf(tempbuff, "Section [LOGGING], Invalid LogLevel: %s", value);
 4554                 }
 4555                 else
 4556                     sprintf(tempbuff, "Section [LOGGING], Invalid Entry %s ignored", raw);
 4557             }
 4558             else
 4559                 sprintf(tempbuff, "Section [LOGGING], Invalid Entry %s ignored", raw);
 4560         }
 4561         if (tempbuff[0])
 4562             logDHCPMess(logBuff, 1);
 4563 
 4564         sprintf(logBuff, "%s Starting...", sVersion);
 4565         logDHCPMess(logBuff, 1);
 4566     }
 4567     else
 4568         printf("%s Starting...\n", sVersion);
 4569 
 4570     sleep(1);
 4571 
 4572     if ((f = fopen(iniFile, "rt")))
 4573     {
 4574         fclose(f);
 4575     }
 4576     else
 4577     {
 4578         sprintf(logBuff, "Warning: file %s not found, defaults will be used", iniFile);
 4579         logDHCPMess(logBuff, 1);
 4580     }
 4581 
 4582     cfig.lease = 36000;
 4583     loadDHCP();
 4584 
 4585     if (cfig.dhcpLogLevel > 1)
 4586         sprintf(logBuff, "Logging: All");
 4587     else if (cfig.dhcpLogLevel >= 1)
 4588         sprintf(logBuff, "Logging: Normal");
 4589     else
 4590         sprintf(logBuff, "Logging: None");
 4591 
 4592     logDHCPMess(logBuff, 1);
 4593 
 4594     if (f = openSection("LISTEN_ON", 1))
 4595     {
 4596         while (readSection(raw, f))
 4597         {
 4598             if (isIP(raw))
 4599             {
 4600                 MYDWORD addr = inet_addr(raw);
 4601                 addServer(cfig.specifiedServers, MAX_SERVERS, addr);
 4602             }
 4603             else
 4604             {
 4605                 sprintf(logBuff, "Warning: Section [LISTEN_ON], Invalid Interface Address %s, ignored", raw);
 4606                 logDHCPMess(logBuff, 1);
 4607             }
 4608         }
 4609     }
 4610 
 4611 /*
 4612     for (int i = 0; i < cfig.rangeCount; i++)
 4613     {
 4614         char *logPtr = logBuff;
 4615         logPtr += sprintf(logPtr, "DHCP Range: ");
 4616         logPtr += sprintf(logPtr, "%s", IP2String(tempbuff, htonl(cfig.dhcpRanges[i].rangeStart)));
 4617         logPtr += sprintf(logPtr, "-%s", IP2String(tempbuff, htonl(cfig.dhcpRanges[i].rangeEnd)));
 4618         logPtr += sprintf(logPtr, "/%s", IP2String(tempbuff, cfig.dhcpRanges[i].mask));
 4619         logDHCPMess(logBuff, 1);
 4620     }
 4621 */
 4622     gethostname(cfig.servername, sizeof(cfig.servername));
 4623 
 4624     char *ptr = strchr(cfig.servername, '.');
 4625 
 4626     if (ptr)
 4627     {
 4628         *ptr = 0;
 4629         ptr++;
 4630         strcpy(cfig.zone, ptr);
 4631         cfig.zLen = strlen(cfig.zone);
 4632     }
 4633 #ifdef getdomainname
 4634     else
 4635     {
 4636         getdomainname(cfig.zone, sizeof(cfig.zone));
 4637         cfig.zLen = strlen(cfig.zone);
 4638     }
 4639 #endif
 4640 
 4641     cfig.fixedSocket = socket(AF_INET, SOCK_DGRAM, 0);
 4642 
 4643     if (cfig.fixedSocket < 0)
 4644     {
 4645         sprintf(logBuff, "Failed to Create Socket");
 4646         logDHCPMess(logBuff, 1);
 4647         exit(EXIT_FAILURE);
 4648     }
 4649 
 4650     getInterfaces(&newNetwork);
 4651     memcpy(cfig.oldservers, newNetwork.staticServers, (MAX_SERVERS * sizeof(MYDWORD)));
 4652 
 4653     if (f = openSection("REPLICATION_SERVERS", 1))
 4654     {
 4655         while (readSection(raw, f))
 4656         {
 4657             mySplit(name, value, raw, '=');
 4658 
 4659             if (name[0] && value[0])
 4660             {
 4661                 if (!isIP(name) && isIP(value))
 4662                 {
 4663                     if (!strcasecmp(name, "Primary"))
 4664                         cfig.zoneServers[0] = inet_addr(value);
 4665                     else if (!strcasecmp(name, "Secondary"))
 4666                         cfig.zoneServers[1] = inet_addr(value);
 4667                     else
 4668                     {
 4669                         sprintf(logBuff, "Section [REPLICATION_SERVERS] Invalid Entry: %s ignored", raw);
 4670                         logDHCPMess(logBuff, 1);
 4671                     }
 4672                 }
 4673                 else
 4674                 {
 4675                     sprintf(logBuff, "Section [REPLICATION_SERVERS] Invalid Entry: %s ignored", raw);
 4676                     logDHCPMess(logBuff, 1);
 4677                 }
 4678             }
 4679             else
 4680             {
 4681                 sprintf(logBuff, "Section [REPLICATION_SERVERS], Missing value, entry %s ignored", raw);
 4682                 logDHCPMess(logBuff, 1);
 4683             }
 4684         }
 4685     }
 4686 
 4687     if (!cfig.zoneServers[0] && cfig.zoneServers[1])
 4688     {
 4689         sprintf(logBuff, "Section [REPLICATION_SERVERS] Missing Primary Server");
 4690         logDHCPMess(logBuff, 1);
 4691     }
 4692     else if (cfig.zoneServers[0] && !cfig.zoneServers[1])
 4693     {
 4694         sprintf(logBuff, "Section [REPLICATION_SERVERS] Missing Secondary Server");
 4695         logDHCPMess(logBuff, 1);
 4696     }
 4697     else if (cfig.zoneServers[0] && cfig.zoneServers[1])
 4698     {
 4699         if (findServer(newNetwork.allServers, MAX_SERVERS, cfig.zoneServers[0]) && findServer(newNetwork.allServers, MAX_SERVERS, cfig.zoneServers[1]))
 4700         {
 4701             sprintf(logBuff, "Section [REPLICATION_SERVERS] Primary & Secondary should be Different Boxes");
 4702             logDHCPMess(logBuff, 1);
 4703         }
 4704         else if (findServer(newNetwork.allServers, MAX_SERVERS, cfig.zoneServers[0]))
 4705             cfig.replication = 1;
 4706         else if (findServer(newNetwork.allServers, MAX_SERVERS, cfig.zoneServers[1]))
 4707             cfig.replication = 2;
 4708         else
 4709         {
 4710             sprintf(logBuff, "Section [REPLICATION_SERVERS] No Server IP not found on this Machine");
 4711             logDHCPMess(logBuff, 1);
 4712         }
 4713     }
 4714 
 4715     if (cfig.replication)
 4716     {
 4717         lockIP(cfig.zoneServers[0]);
 4718         lockIP(cfig.zoneServers[1]);
 4719 
 4720         //sprintf(logBuff, "Contacting Primary DHCP Server %s", IP2String(tempbuff, cfig.zoneServers[0]));
 4721         //logDHCPMess(logBuff, 1);
 4722 
 4723         cfig.dhcpReplConn.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
 4724 
 4725         if (cfig.dhcpReplConn.sock == INVALID_SOCKET)
 4726         {
 4727             sprintf(logBuff, "Failed to Create DHCP Replication Socket");
 4728             logDHCPMess(logBuff, 1);
 4729         }
 4730         else
 4731         {
 4732             //printf("Socket %u\n", cfig.dhcpReplConn.sock);
 4733 
 4734             if (cfig.replication == 1)
 4735                 cfig.dhcpReplConn.server = cfig.zoneServers[0];
 4736             else
 4737                 cfig.dhcpReplConn.server = cfig.zoneServers[1];
 4738 
 4739             cfig.dhcpReplConn.addr.sin_family = AF_INET;
 4740             cfig.dhcpReplConn.addr.sin_addr.s_addr = cfig.dhcpReplConn.server;
 4741             cfig.dhcpReplConn.addr.sin_port = 0;
 4742 
 4743             int nRet = bind(cfig.dhcpReplConn.sock, (sockaddr*)&cfig.dhcpReplConn.addr, sizeof(struct sockaddr_in));
 4744 
 4745             if (nRet == SOCKET_ERROR)
 4746             {
 4747                 cfig.dhcpReplConn.ready = false;
 4748                 sprintf(logBuff, "DHCP Replication Server, Bind Failed");
 4749                 logDHCPMess(logBuff, 1);
 4750             }
 4751             else
 4752             {
 4753                 cfig.dhcpReplConn.port = IPPORT_DHCPS;
 4754                 cfig.dhcpReplConn.loaded = true;
 4755                 cfig.dhcpReplConn.ready = true;
 4756 
 4757                 data3 op;
 4758                 memset(&token, 0, sizeof(data9));
 4759                 token.vp = token.dhcpp.vend_data;
 4760                 token.messsize = sizeof(dhcp_packet);
 4761 
 4762                 token.dhcpp.header.bp_op = BOOTP_REQUEST;
 4763                 token.dhcpp.header.bp_xid = 0;
 4764                 token.dhcpp.header.bp_magic_num[0] = 99;
 4765                 token.dhcpp.header.bp_magic_num[1] = 130;
 4766                 token.dhcpp.header.bp_magic_num[2] = 83;
 4767                 token.dhcpp.header.bp_magic_num[3] = 99;
 4768 
 4769                 op.opt_code = DHCP_OPTION_MESSAGETYPE;
 4770                 op.size = 1;
 4771                 op.value[0] = DHCP_MESS_INFORM;
 4772                 pvdata(&token, &op);
 4773 
 4774                 op.opt_code = DHCP_OPTION_HOSTNAME;
 4775                 op.size = strlen(cfig.servername);
 4776                 memcpy(op.value, cfig.servername, op.size);
 4777                 pvdata(&token, &op);
 4778 
 4779                 token.vp[0] = DHCP_OPTION_END;
 4780                 token.vp++;
 4781                 token.bytes = token.vp - (MYBYTE*)token.raw;
 4782 
 4783                 token.remote.sin_port = htons(IPPORT_DHCPS);
 4784                 token.remote.sin_family = AF_INET;
 4785 
 4786                 if (cfig.replication == 1)
 4787                     token.remote.sin_addr.s_addr = cfig.zoneServers[1];
 4788                 else
 4789                     token.remote.sin_addr.s_addr = cfig.zoneServers[0];
 4790 
 4791                 if (cfig.replication == 2)
 4792                 {
 4793                     pthread_t threadId;
 4794                     pthread_attr_t attr;
 4795                     pthread_attr_init(&attr);
 4796                     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 4797                     int errcode = pthread_create(&threadId, &attr, sendToken, 0);
 4798                     pthread_attr_destroy(&attr);
 4799                 }
 4800             }
 4801         }
 4802     }
 4803 
 4804     sprintf(cfig.servername_fqn, "%s.%s", cfig.servername, cfig.zone);
 4805 
 4806     if (cfig.lease >= MY_MAX_TIME)
 4807         sprintf(logBuff, "Default Lease: Infinity");
 4808     else
 4809         sprintf(logBuff, "Default Lease: %u (sec)", cfig.lease);
 4810 
 4811     logDHCPMess(logBuff, 1);
 4812 
 4813     if (cfig.replication == 1)
 4814         sprintf(logBuff, "Server Name: %s (Primary)", cfig.servername);
 4815     else if (cfig.replication == 2)
 4816         sprintf(logBuff, "Server Name: %s (Secondary)", cfig.servername);
 4817     else
 4818         sprintf(logBuff, "Server Name: %s", cfig.servername);
 4819 
 4820     logDHCPMess(logBuff, 1);
 4821 
 4822     do
 4823     {
 4824         if (newNetwork.maxFD < cfig.dhcpReplConn.sock)
 4825             newNetwork.maxFD = cfig.dhcpReplConn.sock;
 4826 
 4827         bool bindfailed = false;
 4828 
 4829         if (cfig.specifiedServers[0])
 4830         {
 4831             for (MYBYTE i = 0; i < MAX_SERVERS && cfig.specifiedServers[i]; i++)
 4832             {
 4833                 MYBYTE j = 0;
 4834 
 4835                 for (; j < MAX_SERVERS && newNetwork.allServers[j]; j++)
 4836                 {
 4837                     if (newNetwork.allServers[j] == cfig.specifiedServers[i])
 4838                     {
 4839                         MYBYTE k = addServer(newNetwork.listenServers, MAX_SERVERS, newNetwork.allServers[j]);
 4840 
 4841                         if (k != MAX_SERVERS)
 4842                             newNetwork.listenMasks[k] = newNetwork.allMasks[j];
 4843 
 4844                         break;
 4845                     }
 4846                 }
 4847 
 4848                 if (j == MAX_SERVERS || !newNetwork.allServers[j])
 4849                 {
 4850                     bindfailed = true;
 4851                     sprintf(logBuff, "Warning: Section [LISTEN_ON], Interface %s not available, ignored", IP2String(tempbuff, cfig.specifiedServers[i]));
 4852                     logDHCPMess(logBuff, 1);
 4853                 }
 4854             }
 4855         }
 4856         else
 4857         {
 4858             //sprintf(logBuff, "Detecting Static Interfaces..");
 4859             //logDHCPMess(logBuff, 1);
 4860 
 4861             for (MYBYTE i = 0; i < MAX_SERVERS && newNetwork.allServers[i]; i++)
 4862             {
 4863                 if (findServer(newNetwork.staticServers, MAX_SERVERS, newNetwork.allServers[i]))
 4864                 {
 4865                     MYBYTE k = addServer(newNetwork.listenServers, MAX_SERVERS, newNetwork.allServers[i]);
 4866 
 4867                     if (k != MAX_SERVERS)
 4868                         newNetwork.listenMasks[k] = newNetwork.allMasks[i];
 4869                 }
 4870                 else
 4871                 {
 4872                     sprintf(logBuff, "Warning: Interface %s is not Static, not used", IP2String(tempbuff, newNetwork.allServers[i]));
 4873                     logDHCPMess(logBuff, 2);
 4874                     break;
 4875                 }
 4876             }
 4877         }
 4878 
 4879         int i = 0;
 4880 
 4881         for (int j = 0; j < MAX_SERVERS && newNetwork.listenServers[j]; j++)
 4882         {
 4883             int k = 0;
 4884 
 4885             for (; k < MAX_SERVERS && network.dhcpConn[k].loaded; k++)
 4886             {
 4887                 if (network.dhcpConn[k].ready && network.dhcpConn[k].server == newNetwork.listenServers[j])
 4888                     break;
 4889             }
 4890 
 4891             if (network.dhcpConn[k].ready && network.dhcpConn[k].server == newNetwork.listenServers[j])
 4892             {
 4893                 memcpy(&(newNetwork.dhcpConn[i]), &(network.dhcpConn[k]), sizeof(DhcpConnType));
 4894 
 4895                 if (newNetwork.maxFD < newNetwork.dhcpConn[i].sock)
 4896                     newNetwork.maxFD = newNetwork.dhcpConn[i].sock;
 4897 
 4898                 network.dhcpConn[k].ready = false;
 4899                 i++;
 4900                 continue;
 4901             }
 4902             else
 4903             {
 4904                 newNetwork.dhcpConn[i].sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
 4905 
 4906                 if (newNetwork.dhcpConn[i].sock == INVALID_SOCKET)
 4907                 {
 4908                     bindfailed = true;
 4909                     sprintf(logBuff, "Failed to Create Socket");
 4910                     logDHCPMess(logBuff, 1);
 4911                     continue;
 4912                 }
 4913 
 4914                 //printf("Socket %u\n", newNetwork.dhcpConn[i].sock);
 4915 
 4916                 newNetwork.dhcpConn[i].addr.sin_family = AF_INET;
 4917                 newNetwork.dhcpConn[i].addr.sin_addr.s_addr = newNetwork.listenServers[j];
 4918                 newNetwork.dhcpConn[i].addr.sin_port = htons(IPPORT_DHCPS);
 4919                 newNetwork.dhcpConn[i].reUseVal = true;
 4920                 newNetwork.dhcpConn[i].reUseSize = sizeof(newNetwork.dhcpConn[i].reUseVal);
 4921 
 4922                 setsockopt(newNetwork.dhcpConn[i].sock, SOL_SOCKET, SO_REUSEADDR, (char*)&newNetwork.dhcpConn[i].reUseVal, newNetwork.dhcpConn[i].reUseSize);
 4923 
 4924                 newNetwork.dhcpConn[i].broadCastVal = true;
 4925                 newNetwork.dhcpConn[i].broadCastSize = sizeof(newNetwork.dhcpConn[i].broadCastVal);
 4926 
 4927                 setsockopt(newNetwork.dhcpConn[i].sock, SOL_SOCKET, SO_BROADCAST, (char*)&newNetwork.dhcpConn[i].broadCastVal, newNetwork.dhcpConn[i].broadCastSize);
 4928                 int nRet = bind(newNetwork.dhcpConn[i].sock, (sockaddr*)&newNetwork.dhcpConn[i].addr, sizeof(struct sockaddr_in));
 4929 
 4930                 if (nRet == SOCKET_ERROR)
 4931                 {
 4932                     close(newNetwork.dhcpConn[i].sock);
 4933                     sprintf(logBuff, "%s Port 67 already in use", IP2String(tempbuff, newNetwork.listenServers[j]));
 4934                     logDHCPMess(logBuff, 1);
 4935                     continue;
 4936                 }
 4937 
 4938                 newNetwork.dhcpConn[i].loaded = true;
 4939                 newNetwork.dhcpConn[i].ready = true;
 4940 
 4941                 if (newNetwork.maxFD < newNetwork.dhcpConn[i].sock)
 4942                     newNetwork.maxFD = newNetwork.dhcpConn[i].sock;
 4943 
 4944                 newNetwork.dhcpConn[i].server = newNetwork.listenServers[j];
 4945                 newNetwork.dhcpConn[i].mask = newNetwork.listenMasks[j];
 4946                 newNetwork.dhcpConn[i].port = IPPORT_DHCPS;
 4947 
 4948                 i++;
 4949             }
 4950         }
 4951 
 4952         if (network.dhcpListener.ready)
 4953         {
 4954             memcpy(&(newNetwork.dhcpListener), &(network.dhcpListener), sizeof(DhcpConnType));
 4955 
 4956             if (newNetwork.maxFD < newNetwork.dhcpListener.sock)
 4957                 newNetwork.maxFD = newNetwork.dhcpListener.sock;
 4958 
 4959             network.dhcpListener.ready = false;
 4960         }
 4961         else
 4962         {
 4963             newNetwork.dhcpListener.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
 4964 
 4965             if (newNetwork.dhcpListener.sock == INVALID_SOCKET)
 4966             {
 4967                 sprintf(logBuff, "Failed to Creat DHCP Socket");
 4968                 logDHCPMess(logBuff, 1);
 4969             }
 4970             else
 4971             {
 4972                 newNetwork.dhcpListener.reUseVal = true;
 4973                 newNetwork.dhcpListener.reUseSize = sizeof(newNetwork.dhcpListener.reUseVal);
 4974                 setsockopt(newNetwork.dhcpListener.sock, SOL_SOCKET, SO_REUSEADDR, (char*)&newNetwork.dhcpListener.reUseVal, newNetwork.dhcpListener.reUseSize);
 4975                 newNetwork.dhcpListener.pktinfoVal = true;
 4976                 newNetwork.dhcpListener.pktinfoSize = sizeof(newNetwork.dhcpListener.pktinfoVal);
 4977                 setsockopt(newNetwork.dhcpListener.sock, SOL_IP, IP_PKTINFO, &newNetwork.dhcpListener.pktinfoVal, newNetwork.dhcpListener.pktinfoSize);
 4978 
 4979                 newNetwork.dhcpListener.addr.sin_family = AF_INET;
 4980                 newNetwork.dhcpListener.addr.sin_addr.s_addr = INADDR_ANY;
 4981                 newNetwork.dhcpListener.addr.sin_port = htons(IPPORT_DHCPS);
 4982 
 4983                 int nRet = bind(newNetwork.dhcpListener.sock,
 4984                                 (sockaddr*)&newNetwork.dhcpListener.addr,
 4985                                 sizeof(struct sockaddr_in)
 4986                                );
 4987 
 4988                 if (nRet == SOCKET_ERROR)
 4989                 {
 4990                     close(newNetwork.dhcpListener.sock);
 4991                     sprintf(logBuff, "DHCP Port 67 already in use");
 4992                     logDHCPMess(logBuff, 1);
 4993                 }
 4994                 else
 4995                 {
 4996                     newNetwork.dhcpListener.loaded = true;
 4997                     newNetwork.dhcpListener.ready = true;
 4998 
 4999                     if (newNetwork.maxFD < newNetwork.dhcpListener.sock)
 5000                         newNetwork.maxFD = newNetwork.dhcpListener.sock;
 5001                 }
 5002             }
 5003         }
 5004 
 5005         newNetwork.httpConn.port = 6789;
 5006         newNetwork.httpConn.server = newNetwork.dhcpConn[0].server;
 5007         newNetwork.httpConn.loaded = true;
 5008 
 5009         if (f = openSection("HTTP_INTERFACE", 1))
 5010         {
 5011             while (readSection(raw, f))
 5012             {
 5013                 mySplit(name, value, raw, '=');
 5014 
 5015                 if (!strcasecmp(name, "HTTPServer"))
 5016                 {
 5017                     mySplit(name, value, value, ':');
 5018 
 5019                     if (isIP(name))
 5020                     {
 5021                         newNetwork.httpConn.loaded = true;
 5022                         newNetwork.httpConn.server