home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 February / maximum-cd-2011-02.iso / DiscContents / ConnectifyInstaller.exe / source / dualserver / DualServer.cpp next >
Encoding:
C/C++ Source or Header  |  2010-09-25  |  241.6 KB  |  9,658 lines

  1. /**************************************************************************
  2. *   Copyright (C) 2005 by Achal Dhir                                      *
  3. *   achaldhir@gmail.com 
  4. *   Portions modified and Copyright (C) 2010 by Connectify
  5. *                                                                         *
  6. *   This program is free software; you can redistribute it and/or modify  *
  7. *   it under the terms of the GNU General Public License as published by  *
  8. *   the Free Software Foundation; either version 2 of the License, or     *
  9. *   (at your option) any later version.                                   *
  10. *                                                                         *
  11. *   This program is distributed in the hope that it will be useful,       *
  12. *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  13. *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  14. *   GNU General Public License for more details.                          *
  15. *                                                                         *
  16. *   You should have received a copy of the GNU General Public License     *
  17. *   along with this program; if not, write to the                         *
  18. *   Free Software Foundation, Inc.,                                       *
  19. *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  20. ***************************************************************************/
  21. // Dual Service.cpp
  22. #include <stdio.h>
  23. #include <winsock2.h>
  24. #include <time.h>
  25. #include <tchar.h>
  26. #include <ws2tcpip.h>
  27. #include <limits.h>
  28. #include <iphlpapi.h>
  29. #include <process.h>
  30. #include "DualServer.h"
  31.  
  32.  
  33. //Global Variables
  34. SERVICE_STATUS serviceStatus;
  35. SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
  36. HANDLE stopServiceEvent = 0;
  37. data1 network;
  38. data2 cfig;
  39. BYTE cacheInd = 0;
  40. BYTE newInd = 0;
  41. hostMap dnsCache[2];
  42. dhcpMap dhcpCache;
  43. expiryMap dnsAge[2];
  44. expiryMap dhcpAge;
  45. char serviceName[] = "DUALServer";
  46. char displayName[] = "Dual DHCP DNS Service";
  47. char tempbuff[256];
  48. char extbuff[256];
  49. char logBuff[256];
  50. bool verbatim = false;
  51. char iniFile[_MAX_PATH]; // "DualServer.ini"
  52. char leaFile[_MAX_PATH]; // "DualServer.state"
  53. char logFile[_MAX_PATH]; // "DualServer.state"
  54. WORD loggingDay;
  55. char arpa[] = ".in-addr.arpa";
  56. bool dhcpService = true;
  57. bool dnsService = true;
  58. timeval tv;
  59. fd_set readfds;
  60. fd_set writefds;
  61. HANDLE fEvent;
  62. //HANDLE lEvent;
  63. DWORD portOffset;
  64. vciMap vci;
  65.  
  66. //constants
  67. const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  68. 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";
  69. //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";
  70. const char line200[] = "<td>%s</td>";
  71. const char sVersion[] = "Dual DHCP DNS Server Version 6.50 Windows Build 6501";
  72. const data4 opData[] =
  73.     {
  74.         {"IP_Addr", 0, 0},
  75.         {"DHCP_Range", 0, 1},
  76.         //{"Authorized", 0, 6},
  77.         {"SubNet_Mask", DHCP_OPTION_NETMASK, 3},
  78.         {"Time_Offset", DHCP_OPTION_TIMEOFFSET, 4},
  79.         {"Router", DHCP_OPTION_ROUTER, 3},
  80.         {"Time_Server", DHCP_OPTION_TIMESERVER, 3},
  81.         {"Name_Server", DHCP_OPTION_NAMESERVER, 3},
  82.         {"DNS_Server", DHCP_OPTION_DNS, 3},
  83.         {"Log_Server", DHCP_OPTION_LOGSERVER, 3},
  84.         {"Cookie_Server", DHCP_OPTION_COOKIESERVER, 3},
  85.         {"LPR_Server", DHCP_OPTION_LPRSERVER, 3},
  86.         {"Impress_Server", DHCP_OPTION_IMPRESSSERVER, 3},
  87.         {"RLP_Server", DHCP_OPTION_RESLOCSERVER, 3},
  88.         {"Hostname", DHCP_OPTION_HOSTNAME, 1},
  89.         {"Boot_File_Size", DHCP_OPTION_BOOTFILESIZE, 5},
  90. //        {"Domain_Name", DHCP_OPTION_DOMAINNAME, 1},
  91.         {"Swap_Server", DHCP_OPTION_SWAPSERVER, 3},
  92.         {"Root_Path", DHCP_OPTION_ROOTPATH, 1},
  93.         {"Extension_Path", DHCP_OPTION_EXTSPATH, 1},
  94.         {"IP_Forward_On/Off", DHCP_OPTION_IPFORWARD, 7},
  95.         {"SrcRte_On/Off", DHCP_OPTION_NONLOCALSR, 7},
  96.         {"Policy_Filter", DHCP_OPTION_POLICYFILTER, 3},
  97.         {"Default_IP_TTL", DHCP_OPTION_IPTTL, 6},
  98.         {"MTU_Timeout", DHCP_OPTION_PATHMTUAGING, 4},
  99.         {"MTU_Plateau", DHCP_OPTION_PATHMTUPLATEAU, 2},
  100.         {"MTU_Interface", DHCP_OPTION_INTERFACEMTU, 5},
  101.         {"All_Subnet_Local", DHCP_OPTION_SUBNETSLOCAL, 7},
  102.         {"Broadcast_Address", DHCP_OPTION_BCASTADDRESS, 3},
  103.         {"Mask_Discovery", DHCP_OPTION_MASKDISCOVERY, 7},
  104.         {"Mask_Supplier", DHCP_OPTION_MASKSUPPLIER, 7},
  105.         {"Router_Discovery", DHCP_OPTION_ROUTERDISCOVERY, 7},
  106.         {"Router_Soli_Address", DHCP_OPTION_ROUTERSOLIC, 3},
  107.         {"Static_Routes", DHCP_OPTION_STATICROUTE, 3},
  108.         {"Trailers", DHCP_OPTION_TRAILERENCAPS, 7},
  109.         {"ARP_Timeout", DHCP_OPTION_ARPTIMEOUT, 4},
  110.         {"Ethernet_Encp", DHCP_OPTION_ETHERNETENCAPS, 7},
  111.         {"Default_TCP_TTL", DHCP_OPTION_TCPTTL, 6},
  112.         {"Keepalive_Time", DHCP_OPTION_TCPKEEPALIVEINT, 4},
  113.         {"Keepalive_Garbage", DHCP_OPTION_TCPKEEPALIVEGRBG, 7},
  114.         {"NIS_Domain", DHCP_OPTION_NISDOMAIN, 1},
  115.         {"NIS_Servers", DHCP_OPTION_NISSERVERS, 3},
  116.         {"NTP_Servers", DHCP_OPTION_NTPSERVERS, 3},
  117.         {"NETBIOS_Name_Srv", DHCP_OPTION_NETBIOSNAMESERV, 3},
  118.         {"NETBIOS_Dist_Srv", DHCP_OPTION_NETBIOSDGDIST, 3},
  119.         {"NETBIOS_Node_Type", DHCP_OPTION_NETBIOSNODETYPE, 6},
  120.         {"NETBIOS_Scope", DHCP_OPTION_NETBIOSSCOPE, 1},
  121.         {"X_Window_Font", DHCP_OPTION_X11FONTS, 3},
  122.         {"X_Window_Manager", DHCP_OPTION_X11DISPLAYMNGR, 3},
  123.         {"Lease_Time", DHCP_OPTION_IPADDRLEASE, 4},
  124.         {"Renewal_Time", DHCP_OPTION_RENEWALTIME, 4},
  125.         {"Rebinding_Time", DHCP_OPTION_REBINDINGTIME, 4},
  126.         {"Netware/IP_Domain", 62, 1},
  127.         {"Netware/IP_Options", 63, 2},
  128.         {"NIS+_Domain_Name", DHCP_OPTION_NISPLUSDOMAIN, 1},
  129.         {"NIS+_Server_Addr", DHCP_OPTION_NISPLUSSERVERS, 3},
  130.         {"TFTP_Server_Name", DHCP_OPTION_TFTPSERVER, 1},
  131.         {"Boot_File", DHCP_OPTION_BOOTFILE, 1},
  132.         {"Home_Agent_Addrs", DHCP_OPTION_MOBILEIPHOME, 3},
  133.         {"SMTP_Server", DHCP_OPTION_SMTPSERVER, 3},
  134.         {"POP3_Server", DHCP_OPTION_POP3SERVER, 3},
  135.         {"NNTP_Server", DHCP_OPTION_NNTPSERVER, 3},
  136.         {"WWW_Server", DHCP_OPTION_WWWSERVER, 3},
  137.         {"Finger_Server", DHCP_OPTION_FINGERSERVER, 3},
  138.         {"IRC_Server", DHCP_OPTION_IRCSERVER, 3},
  139.         {"StreetTalk_Server", DHCP_OPTION_STSERVER, 3},
  140.         {"STDA_Server", DHCP_OPTION_STDASERVER, 3},
  141.         {"NDS_Servers", DHCP_OPTION_NDSSERVERS, 3},
  142.         {"NDS_Tree_Name", DHCP_OPTION_NDSTREENAME, 1},
  143.         {"NDS_Context", 87, 1},
  144.         {"LDAP_URL", DHCP_OPTION_LDAP, 1},
  145.         {"Auto_Configure", DHCP_OPTION_AUTO_CONFIG, 7},
  146.         {"Name_Service_Search", DHCP_OPTION_NAMESERVICESEARCH, 2},
  147.         {"Subnet_Selection", DHCP_OPTION_SUBNETSELECTION, 3},
  148.         //{"DNS_Domain_Search", DHCP_OPTION_DOMAINSEARCH, 1},
  149.         {"TFTP_Phone_Server", DHCP_OPTION_TFPTSERVERIPADDRESS, 3},
  150.         //{"TFTP_Server", DHCP_OPTION_TFPTSERVERIPADDRESS, 3},
  151.         {"Call_Server", DHCP_OPTION_CALLSERVERIPADDRESS, 3},
  152.         {"Discrimination_String", DHCP_OPTION_DISCRIMINATIONSTRING, 1},
  153.         {"RemoteStatisticsServer", DHCP_OPTION_REMOTESTATISTICSSERVER, 3},
  154.         {"Phone_Http_Proxy", DHCP_OPTION_HTTPPROXYFORPHONE_SPEC, 3},
  155.         {"IP_Phone", 176, 1},
  156.         {"Next_Server", DHCP_OPTION_NEXTSERVER, 3}
  157.     };
  158.  
  159. void WINAPI ServiceControlHandler(DWORD controlCode)
  160. {
  161.     switch (controlCode)
  162.     {
  163.         case SERVICE_CONTROL_INTERROGATE:
  164.             break;
  165.  
  166.         case SERVICE_CONTROL_SHUTDOWN:
  167.         case SERVICE_CONTROL_STOP:
  168.             serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
  169.             serviceStatus.dwWaitHint = 20000;
  170.             serviceStatus.dwCheckPoint = 1;
  171.             SetServiceStatus(serviceStatusHandle, &serviceStatus);
  172.  
  173.             SetEvent(stopServiceEvent);
  174.             return;
  175.  
  176.         case SERVICE_CONTROL_PAUSE:
  177.             break;
  178.  
  179.         case SERVICE_CONTROL_CONTINUE:
  180.             break;
  181.  
  182.         default:
  183.             if (controlCode >= 128 && controlCode <= UCHAR_MAX)
  184.                 break;
  185.             else
  186.                 break;
  187.     }
  188.  
  189.     SetServiceStatus(serviceStatusHandle, &serviceStatus);
  190. }
  191.  
  192. void WINAPI ServiceMain(DWORD /*argc*/, TCHAR* /*argv*/[])
  193. {
  194.     serviceStatus.dwServiceType = SERVICE_WIN32;
  195.     serviceStatus.dwCurrentState = SERVICE_STOPPED;
  196.     serviceStatus.dwControlsAccepted = 0;
  197.     serviceStatus.dwWin32ExitCode = NO_ERROR;
  198.     serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
  199.     serviceStatus.dwCheckPoint = 0;
  200.     serviceStatus.dwWaitHint = 0;
  201.  
  202.     serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, ServiceControlHandler);
  203.  
  204.     if (serviceStatusHandle)
  205.     {
  206.         serviceStatus.dwCurrentState = SERVICE_START_PENDING;
  207.         SetServiceStatus(serviceStatusHandle, &serviceStatus);
  208.  
  209.         if (!(_beginthread(init, 0, 0) > 0))
  210.         {
  211.             if (cfig.dnsLogLevel || cfig.dhcpLogLevel)
  212.             {
  213.                 sprintf(logBuff, "Thread Creation Failed");
  214.                 logMess(logBuff, 1);
  215.             }
  216.         }
  217.  
  218.         data9 dhcpr;
  219.         data5 dnsr;
  220.         tv.tv_sec = 20;
  221.         tv.tv_usec = 0;
  222.  
  223.         stopServiceEvent = CreateEvent(0, FALSE, FALSE, 0);
  224.         serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
  225.         serviceStatus.dwCurrentState = SERVICE_RUNNING;
  226.         SetServiceStatus(serviceStatusHandle, &serviceStatus);
  227.  
  228.         do
  229.         {
  230.             network.busy = false;
  231.  
  232.             if ((!network.dhcpConn[0].server && !network.dnsUdpConn[0].server) || !network.ready)
  233.             {
  234.                 Sleep(1000);
  235.                 continue;
  236.             }
  237.  
  238.             FD_ZERO(&readfds);
  239.  
  240.             if (dhcpService)
  241.             {
  242.                 if (network.httpConn.server)
  243.                     FD_SET(network.httpConn.sock, &readfds);
  244.  
  245.                 for (int i = 0; i < MAX_SERVERS && network.dhcpConn[i].server; i++)
  246.                     FD_SET(network.dhcpConn[i].sock, &readfds);
  247.  
  248.                 if (cfig.replication)
  249.                     FD_SET(network.dhcpReplConn.sock, &readfds);
  250.             }
  251.  
  252.             if (dnsService)
  253.             {
  254.                 for (int i = 0; i < MAX_SERVERS && network.dnsUdpConn[i].server; i++)
  255.                     FD_SET(network.dnsUdpConn[i].sock, &readfds);
  256.  
  257.                 for (int i = 0; i < MAX_SERVERS && network.dnsTcpConn[i].server; i++)
  258.                     FD_SET(network.dnsTcpConn[i].sock, &readfds);
  259.  
  260.                 FD_SET(network.forwConn.sock, &readfds);
  261.             }
  262.  
  263.             if (select(network.maxFD, &readfds, NULL, NULL, &tv))
  264.             {
  265.                 if (network.ready)
  266.                 {
  267.                     network.busy = true;
  268.                     if (dhcpService)
  269.                     {
  270.                         if (network.httpConn.server && FD_ISSET(network.httpConn.sock, &readfds))
  271.                         {
  272.                             data19 *req = (data19*)calloc(1, sizeof(data19));
  273.  
  274.                             if (req)
  275.                             {
  276.                                 req->sockLen = sizeof(req->addr);
  277.                                 req->sock = accept(network.httpConn.sock, (sockaddr*)&req->addr, &req->sockLen);
  278.  
  279.                                 if (req->sock == INVALID_SOCKET)
  280.                                 {
  281.                                     sprintf(logBuff, "Accept Failed, Error=%u\n", WSAGetLastError());
  282.                                     logDHCPMess(logBuff, 2);
  283.                                     free(req);
  284.                                 }
  285.                                 else
  286.                                     procHTTP(req);
  287.                             }
  288.                             else
  289.                             {
  290.                                 sprintf(logBuff, "Memory Error");
  291.                                 logDHCPMess(logBuff, 0);
  292.                             }
  293.                         }
  294.  
  295.                         if (cfig.replication && FD_ISSET(network.dhcpReplConn.sock, &readfds))
  296.                         {
  297.                             dhcpr.sockLen = sizeof(dhcpr.addr);
  298.                             dhcpr.bytes = recvfrom(network.dhcpReplConn.sock,
  299.                                                    dhcpr.raw,
  300.                                                    sizeof(dhcpr.raw),
  301.                                                    0,
  302.                                                    (sockaddr*)&dhcpr.addr,
  303.                                                    &dhcpr.sockLen);
  304.                         }
  305.                     }
  306.  
  307.                     for (int i = 0; i < MAX_SERVERS && network.dhcpConn[i].server; i++)
  308.                     {
  309.                         if (FD_ISSET(network.dhcpConn[i].sock, &readfds) && gdmess(&dhcpr, i) && sdmess(&dhcpr))
  310.                             alad(&dhcpr);
  311.                     }
  312.  
  313.                     if (dnsService)
  314.                     {
  315.                         for (int i = 0; i < MAX_SERVERS && network.dnsUdpConn[i].server; i++)
  316.                         {
  317.                             if (FD_ISSET(network.dnsUdpConn[i].sock, &readfds))
  318.                             {
  319.                                 if (gdnmess(&dnsr, i))
  320.                                 {
  321.                                     if (dnsr.dnsp->header.rcode == RCODE_NOTIMPL || dnsr.dnsp->header.rcode == RCODE_REFUSED)
  322.                                         sdnmess(&dnsr);
  323.                                     else if (scanloc(&dnsr))
  324.                                     {
  325.                                         if (htons(dnsr.dnsp->header.ancount))
  326.                                         {
  327.                                             if (cfig.dnsLogLevel == 2)
  328.                                             {
  329.                                                 if (dnsr.qtype == DNS_TYPE_SOA)
  330.                                                     sprintf(logBuff, "SOA Sent for zone %s", dnsr.query);
  331.                                                 else if (dnsr.qtype == DNS_TYPE_NS)
  332.                                                     sprintf(logBuff, "NS Sent for zone %s", dnsr.query);
  333.                                                 else if (dnsr.cache.dataType == CACHED)
  334.                                                     sprintf(logBuff, "%s resolved from Cache to %s", dnsr.query, getResult(&dnsr));
  335.                                                 else
  336.                                                     sprintf(logBuff, "%s resolved Locally to %s", dnsr.query, getResult(&dnsr));
  337.  
  338.                                                 logDNSMess(&dnsr, logBuff, 2);
  339.                                             }
  340.                                         }
  341.                                         else if (dnsr.dnsp->header.rcode == RCODE_NAMEERROR || dnsr.dnsp->header.rcode == RCODE_NOERROR)
  342.                                         {
  343.                                             dnsr.dnsp->header.rcode = RCODE_NAMEERROR;
  344.                                             if (cfig.dnsLogLevel == 2)
  345.                                             {
  346.                                                 sprintf(logBuff, "%s not found", dnsr.query);
  347.                                                 logDNSMess(&dnsr, logBuff, 2);
  348.                                             }
  349.                                         }
  350.                                         sdnmess(&dnsr);
  351.                                     }
  352.                                     else if (!fdnmess(&dnsr))
  353.                                         sdnmess(&dnsr);
  354.                                 }
  355.                             }
  356.                         }
  357.  
  358.                         for (int i = 0; i < MAX_SERVERS && network.dnsTcpConn[i].server; i++)
  359.                         {
  360.                             if (FD_ISSET(network.dnsTcpConn[i].sock, &readfds))
  361.                             {
  362.                                 dnsr.sockInd = i;
  363.                                 dnsr.sockLen = sizeof(dnsr.addr);
  364.                                 errno = 0;
  365.                                 dnsr.sock = accept(network.dnsTcpConn[i].sock, (sockaddr*)&dnsr.addr, &dnsr.sockLen);
  366.  
  367.                                 if (dnsr.sock == INVALID_SOCKET)
  368.                                 {
  369.                                     if (cfig.dnsLogLevel)
  370.                                     {
  371.                                         sprintf(logBuff, "Accept Failed, Error=%u", WSAGetLastError());
  372.                                         logDHCPMess(logBuff, 1);
  373.                                     }
  374.                                 }
  375.                                 else
  376.                                     procTCP(&dnsr);
  377.                             }
  378.                         }
  379.  
  380.                         if (FD_ISSET(network.forwConn.sock, &readfds))
  381.                         {
  382.                             if (frdnmess(&dnsr))
  383.                             {
  384.                                 sdnmess(&dnsr);
  385.  
  386.                                 if (cfig.dnsLogLevel == 2)
  387.                                 {
  388.                                     if (dnsr.cache.dnsIndex < MAX_SERVERS)
  389.                                     {
  390.                                         if (dnsr.dnsp->header.ancount)
  391.                                         {
  392.                                             if (getResult(&dnsr))
  393.                                                 sprintf(logBuff, "%s resolved from Forwarding server as %s", dnsr.query, tempbuff);
  394.                                             else
  395.                                                 sprintf(logBuff, "%s resolved from Forwarding server", dnsr.query);
  396.                                         }
  397.                                         else
  398.                                             sprintf(logBuff, "%s not found by Forwarding Server", dnsr.query);
  399.                                     }
  400.                                     else
  401.                                     {
  402.                                         if (dnsr.dnsp->header.ancount)
  403.                                         {
  404.                                             if (getResult(&dnsr))
  405.                                                 sprintf(logBuff, "%s resolved from Child Server as %s", dnsr.query, tempbuff);
  406.                                             else
  407.                                                 sprintf(logBuff, "%s resolved from Child Server", dnsr.query);
  408.                                         }
  409.                                         else
  410.                                             sprintf(logBuff, "%s not found by Child Server", dnsr.query);
  411.                                     }
  412.  
  413.                                     logDNSMess(&dnsr, logBuff, 2);
  414.                                 }
  415.                             }
  416.                         }
  417.                     }
  418.                 }
  419.             }
  420.  
  421.             cacheInd = newInd;
  422.             checkSize(cacheInd);
  423.         }
  424.         while (WaitForSingleObject(stopServiceEvent, 0) == WAIT_TIMEOUT);
  425.  
  426.         serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
  427.         //serviceStatus.dwCheckPoint = 2;
  428.         //serviceStatus.dwWaitHint = 1000;
  429.         SetServiceStatus(serviceStatusHandle, &serviceStatus);
  430.         sprintf(logBuff, "Closing Network Connections...");
  431.         logMess(logBuff, 1);
  432.         closeConn();
  433.         sprintf(logBuff, "Dual Server Stopped !\n");
  434.         logMess(logBuff, 1);
  435.  
  436.         if (cfig.logfile)
  437.         {
  438.             fclose(cfig.logfile);
  439.             cfig.logfile = 0;
  440.         }
  441.  
  442.         WSACleanup();
  443.  
  444.         serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
  445.         serviceStatus.dwCurrentState = SERVICE_STOPPED;
  446.         SetServiceStatus(serviceStatusHandle, &serviceStatus);
  447.  
  448.         CloseHandle(stopServiceEvent);
  449.         stopServiceEvent = 0;
  450.     }
  451. }
  452.  
  453. void closeConn()
  454. {
  455.     if (network.httpConn.server)
  456.     {
  457.         closesocket(network.httpConn.sock);
  458.     }
  459.  
  460.     if (dhcpService)
  461.     {
  462.         for (int i = 0; i < MAX_SERVERS && network.dhcpConn[i].server; i++)
  463.             closesocket(network.dhcpConn[i].sock);
  464.  
  465.         if (cfig.replication)
  466.             closesocket(network.dhcpReplConn.sock);
  467.     }
  468.  
  469.     if (dnsService)
  470.     {
  471.         for (int i = 0; i < MAX_SERVERS && network.dnsUdpConn[i].server; i++)
  472.             closesocket(network.dnsUdpConn[i].sock);
  473.  
  474.         for (int i = 0; i < MAX_SERVERS && network.dnsTcpConn[i].server; i++)
  475.             closesocket(network.dnsTcpConn[i].sock);
  476.  
  477.         closesocket(network.forwConn.sock);
  478.     }
  479. }
  480.  
  481. void runService()
  482. {
  483.     SERVICE_TABLE_ENTRY serviceTable[] =
  484.         {
  485.             {serviceName, ServiceMain},
  486.             {0, 0}
  487.         };
  488.  
  489.     StartServiceCtrlDispatcher(serviceTable);
  490. }
  491.  
  492. void showError(DWORD enumber)
  493. {
  494.     LPTSTR lpMsgBuf;
  495.     FormatMessage(
  496.         FORMAT_MESSAGE_ALLOCATE_BUFFER |
  497.         FORMAT_MESSAGE_FROM_SYSTEM |
  498.         FORMAT_MESSAGE_IGNORE_INSERTS,
  499.         NULL,
  500.         enumber,
  501.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  502.         (LPTSTR)&lpMsgBuf,
  503.         0,
  504.         NULL
  505.     );
  506.     printf("%s\n", lpMsgBuf);
  507. }
  508.  
  509. bool stopService(SC_HANDLE service)
  510. {
  511.     if (service)
  512.     {
  513.         SERVICE_STATUS serviceStatus;
  514.         QueryServiceStatus(service, &serviceStatus);
  515.         if (serviceStatus.dwCurrentState != SERVICE_STOPPED)
  516.         {
  517.             ControlService(service, SERVICE_CONTROL_STOP, &serviceStatus);
  518.             printf("Stopping Service.");
  519.             for (int i = 0; i < 100; i++)
  520.             {
  521.                 QueryServiceStatus(service, &serviceStatus);
  522.                 if (serviceStatus.dwCurrentState == SERVICE_STOPPED)
  523.                 {
  524.                     printf("Stopped\n");
  525.                     return true;
  526.                 }
  527.                 else
  528.                 {
  529.                     Sleep(500);
  530.                     printf(".");
  531.                 }
  532.             }
  533.             printf("Failed\n");
  534.             return false;
  535.         }
  536.     }
  537.     return true;
  538. }
  539.  
  540. void installService()
  541. {
  542.     SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE | SERVICE_START);
  543.  
  544.     if (serviceControlManager)
  545.     {
  546.         TCHAR path[ _MAX_PATH + 1 ];
  547.         if (GetModuleFileName(0, path, sizeof(path) / sizeof(path[0])) > 0)
  548.         {
  549.             SC_HANDLE service = CreateService(serviceControlManager,
  550.                                               serviceName, displayName,
  551.                                               SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
  552.                                               SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, path,
  553.                                               0, 0, 0, 0, 0);
  554.             if (service)
  555.             {
  556.                 printf("Successfully installed.. !\n");
  557.                 StartService(service, 0, NULL);
  558.                 CloseServiceHandle(service);
  559.             }
  560.             else
  561.             {
  562.                 showError(GetLastError());
  563.             }
  564.         }
  565.         CloseServiceHandle(serviceControlManager);
  566.     }
  567. }
  568.  
  569. void uninstallService()
  570. {
  571.     SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
  572.  
  573.     if (serviceControlManager)
  574.     {
  575.         SC_HANDLE service = OpenService(serviceControlManager,
  576.                                         serviceName, SERVICE_QUERY_STATUS | SERVICE_STOP | DELETE);
  577.         if (service)
  578.         {
  579.             if (stopService(service))
  580.             {
  581.                 if (DeleteService(service))
  582.                     printf("Successfully Removed !\n");
  583.                 else
  584.                     showError(GetLastError());
  585.             }
  586.             else
  587.                 printf("Failed to Stop Service..\n");
  588.  
  589.             CloseServiceHandle(service);
  590.         }
  591.         else
  592.             printf("Service Not Found..\n");
  593.  
  594.         CloseServiceHandle(serviceControlManager);
  595.     }
  596. }
  597.  
  598. int main(int argc, TCHAR* argv[])
  599. {
  600.     OSVERSIONINFO osvi;
  601.     osvi.dwOSVersionInfoSize = sizeof(osvi);
  602.     bool result = GetVersionEx(&osvi);
  603.  
  604.     if (result && osvi.dwPlatformId >= VER_PLATFORM_WIN32_NT)
  605.     {
  606.         if (argc > 1 && lstrcmpi(argv[1], TEXT("-i")) == 0)
  607.         {
  608.             installService();
  609.         }
  610.         else if (argc > 1 && lstrcmpi(argv[1], TEXT("-u")) == 0)
  611.         {
  612.             uninstallService();
  613.         }
  614.         else if (argc > 1 && lstrcmpi(argv[1], TEXT("-v")) == 0)
  615.         {
  616.             SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
  617.             bool serviceStopped = true;
  618.  
  619.             if (serviceControlManager)
  620.             {
  621.                 SC_HANDLE service = OpenService(serviceControlManager,
  622.                                                 serviceName, SERVICE_QUERY_STATUS | SERVICE_STOP);
  623.                 if (service)
  624.                 {
  625.                     serviceStopped = stopService(service);
  626.                     CloseServiceHandle(service);
  627.                 }
  628.                 CloseServiceHandle(serviceControlManager);
  629.             }
  630.  
  631.             if (serviceStopped)
  632.                 runProg();
  633.             else
  634.                 printf("Failed to Stop Service\n");
  635.         }
  636.         else
  637.             runService();
  638.     }
  639.     else if (argc == 1 || lstrcmpi(argv[1], TEXT("-v")) == 0)
  640.         runProg();
  641.     else
  642.         printf("This option is not available on Windows95/98/ME\n");
  643.  
  644.     return 0;
  645. }
  646.  
  647. void runProg()
  648. {
  649.     //printf("%i\n",t);
  650.     //printf("%i\n",sizeof(data7));
  651.     //printf("%d\n",dnsCache[cacheInd].max_size());
  652.     verbatim = true;
  653.  
  654.     if (!(_beginthread(init, 0, 0) > 0))
  655.     {
  656.         if (cfig.dnsLogLevel || cfig.dhcpLogLevel)
  657.         {
  658.             sprintf(logBuff, "Thread Creation Failed");
  659.             logMess(logBuff, 1);
  660.         }
  661.     }
  662.  
  663.     data9 dhcpr;
  664.     data5 dnsr;            //dns request
  665.     tv.tv_sec = 20;
  666.     tv.tv_usec = 0;
  667.  
  668.     while (true)
  669.     {
  670.         //printf("Cache1=%u Cache2=%u Expiry=%u dhcp=%u\n", dnsCache[0].size(),dnsCache[1].size(),dnsAge[ind].size(),dhcpCache.size());
  671.  
  672.         network.busy = false;
  673.  
  674.         if ((!network.dhcpConn[0].server && !network.dnsUdpConn[0].server) || !network.ready)
  675.         {
  676.             Sleep(1000);
  677.             continue;
  678.         }
  679.  
  680.         FD_ZERO(&readfds);
  681.  
  682.         if (dhcpService)
  683.         {
  684.             if (network.httpConn.server)
  685.                 FD_SET(network.httpConn.sock, &readfds);
  686.  
  687.             if (cfig.replication)
  688.                 FD_SET(network.dhcpReplConn.sock, &readfds);
  689.  
  690.             for (int i = 0; i < MAX_SERVERS && network.dhcpConn[i].server; i++)
  691.                 FD_SET(network.dhcpConn[i].sock, &readfds);
  692.         }
  693.  
  694.         if (dnsService)
  695.         {
  696.             FD_SET(network.forwConn.sock, &readfds);
  697.  
  698.             for (int i = 0; i < MAX_SERVERS && network.dnsUdpConn[i].server; i++)
  699.                 FD_SET(network.dnsUdpConn[i].sock, &readfds);
  700.  
  701.             for (int i = 0; i < MAX_SERVERS && network.dnsTcpConn[i].server; i++)
  702.                 FD_SET(network.dnsTcpConn[i].sock, &readfds);
  703.         }
  704.  
  705.         //printf("dhcpCache=%u,dns0=%u,dns1=%u\n",dhcpCache.size(),dnsCache[0].size(),dnsCache[1].size());
  706.         //printf("%i\n",select(USHRT_MAX, &readfds, NULL, NULL, &tv));
  707.  
  708.         //printf("%i\n",select(USHRT_MAX, &readfds, NULL, NULL, &tv));
  709.         if (select(network.maxFD, &readfds, NULL, NULL, &tv))
  710.         {
  711.             if (network.ready)
  712.             {
  713.                 network.busy = true;
  714.  
  715.                 if (dhcpService)
  716.                 {
  717.                     if (network.httpConn.server && FD_ISSET(network.httpConn.sock, &readfds))
  718.                     {
  719.                         data19 *req = (data19*)calloc(1, sizeof(data19));
  720.  
  721.                         if (req)
  722.                         {
  723.                             req->sockLen = sizeof(req->addr);
  724.                             req->sock = accept(network.httpConn.sock, (sockaddr*)&req->addr, &req->sockLen);
  725.  
  726.                             if (req->sock == INVALID_SOCKET)
  727.                             {
  728.                                 sprintf(logBuff, "Accept Failed, Error=%u\n", WSAGetLastError());
  729.                                 logDHCPMess(logBuff, 2);
  730.                                 free(req);
  731.                             }
  732.                             else 
  733.                                 procHTTP(req);
  734.                         }
  735.                         else
  736.                         {
  737.                             sprintf(logBuff, "Memory Error");
  738.                             logDHCPMess(logBuff, 0);
  739.                         }
  740.                     }
  741.  
  742.                     if (cfig.replication && FD_ISSET(network.dhcpReplConn.sock, &readfds))
  743.                     {
  744.                         //printf("Repl\n");
  745.                         dhcpr.sockLen = sizeof(dhcpr.addr);
  746.                         dhcpr.bytes = recvfrom(network.dhcpReplConn.sock,
  747.                                                dhcpr.raw,
  748.                                                sizeof(dhcpr.raw),
  749.                                                0,
  750.                                                (sockaddr*)&dhcpr.addr,
  751.                                                &dhcpr.sockLen);
  752.                     }
  753.  
  754.                     for (int i = 0; i < MAX_SERVERS && network.dhcpConn[i].server; i++)
  755.                     {
  756.                         if (FD_ISSET(network.dhcpConn[i].sock, &readfds) && gdmess(&dhcpr, i) && sdmess(&dhcpr))
  757.                             alad(&dhcpr);
  758.                     }
  759.                 }
  760.  
  761.                 if (dnsService)
  762.                 {
  763.                     for (int i = 0; i < MAX_SERVERS && network.dnsUdpConn[i].server; i++)
  764.                     {
  765.                         if (FD_ISSET(network.dnsUdpConn[i].sock, &readfds))
  766.                         {
  767.                             if (gdnmess(&dnsr, i))        //-- get dns query 
  768.                             {
  769.                                 if (dnsr.dnsp->header.rcode == RCODE_NOTIMPL || dnsr.dnsp->header.rcode == RCODE_REFUSED)
  770.                                 {
  771.                                     sdnmess(&dnsr);
  772.                                 }
  773.                                 else if (scanloc(&dnsr))    //-- solve domain name locally 
  774.                                 {
  775.                                     if (htons(dnsr.dnsp->header.ancount))    //-- if there are answers, print a message.
  776.                                     {
  777.                                         if (dnsr.qtype == DNS_TYPE_SOA)
  778.                                             printf("SOA Sent for zone %s\n", dnsr.query);
  779.                                         else if (dnsr.qtype == DNS_TYPE_NS)
  780.                                             printf("NS Sent for zone %s\n", dnsr.query);
  781.                                         else if (dnsr.cache.dataType == CACHED)
  782.                                             printf("%s resolved from Cache to %s\n", dnsr.query, getResult(&dnsr));
  783.                                         else
  784.                                             printf("%s resolved Locally to %s\n", dnsr.query, getResult(&dnsr));
  785.                                     }    //-- else: cannot find the IP of the domain name, set response code as RCODE_NAMEERROR and print a message
  786.                                     else if (dnsr.dnsp->header.rcode == RCODE_NAMEERROR || dnsr.dnsp->header.rcode == RCODE_NOERROR)
  787.                                     {
  788.                                         dnsr.dnsp->header.rcode = RCODE_NAMEERROR;
  789.                                         printf("%s not found\n", dnsr.query);
  790.                                     }
  791.                                     sdnmess(&dnsr);        //-- send dns messages back to clients
  792.                                 }
  793.                                 else if (!fdnmess(&dnsr))    //-- forward to child server
  794.                                     sdnmess(&dnsr);
  795.                             }
  796.                         }
  797.                     }
  798.  
  799.                     for (int i = 0; i < MAX_SERVERS && network.dnsTcpConn[i].server; i++)
  800.                     {
  801.                         if (FD_ISSET(network.dnsTcpConn[i].sock, &readfds))
  802.                         {
  803.                             dnsr.sockInd = i;
  804.                             dnsr.sockLen = sizeof(dnsr.addr);
  805.                             errno = 0;
  806.                             dnsr.sock = accept(network.dnsTcpConn[i].sock, (sockaddr*)&dnsr.addr, &dnsr.sockLen);
  807.  
  808.                             if (dnsr.sock == INVALID_SOCKET)
  809.                                 printf("Accept Failed, Error=%u", WSAGetLastError());
  810.                             else 
  811.                                 procTCP(&dnsr);
  812.                         }
  813.                     }
  814.  
  815.                     if (FD_ISSET(network.forwConn.sock, &readfds))
  816.                     {
  817.                         if (frdnmess(&dnsr))    //-- get the forward response DNS message    
  818.                         {
  819.                             sdnmess(&dnsr);        //-- send the DNS result back to clients
  820.  
  821.                             //-- print results
  822.                             if (dnsr.cache.dnsIndex < MAX_SERVERS)
  823.                             {    
  824.                                 if (dnsr.dnsp->header.ancount)
  825.                                 {
  826.                                     if (getResult(&dnsr))
  827.                                         printf("%s resolved from Forwarding server as %s\n", dnsr.query, tempbuff);
  828.                                     else
  829.                                         printf("%s resolved from Forwarding server\n", dnsr.query);
  830.                                 }
  831.                                 else
  832.                                     printf("%s not found by Forwarding Server\n", dnsr.query);
  833.                             }
  834.                             else
  835.                             {
  836.                                 if (dnsr.dnsp->header.ancount)
  837.                                 {
  838.                                     if (getResult(&dnsr))
  839.                                         printf("%s resolved from Child Server as %s\n", dnsr.query, tempbuff);
  840.                                     else
  841.                                         printf("%s resolved from Child Server\n", dnsr.query);
  842.                                 }
  843.                                 else
  844.                                     printf("%s not found by Child Server\n", dnsr.query);
  845.                             }
  846.                         }
  847.                     }
  848.                 }
  849.             }
  850.  
  851.             cacheInd = newInd;
  852.             checkSize(cacheInd);
  853.         }
  854.     }
  855.  
  856.     sprintf(logBuff, "Closing Network Connections...");
  857.     logMess(logBuff, 1);
  858.     closeConn();
  859.     sprintf(logBuff, "Dual Server Stopped !\n");
  860.     logMess(logBuff, 1);
  861.  
  862.     if (cfig.logfile)
  863.     {
  864.         fclose(cfig.logfile);
  865.         cfig.logfile = 0;
  866.     }
  867.  
  868.     WSACleanup();
  869. }
  870.  
  871. bool chkQu(char *query)
  872. {
  873.     if (strlen(query) >= 255)
  874.         return 0;
  875.  
  876.     while (true)
  877.     {
  878.         char *dp = strchr(query, '.');
  879.         if (dp)
  880.         {
  881.             WORD size = (DWORD)dp - (DWORD)query;
  882.             if (size >= 64)
  883.                 return 0;
  884.             query += (size + 1);
  885.         }
  886.         else if (strlen(query) >= 64)
  887.             return 0;
  888.         else
  889.             return 1;
  890.     }
  891. }
  892.  
  893. WORD fQu(char *query, dnsPacket *mess, char *raw)
  894. {
  895.     BYTE *xname = (BYTE*)query;
  896.     BYTE *xraw = (BYTE*)raw;
  897.     WORD retvalue = 0;
  898.     bool goneout = false;
  899.     while (true)
  900.     {
  901.         BYTE size = *xraw;
  902.         xraw++;
  903.  
  904.         if (!size)
  905.         {
  906.             break;
  907.         }
  908.         else if (size <= 63)
  909.         {
  910.             if (!goneout)
  911.                 retvalue += (size + 1);
  912.  
  913.             memcpy(xname, xraw, size);
  914.             xname += size;
  915.             xraw += size;
  916.  
  917.             if (!*xraw)
  918.                 break;
  919.  
  920.             *xname = '.';
  921.             xname++;
  922.         }
  923.         else
  924.         {
  925.             if (!goneout)
  926.                 retvalue += 2;
  927.  
  928.             goneout = true;
  929.             size %= 128;
  930.             size %= 64;
  931.             size *= 256;
  932.             size += *xraw;
  933.             xraw = (BYTE*)mess + size;
  934.         }
  935.     }
  936.     *xname = 0;
  937.  
  938.     if (!goneout)
  939.         retvalue++;
  940.  
  941.     return retvalue;
  942. }
  943.  
  944. WORD qLen(char *query)
  945. {
  946.     WORD fullsize = 1;
  947.     while (true)
  948.     {
  949.         char *i = strchr(query, '.');
  950.         if (i != NULL)
  951.         {
  952.             int size = (DWORD)i - (DWORD)query;
  953.             query += (size + 1);
  954.             fullsize += (size + 1);
  955.         }
  956.         else
  957.         {
  958.             int size = strlen(query);
  959.             if (size)
  960.                 fullsize += (size + 1);
  961.             break;
  962.         }
  963.     }
  964.     //printf("%i\n",fullsize);
  965.     return fullsize;
  966. }
  967.  
  968. WORD pQu(char *raw, char *query)
  969. {
  970.     WORD fullsize = 1;
  971.     while (true)
  972.     {
  973.         char *i = strchr(query, '.');
  974.         if (i != NULL)
  975.         {
  976.             int size = (DWORD)i - (DWORD)query;
  977.             *raw = size;
  978.             raw++;
  979.             memcpy(raw, query, size);
  980.             raw += size;
  981.             query += (size + 1);
  982.             fullsize += (size + 1);
  983.         }
  984.         else
  985.         {
  986.             int size = strlen(query);
  987.             if (size)
  988.             {
  989.                 *raw = size;
  990.                 raw++;
  991.                 strcpy(raw, query);
  992.                 fullsize += (size + 1);
  993.             }
  994.             break;
  995.         }
  996.     }
  997.     //printf("%i\n",fullsize);
  998.     return fullsize;
  999. }
  1000.  
  1001. WORD fUShort(void *raw)
  1002. {
  1003.     return ntohs(*(WORD*)raw);
  1004. }
  1005.  
  1006. DWORD fULong(void *raw)
  1007. {
  1008.     return ntohl(*(DWORD*)raw);
  1009. }
  1010.  
  1011. DWORD fIP(void *raw)
  1012. {
  1013.     return (*(DWORD*)raw);
  1014. }
  1015.  
  1016. BYTE pUShort(void *raw, WORD data)
  1017. {
  1018.     *((WORD*)raw) = htons(data);
  1019.     return 2;
  1020. }
  1021.  
  1022. BYTE pULong(void *raw, DWORD data)
  1023. {
  1024.     *((DWORD*)raw) = htonl(data);
  1025.     return 4;
  1026. }
  1027.  
  1028. BYTE pIP(void *raw, DWORD data)
  1029. {
  1030.     *((DWORD*)raw) = data;
  1031.     return 4;
  1032. }
  1033.  
  1034. void addRRNone(data5 *req)
  1035. {
  1036.     if (network.dns[0])
  1037.         req->dnsp->header.ra = 1;
  1038.     else
  1039.         req->dnsp->header.ra = 0;
  1040.  
  1041.     req->dnsp->header.at = 0;
  1042.     req->dnsp->header.aa = 0;
  1043.  
  1044.     req->dnsp->header.qr = 1;
  1045.     req->dnsp->header.ancount = 0;
  1046.     req->dnsp->header.nscount = 0;
  1047.     req->dnsp->header.adcount = 0;
  1048. }
  1049.  
  1050. void addRRExt(data5 *req)
  1051. {
  1052.     //printf("%u=%u\n", req->cache.dataType, CACHED);
  1053.  
  1054.     WORD xid = req->dnsp->header.xid;
  1055.  
  1056.     if (strcasecmp(req->cname, req->query))
  1057.     {
  1058.         dnsPacket *packet;
  1059.  
  1060.         if (req->cache.dataType == CACHED && req->cache.response)
  1061.             packet = (dnsPacket*)req->cache.response;
  1062.         else
  1063.         {
  1064.             memcpy(req->temp, req->dnsp, req->bytes);
  1065.             packet = (dnsPacket*)req->temp;
  1066.         }
  1067.  
  1068.         req->dnsp->header.aa = 0;
  1069.         req->dnsp->header.at = 0;
  1070.         req->dnsp->header.qdcount = htons(1);
  1071.         req->dnsp->header.ancount = htons(1);
  1072.  
  1073.         //manuplate the response
  1074.         req->data = &req->dnsp->data;
  1075.         req->data += pQu(req->data, req->query);
  1076.         req->data += pUShort(req->data, DNS_TYPE_A);
  1077.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1078.         req->data += pQu(req->data, req->query);
  1079.         req->data += pUShort(req->data, DNS_TYPE_CNAME);
  1080.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1081.         req->data += pULong(req->data, cfig.ttl);
  1082.         req->data += pUShort(req->data, qLen(req->cname));
  1083.         req->data += pQu(req->data, req->cname);
  1084.  
  1085.         char *dp = &packet->data;
  1086.  
  1087.         for (int i = 1; i <= ntohs(packet->header.qdcount); i++)
  1088.         {
  1089.             dp += fQu(req->cname, packet, dp);
  1090.             dp += 4;
  1091.         }
  1092.  
  1093.         WORD dl = 0;
  1094.         for (int i = 1; i <= ntohs(packet->header.ancount); i++)
  1095.         {
  1096.             dp += fQu(req->cname, packet, dp);
  1097.             req->data += pQu(req->data, req->cname);
  1098.             memcpy(req->data, dp, 8);
  1099.             req->data += 8;
  1100.             int type = fUShort(dp);
  1101.             dp += 2; //type
  1102.             dp += 2; //class
  1103.             dp += 4; //ttl
  1104.             WORD zLen = fUShort(dp);
  1105.             dp += 2; //datalength
  1106.  
  1107.             switch (type)
  1108.             {
  1109.                 case DNS_TYPE_A:
  1110.                     req->data += pUShort(req->data, zLen);
  1111.                     req->data += pULong(req->data, fULong(dp));
  1112.                     break;
  1113.                 case DNS_TYPE_CNAME:
  1114.                     fQu(req->cname, packet, dp);
  1115.                     dl = pQu(req->data + 2, req->cname);
  1116.                     req->data += pUShort(req->data, dl);
  1117.                     req->data += dl;
  1118.                     break;
  1119.             }
  1120.             dp += zLen;
  1121.             req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1122.         }
  1123.  
  1124.         req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1125.     }
  1126.     else if (req->cache.dataType == CACHED && req->cache.response)
  1127.     {
  1128.         memcpy(req->dnsp, req->cache.response, req->cache.bytes);
  1129.         req->dnsp->header.xid = xid;
  1130.         req->bytes = req->cache.bytes;
  1131.     }
  1132. }
  1133.  
  1134. void addRRA(data5 *req)
  1135. {
  1136.     if (strcasecmp(req->query, req->cname))
  1137.     {
  1138.         req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1139.         req->data += pQu(req->data, req->query);
  1140.         req->data += pUShort(req->data, DNS_TYPE_CNAME);
  1141.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1142.         req->data += pULong(req->data, cfig.ttl);
  1143.         req->data += pUShort(req->data, qLen(req->cname));
  1144.         req->data += pQu(req->data, req->cname);
  1145.     }
  1146.  
  1147.     for (;req->iterBegin != dnsCache[cacheInd].end(); req->iterBegin++)
  1148.     {
  1149.         data7 *cache = req->iterBegin->second;
  1150.  
  1151.         if (strcasecmp(cache->mapname, req->mapname))
  1152.             break;
  1153.  
  1154.         if (cache->ip)
  1155.         {
  1156.             req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1157.             req->data += pQu(req->data, req->cname);
  1158.             req->data += pUShort(req->data, DNS_TYPE_A);
  1159.             req->data += pUShort(req->data, DNS_CLASS_IN);
  1160.  
  1161.             if (cache->dataType == LOCAL_A)
  1162.             {
  1163.                 if (cache->expiry == LONG_MAX)
  1164.                     req->data += pULong(req->data, ULONG_MAX);
  1165.                 else if ((DWORD)(cache->expiry - time(NULL)) >= cfig.ttl)
  1166.                     req->data += pULong(req->data, cfig.ttl - 1);
  1167.                 else
  1168.                     req->data += pULong(req->data, (cache->expiry - time(NULL)));
  1169.             }
  1170.             else
  1171.                 req->data += pULong(req->data, cfig.ttl);
  1172.  
  1173.             req->data += pUShort(req->data, 4);
  1174.             req->data += pIP(req->data, cache->ip);
  1175.         }
  1176.     }
  1177.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1178. }
  1179.  
  1180. void addRRPtr(data5 *req)
  1181. {
  1182.     for (;req->iterBegin != dnsCache[cacheInd].end(); req->iterBegin++)
  1183.     {
  1184.         data7 *cache = req->iterBegin->second;
  1185.  
  1186.         if (strcasecmp(cache->mapname, req->mapname))
  1187.             break;
  1188.  
  1189.         req->data += pQu(req->data, req->query);
  1190.         req->data += pUShort(req->data, DNS_TYPE_PTR);
  1191.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1192.         req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1193.  
  1194.         if (cache->dataType == LOCAL_PTR_AUTH || cache->dataType == LOCAL_PTR_NAUTH)
  1195.         {
  1196.             if (cache->expiry == LONG_MAX)
  1197.                 req->data += pULong(req->data, ULONG_MAX);
  1198.             else if ((DWORD)(cache->expiry - time(NULL)) >= cfig.ttl)
  1199.                 req->data += pULong(req->data, cfig.ttl - 1);
  1200.             else
  1201.                 req->data += pULong(req->data, (cache->expiry - time(NULL)));
  1202.         }
  1203.         else
  1204.             req->data += pULong(req->data, cfig.ttl);
  1205.  
  1206.         if (!strchr(cache->hostname, '.'))
  1207.             sprintf(req->cname, "%s.%s", cache->hostname, cfig.zone);
  1208.         else
  1209.             strcpy(req->cname, cache->hostname);
  1210.  
  1211.         req->data += pUShort(req->data, qLen(req->cname));
  1212.         req->data += pQu(req->data, req->cname);
  1213.     }
  1214.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1215. }
  1216.  
  1217. void addRRServerA(data5 *req)
  1218. {
  1219.     if (strcasecmp(req->query, req->cname))
  1220.     {
  1221.         req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1222.         req->data += pQu(req->data, req->query);
  1223.         req->data += pUShort(req->data, DNS_TYPE_CNAME);
  1224.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1225.         req->data += pULong(req->data, cfig.ttl);
  1226.         req->data += pUShort(req->data, qLen(req->cname));
  1227.         req->data += pQu(req->data, req->cname);
  1228.     }
  1229.  
  1230.     req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1231.     req->data += pQu(req->data, req->cname);
  1232.     req->data += pUShort(req->data, DNS_TYPE_A);
  1233.     req->data += pUShort(req->data, DNS_CLASS_IN);
  1234.     req->data += pULong(req->data, cfig.ttl);
  1235.     req->data += pUShort(req->data, 4);
  1236.     req->data += pIP(req->data, network.dnsUdpConn[req->sockInd].server);
  1237.  
  1238.     for (;req->iterBegin != dnsCache[cacheInd].end(); req->iterBegin++)
  1239.     {
  1240.         data7 *cache = req->iterBegin->second;
  1241.  
  1242.         if (strcasecmp(cache->mapname, req->mapname))
  1243.             break;
  1244.  
  1245.         if (cache->ip && cache->ip != network.dnsUdpConn[req->sockInd].server)
  1246.         {
  1247.             req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1248.             req->data += pQu(req->data, req->cname);
  1249.             req->data += pUShort(req->data, DNS_TYPE_A);
  1250.             req->data += pUShort(req->data, DNS_CLASS_IN);
  1251.             req->data += pULong(req->data, cfig.ttl);
  1252.             req->data += pUShort(req->data, 4);
  1253.             req->data += pIP(req->data, cache->ip);
  1254.         }
  1255.     }
  1256.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1257. }
  1258.  
  1259. void addRRWildA(data5 *req, DWORD ip)
  1260. {
  1261.     req->dnsp->header.ancount = htons(1);
  1262.     req->data += pQu(req->data, req->query);
  1263.     req->data += pUShort(req->data, DNS_TYPE_A);
  1264.     req->data += pUShort(req->data, DNS_CLASS_IN);
  1265.     req->data += pULong(req->data, cfig.ttl);
  1266.     req->data += pUShort(req->data, 4);
  1267.     req->data += pIP(req->data, ip);
  1268.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1269. }
  1270.  
  1271. void addRRLocalhostA(data5 *req)
  1272. {
  1273.     if (strcasecmp(req->query, req->mapname))
  1274.     {
  1275.         req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1276.         req->data += pQu(req->data, req->query);
  1277.         req->data += pUShort(req->data, DNS_TYPE_CNAME);
  1278.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1279.         req->data += pULong(req->data, cfig.ttl);
  1280.         req->data += pUShort(req->data, qLen(req->mapname));
  1281.         req->data += pQu(req->data, req->mapname);
  1282.     }
  1283.  
  1284.     req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1285.     req->data += pQu(req->data, req->mapname);
  1286.     req->data += pUShort(req->data, DNS_TYPE_A);
  1287.     req->data += pUShort(req->data, DNS_CLASS_IN);
  1288.     req->data += pULong(req->data, cfig.ttl);
  1289.     req->data += pUShort(req->data, 4);
  1290.     req->data += pIP(req->data, req->cache.ip);
  1291.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1292. }
  1293.  
  1294. void addRRLocalhostPtr(data5 *req)
  1295. {
  1296.     req->data += pQu(req->data, req->query);
  1297.     req->data += pUShort(req->data, DNS_TYPE_PTR);
  1298.     req->data += pUShort(req->data, DNS_CLASS_IN);
  1299.     req->dnsp->header.ancount = htons(1);
  1300.     req->data += pULong(req->data, cfig.ttl);
  1301.     req->data += pUShort(req->data, qLen(req->cache.hostname));
  1302.     req->data += pQu(req->data, req->cache.hostname);
  1303.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1304. }
  1305.  
  1306. void addRRMX(data5 *req)
  1307. {
  1308.     req->dnsp->header.ancount = 0;
  1309.  
  1310.     if (cfig.mxCount[cacheInd])
  1311.     {
  1312.         for (int m = 0; m < cfig.mxCount[cacheInd]; m++)
  1313.         {
  1314.             //req->data += pQu(req->data, req->query);
  1315.             req->data += pQu(req->data, cfig.zone);
  1316.             req->data += pUShort(req->data, DNS_TYPE_MX);
  1317.             req->data += pUShort(req->data, DNS_CLASS_IN);
  1318.             req->data += pULong(req->data, cfig.ttl);
  1319.             req->data += pUShort(req->data, strlen(cfig.mxServers[cacheInd][m].hostname) + 4);
  1320.             req->data += pUShort(req->data, cfig.mxServers[cacheInd][m].pref);
  1321.             req->data += pQu(req->data, cfig.mxServers[cacheInd][m].hostname);
  1322.             req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1323.         }
  1324.     }
  1325.     else
  1326.         req->dnsp->header.rcode = RCODE_NAMEERROR;
  1327.  
  1328.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1329. }
  1330.  
  1331. void addRRNSA(data5 *req)
  1332. {
  1333.     //printf("%s=%u\n", cfig.ns, cfig.expireTime);
  1334.     if (cfig.authorized && cfig.expireTime > time(NULL))
  1335.     {
  1336.         req->dnsp->header.at = 1;
  1337.         req->dnsp->header.aa = 1;
  1338.         req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1339.  
  1340.         req->data += pQu(req->data, cfig.zone);
  1341.         req->data += pUShort(req->data, DNS_TYPE_NS);
  1342.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1343.  
  1344.         req->data += pULong(req->data, cfig.expire);
  1345.  
  1346.         req->data += pUShort(req->data, qLen(cfig.ns));
  1347.         req->data += pQu(req->data, cfig.ns);
  1348.  
  1349.         req->data += pQu(req->data, cfig.servername_fqn);
  1350.         req->data += pUShort(req->data, DNS_TYPE_A);
  1351.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1352.  
  1353.         req->data += pULong(req->data, cfig.expire);
  1354.  
  1355.         req->data += pUShort(req->data, 4);
  1356.         req->data += pIP(req->data, cfig.nsIP);
  1357.     }
  1358.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1359. }
  1360.  
  1361. void addRRNSPtr(data5 *req)
  1362. {
  1363.     if (cfig.authorized && cfig.expireTime > time(NULL))
  1364.     {
  1365.         req->dnsp->header.at = 1;
  1366.         req->dnsp->header.aa = 1;
  1367.         req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1368.  
  1369.         req->data += pQu(req->data, cfig.authority);
  1370.         req->data += pUShort(req->data, DNS_TYPE_NS);
  1371.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1372.  
  1373.         req->data += pULong(req->data, cfig.expire);
  1374.  
  1375.         req->data += pUShort(req->data, qLen(cfig.ns));
  1376.         req->data += pQu(req->data, cfig.ns);
  1377.  
  1378.         req->data += pQu(req->data, cfig.ns);
  1379.         req->data += pUShort(req->data, DNS_TYPE_A);
  1380.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1381.  
  1382.         req->data += pULong(req->data, cfig.expire);
  1383.  
  1384.         req->data += pUShort(req->data, 4);
  1385.         req->data += pIP(req->data, cfig.nsIP);
  1386.     }
  1387.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1388. }
  1389.  
  1390. void addRRSOA(data5 *req, DWORD serial)
  1391. {
  1392.     if (cfig.authorized)
  1393.     {
  1394.         req->dnsp->header.at = 1;
  1395.         req->dnsp->header.aa = 1;
  1396.         req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1397.  
  1398.         req->data += pQu(req->data, req->query);
  1399.         req->data += pUShort(req->data, DNS_TYPE_SOA);
  1400.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1401.         req->data += pULong(req->data, cfig.ttl);
  1402.         char *data = req->data;
  1403.         req->data += 2;
  1404.         req->data += pQu(req->data, cfig.ns);
  1405.         sprintf(req->cname, "hostmaster.%s", cfig.zone);
  1406.         req->data += pQu(req->data, req->cname);
  1407.         req->data += pULong(req->data, serial);
  1408.         req->data += pULong(req->data, cfig.refresh);
  1409.         req->data += pULong(req->data, cfig.retry);
  1410.         req->data += pULong(req->data, cfig.expire);
  1411.         req->data += pULong(req->data, cfig.minimum);
  1412.         pUShort(data, ((DWORD)req->data - (DWORD)data) - 2);
  1413.     }
  1414.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1415. }
  1416.  
  1417. void addAuth(data5 *req)
  1418. {
  1419.     if (cfig.authorized && cfig.expireTime > time(NULL))
  1420.     {
  1421.         req->dnsp->header.at = 1;
  1422.         req->dnsp->header.aa = 1;
  1423.  
  1424.         req->dnsp->header.nscount = htons(1);
  1425.  
  1426.         if (req->qtype == DNS_TYPE_PTR)
  1427.             req->data += pQu(req->data, cfig.authority);
  1428.         else
  1429.             req->data += pQu(req->data, cfig.zone);
  1430.  
  1431.         req->data += pUShort(req->data, DNS_TYPE_NS);
  1432.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1433.  
  1434.         if (cfig.expire >= LONG_MAX)
  1435.             req->data += pULong(req->data, ULONG_MAX);
  1436.         else
  1437.             req->data += pULong(req->data, cfig.expire);
  1438.  
  1439.         req->data += pUShort(req->data, qLen(cfig.ns));
  1440.         req->data += pQu(req->data, cfig.ns);
  1441.  
  1442.         addRRAd(req);
  1443.     }
  1444.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1445. }
  1446.  
  1447. void addRRAd(data5 *req)
  1448. {
  1449.     if (cfig.authorized && cfig.expireTime > time(NULL))
  1450.     {
  1451.         req->dnsp->header.adcount = htons(1);
  1452.  
  1453.         req->data += pQu(req->data, cfig.ns);
  1454.         req->data += pUShort(req->data, DNS_TYPE_A);
  1455.         req->data += pUShort(req->data, DNS_CLASS_IN);
  1456.         req->data += pULong(req->data, cfig.ttl);
  1457.         req->data += pUShort(req->data, 4);
  1458.         req->data += pIP(req->data, cfig.nsIP);
  1459.     }
  1460.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1461. }
  1462.  
  1463. void addRRAOne(data5 *req)
  1464. {
  1465.     req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1466.  
  1467.     if (!strchr(req->iterBegin->second->mapname, '.'))
  1468.         sprintf(req->cname, "%s.%s", req->iterBegin->second->mapname, cfig.zone);
  1469.     else
  1470.         strcpy(req->cname, req->iterBegin->second->mapname);
  1471.  
  1472.     req->data += pQu(req->data, req->cname);
  1473.     req->data += pUShort(req->data, DNS_TYPE_A);
  1474.     req->data += pUShort(req->data, DNS_CLASS_IN);
  1475.  
  1476.     if (req->iterBegin->second->dataType == LOCAL_A)
  1477.     {
  1478.         if (req->iterBegin->second->expiry == LONG_MAX)
  1479.             req->data += pULong(req->data, ULONG_MAX - 1);
  1480.         else if ((DWORD)(req->iterBegin->second->expiry - time(NULL)) >= cfig.ttl)
  1481.             req->data += pULong(req->data, cfig.ttl - 1);
  1482.         else
  1483.             req->data += pULong(req->data, (req->iterBegin->second->expiry - time(NULL)));
  1484.     }
  1485.     else
  1486.         req->data += pULong(req->data, cfig.ttl);
  1487.  
  1488.     req->data += pUShort(req->data, 4);
  1489.     req->data += pIP(req->data, req->iterBegin->second->ip);
  1490.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1491. }
  1492.  
  1493. void addRRPtrOne(data5 *req)
  1494. {
  1495.     req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1496.     strcpy(req->cname, req->iterBegin->second->mapname);
  1497.     strcat(req->cname, arpa);
  1498.     req->data += pQu(req->data, req->cname);
  1499.     req->data += pUShort(req->data, DNS_TYPE_PTR);
  1500.     req->data += pUShort(req->data, DNS_CLASS_IN);
  1501.  
  1502.     if (req->iterBegin->second->dataType == LOCAL_PTR_AUTH || req->iterBegin->second->dataType == LOCAL_PTR_NAUTH)
  1503.     {
  1504.         if (req->iterBegin->second->expiry == LONG_MAX)
  1505.             req->data += pULong(req->data, ULONG_MAX - 1);
  1506.         else if ((DWORD)(req->iterBegin->second->expiry - time(NULL)) >= cfig.ttl)
  1507.             req->data += pULong(req->data, cfig.ttl - 1);
  1508.         else
  1509.             req->data += pULong(req->data, (req->iterBegin->second->expiry - time(NULL)));
  1510.     }
  1511.     else
  1512.         req->data += pULong(req->data, cfig.ttl);
  1513.  
  1514.     if (!strchr(req->iterBegin->second->hostname, '.'))
  1515.         sprintf(req->cname, "%s.%s", req->iterBegin->second->hostname, cfig.zone);
  1516.     else
  1517.         strcpy(req->cname, req->iterBegin->second->hostname);
  1518.  
  1519.     req->data += pUShort(req->data, qLen(req->cname));
  1520.     req->data += pQu(req->data, req->cname);
  1521.  
  1522.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1523. }
  1524.  
  1525. void addRRSTAOne(data5 *req)
  1526. {
  1527.     req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1528.  
  1529.     if (!strchr(req->iterBegin->second->mapname, '.'))
  1530.         sprintf(req->cname, "%s.%s", req->iterBegin->second->mapname, cfig.zone);
  1531.     else
  1532.         strcpy(req->cname, req->iterBegin->second->mapname);
  1533.  
  1534.     req->data += pQu(req->data, req->cname);
  1535.     req->data += pUShort(req->data, DNS_TYPE_A);
  1536.     req->data += pUShort(req->data, DNS_CLASS_IN);
  1537.     req->data += pULong(req->data, cfig.ttl);
  1538.     req->data += pUShort(req->data, 4);
  1539.     req->data += pIP(req->data, req->iterBegin->second->ip);
  1540.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1541. }
  1542.  
  1543. void addRRCNOne(data5 *req)
  1544. {
  1545.     req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1546.  
  1547.     if (!strchr(req->iterBegin->second->mapname, '.'))
  1548.         sprintf(req->cname, "%s.%s", req->iterBegin->second->mapname, cfig.zone);
  1549.     else
  1550.         strcpy(req->cname, req->iterBegin->second->mapname);
  1551.  
  1552.     req->data += pQu(req->data, req->cname);
  1553.     req->data += pUShort(req->data, DNS_TYPE_CNAME);
  1554.     req->data += pUShort(req->data, DNS_CLASS_IN);
  1555.     req->data += pULong(req->data, cfig.ttl);
  1556.  
  1557.     if (!strchr(req->iterBegin->second->hostname, '.'))
  1558.         sprintf(req->cname, "%s.%s", req->iterBegin->second->hostname, cfig.zone);
  1559.     else
  1560.         strcpy(req->cname, req->iterBegin->second->hostname);
  1561.  
  1562.     req->data += pUShort(req->data, qLen(req->cname));
  1563.     req->data += pQu(req->data, req->cname);
  1564.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1565. }
  1566.  
  1567. void addRRMXOne(data5 *req, BYTE m)
  1568. {
  1569.     //req->data += pQu(req->data, req->query);
  1570.     req->data += pQu(req->data, cfig.zone);
  1571.     req->data += pUShort(req->data, DNS_TYPE_MX);
  1572.     req->data += pUShort(req->data, DNS_CLASS_IN);
  1573.     req->data += pULong(req->data, cfig.ttl);
  1574.     req->data += pUShort(req->data, strlen(cfig.mxServers[cacheInd][m].hostname) + 4);
  1575.     req->data += pUShort(req->data, cfig.mxServers[cacheInd][m].pref);
  1576.     req->data += pQu(req->data, cfig.mxServers[cacheInd][m].hostname);
  1577.     req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
  1578.     req->bytes = (DWORD)req->data - (DWORD)req->raw;
  1579. }
  1580.  
  1581. void procHTTP(data19 *req)
  1582. {
  1583.     req->ling.l_onoff = 1; //0 = off (l_linger ignored), nonzero = on
  1584.     req->ling.l_linger = 30; //0 = discard data, nonzero = wait for data sent
  1585.     setsockopt(req->sock, SOL_SOCKET, SO_LINGER, (const char*)&req->ling, sizeof(req->ling));
  1586.  
  1587.     time_t t = time(NULL);
  1588.     BYTE bp_chaddr[16];
  1589.     dhcpMap::iterator p;
  1590.     int ind = 0;
  1591.     DWORD iip = 0;
  1592.     data7 *dhcpEntry = NULL;
  1593.     data7 *cache = NULL;
  1594.     DWORD memSize = 2048 + (135 * dhcpCache.size()) + ((cfig.dhcpSize - dhcpCache.size()) * 26);
  1595.     req->buffer = (char*)calloc(1, memSize);
  1596.  
  1597.     if (!req->buffer)
  1598.     {
  1599.         sprintf(logBuff, "Memory Error");
  1600.         logDHCPMess(logBuff, 0);
  1601.         closesocket(req->sock);
  1602.         free(req);
  1603.         return;
  1604.     }
  1605.  
  1606.     errno = 0;
  1607.     req->bytes = recv(req->sock, req->buffer, memSize, 0);
  1608.     errno = WSAGetLastError();
  1609.  
  1610.     if (errno)
  1611.     {
  1612.         sprintf(logBuff, "Client %s, HTTP Message Receive failed, Error %u", IP2String(tempbuff, req->addr.sin_addr.s_addr), errno);
  1613.         logDHCPMess(logBuff, 1);
  1614.         free(req->buffer);
  1615.         closesocket(req->sock);
  1616.         free(req);
  1617.         return;
  1618.     }
  1619.     else if (cfig.dnsLogLevel >= 2)
  1620.     {
  1621.         //sprintf(logBuff, "Client %s, HTTP Request Received", IP2String(tempbuff, req->addr.sin_addr.s_addr));
  1622.         //logDHCPMess(logBuff, 2);
  1623.         //printf("%s\n", req->buffer);
  1624.     }
  1625.  
  1626.     char *fp = req->buffer;
  1627.     char *maxData = req->buffer + (memSize - 512);
  1628.     tm *ttm = gmtime(&t);
  1629.     strftime(tempbuff, sizeof(tempbuff), "%a, %d %b %Y %H:%M:%S GMT", ttm);
  1630.     fp += sprintf(fp, send200, tempbuff, tempbuff);
  1631.     char *contentStart = fp;
  1632.     fp += sprintf(fp, "<html>\n<head>\n<META HTTP-EQUIV=\"Refresh\" CONTENT=\"60\">\n<META HTTP-EQUIV=\"Cache-Control\" CONTENT=\"no-cache\">\n</head>\n");
  1633.     fp += sprintf(fp, "<body bgcolor=\"#cccccc\">\n<h2>%s</h2>\n", sVersion);
  1634.     fp += sprintf(fp, "<table id=\"active\" border=\"1\" width=\"800\" bgcolor=\"#b8b8b8\">\n");
  1635.     fp += sprintf(fp, "<tr><th colspan=\"5\"><font size=\"5\"><i>Active Leases</i></font></th></tr>\n");
  1636.     fp += sprintf(fp, "<tr><th>Mac Address</th><th>IP</th><th>Lease Expiry</th><th>Hostname (first 20 chars)</th><th>Vendor Class Identifier</th></tr>\n");
  1637.  
  1638.     for (p = dhcpCache.begin(); p != dhcpCache.end() && fp < maxData; p++)
  1639.     {
  1640.         if ((dhcpEntry = p->second) && dhcpEntry->local && dhcpEntry->expiry >= t)
  1641.         {
  1642.             fp += sprintf(fp, "<tr>");
  1643.             BYTE bp_hlen = fromUUE(bp_chaddr, dhcpEntry->mapname);
  1644.             fp += sprintf(fp, line200, hex2String(tempbuff, bp_chaddr, bp_hlen, ':'));
  1645.             fp += sprintf(fp, line200, IP2String(tempbuff, dhcpEntry->ip));
  1646.  
  1647.             if (dhcpEntry->expiry >= LONG_MAX)
  1648.                 fp += sprintf(fp, line200, "Infinity");
  1649.             else
  1650.             {
  1651.                 tm *ttm = localtime(&dhcpEntry->expiry);
  1652.                 strftime(tempbuff, sizeof(tempbuff), "%d-%b-%y %X", ttm);
  1653.                 fp += sprintf(fp, line200, tempbuff);
  1654.             }
  1655.  
  1656.             cache = findEntry(cacheInd, IP2String(tempbuff, htonl(dhcpEntry->ip)));
  1657.  
  1658.             if (cache && cache->hostname)
  1659.             {
  1660.                 if (strlen(cache->hostname) <= 20)
  1661.                     fp += sprintf(fp, line200, cache->hostname);
  1662.                 else
  1663.                 {
  1664.                     memcpy(tempbuff, cache->hostname, 20);
  1665.                     tempbuff[20] = 0;
  1666.                     fp += sprintf(fp, line200, tempbuff);
  1667.                 }
  1668.             }
  1669.             else
  1670.                 fp += sprintf(fp, line200, " ");
  1671.             
  1672.             fp += sprintf(fp, "<td align = \"center\">");
  1673.             fp += sprintf(fp, "%s ", vci[dhcpEntry->ip].vci);
  1674.             fp += sprintf(fp, "</td>");
  1675.             fp += sprintf(fp, "</tr>\n");
  1676.         }
  1677.     }
  1678.  
  1679.     fp += sprintf(fp, "</table>\n<br>\n<table id=\"freedynamic\" border=\"1\" width=\"600\" bgcolor=\"#b8b8b8\">\n");
  1680.     fp += sprintf(fp, "<tr><th colspan=\"5\"><font size=\"5\"><i>Free Dynamic Leases</i></font></th></tr>\n");
  1681.     BYTE colNum = 0;
  1682.  
  1683.     for (char rangeInd = 0; rangeInd < MAX_RANGES && cfig.dhcpRanges[rangeInd].rangeStart && fp < maxData; rangeInd++)
  1684.     {
  1685.         for (ind = 0, iip = cfig.dhcpRanges[rangeInd].rangeStart; iip <= cfig.dhcpRanges[rangeInd].rangeEnd; iip++, ind++)
  1686.         {
  1687.             if (cfig.dhcpRanges[rangeInd].expiry[ind] < t)
  1688.             {
  1689.                 if (!colNum)
  1690.                 {
  1691.                     fp += sprintf(fp, "<tr>");
  1692.                     colNum = 1;
  1693.                 }
  1694.                 else if (colNum < 5)
  1695.                     colNum++;
  1696.                 else
  1697.                 {
  1698.                     fp += sprintf(fp, "</tr>\n<tr>");
  1699.                     colNum = 1;
  1700.                 }
  1701.  
  1702.                 fp += sprintf(fp, line200, IP2String(tempbuff, htonl(iip)));
  1703.             }
  1704.         }
  1705.     }
  1706.  
  1707.     if (colNum)
  1708.         fp += sprintf(fp, "</tr>\n");
  1709.  
  1710.     fp += sprintf(fp, "</table>\n<br>\n<table id=\"freestatic\" border=\"1\" width=\"600\" bgcolor=\"#b8b8b8\">\n");
  1711.     fp += sprintf(fp, "<tr><th colspan=\"5\"><font size=\"5\"><i>Free Static Leases</i></font></th></tr>\n");
  1712.     fp += sprintf(fp, "<tr><th>Mac Address</th><th>IP</th><th>Mac Address</th><th>IP</th></tr>\n");
  1713.     colNum = 0;
  1714.  
  1715.     for (p = dhcpCache.begin(); p != dhcpCache.end() && fp < maxData; p++)
  1716.     {
  1717.         if ((dhcpEntry = p->second) && dhcpEntry->fixed && dhcpEntry->expiry < t)
  1718.         {
  1719.             if (!colNum)
  1720.             {
  1721.                 fp += sprintf(fp, "<tr>");
  1722.                 colNum = 1;
  1723.             }
  1724.             else if (colNum == 1)
  1725.             {
  1726.                 colNum = 2;
  1727.             }
  1728.             else if (colNum == 2)
  1729.             {
  1730.                 fp += sprintf(fp, "</tr>\n<tr>");
  1731.                 colNum = 1;
  1732.             }
  1733.  
  1734.             BYTE bp_hlen = fromUUE(bp_chaddr, dhcpEntry->mapname);
  1735.             fp += sprintf(fp, line200, hex2String(tempbuff, bp_chaddr, bp_hlen, ':'));
  1736.             fp += sprintf(fp, line200, IP2String(tempbuff, dhcpEntry->ip));
  1737.         }
  1738.     }
  1739.  
  1740.     if (colNum)
  1741.         fp += sprintf(fp, "</tr>\n");
  1742.  
  1743.     fp += sprintf(fp, "</table>\n</body>\n</html>");
  1744.     memcpy((contentStart - 12), tempbuff, sprintf(tempbuff, "%u", (fp - contentStart)));
  1745.     req->bytes = fp - req->buffer;
  1746.  
  1747.     if (!(_beginthread(sendHTTP, 0, (void*)req) > 0))
  1748.     {
  1749.         if (cfig.dnsLogLevel)
  1750.         {
  1751.             sprintf(logBuff, "Thread Creation Failed");
  1752.             logDHCPMess(logBuff, 1);
  1753.         }
  1754.         send(req->sock, req->buffer, req->bytes, 0);
  1755.         closesocket(req->sock);
  1756.         free(req->buffer);
  1757.         free(req);
  1758.     }
  1759.  
  1760.     return;
  1761.  
  1762. void sendHTTP(void *lpParam)
  1763. {
  1764.     //printf("Here\n");
  1765.     data19 *req = (data19*)lpParam;
  1766.     send(req->sock, req->buffer, req->bytes, 0);
  1767.     Sleep(1000*(20));
  1768.     closesocket(req->sock);
  1769.     free(req->buffer);
  1770.     free(req);
  1771.     _endthread();
  1772.     return;
  1773. }
  1774.  
  1775. void procTCP(data5 *req)
  1776. {
  1777.     req->ling.l_onoff = 1; //0 = off (l_linger ignored), nonzero = on
  1778.     req->ling.l_linger = 10; //0 = discard data, nonzero = wait for data sent
  1779.     setsockopt(req->sock, SOL_SOCKET, SO_LINGER, (const char*)&req->ling, sizeof(req->ling));
  1780.  
  1781.     errno = 0;
  1782.     req->bytes = recvTcpDnsMess(req->sock, req->raw, true);
  1783.     //printf("%u\n",req->bytes);
  1784.  
  1785.     if (req->bytes < 2)
  1786.     {
  1787.         sprintf(logBuff, "Error Getting TCP DNS Message");
  1788.         logDNSMess(logBuff, 1);
  1789.         closesocket(req->sock);
  1790.         return;
  1791.     }
  1792.  
  1793.     WORD pktSize = fUShort(req->raw);
  1794.     req->data = req->raw + 2;
  1795.     req->dnsp = (dnsPacket*)(req->data);
  1796.  
  1797.     if (req->dnsp->header.opcode != OPCODE_STANDARD_QUERY)
  1798.     {
  1799.         switch (req->dnsp->header.opcode)
  1800.         {
  1801.             case OPCODE_INVERSE_QUERY:
  1802.                 sprintf(logBuff, "Inverse query not supported");
  1803.                 break;
  1804.  
  1805.             case OPCODE_SRVR_STAT_REQ:
  1806.                 sprintf(logBuff, "Server Status Request not supported");
  1807.                 break;
  1808.  
  1809.             case OPCODE_NOTIFY:
  1810.                 sprintf(logBuff, "Notify not supported");
  1811.                 break;
  1812.  
  1813.             case OPCODE_DYNAMIC_UPDATE:
  1814.                 sprintf(logBuff, "Dynamic Update not needed/supported by Dual Server");
  1815.                 break;
  1816.  
  1817.             default:
  1818.                 sprintf(logBuff, "OpCode %u not supported", req->dnsp->header.opcode);
  1819.         }
  1820.  
  1821.         logTCPMess(req, logBuff, 1);
  1822.  
  1823.         addRRNone(req);
  1824.         req->dnsp->header.rcode = RCODE_NOTIMPL;
  1825.         sTCPmess(req);
  1826.         closesocket(req->sock);
  1827.         return;
  1828.     }
  1829.  
  1830.     if (req->dnsp->header.qr != 0 || ntohs(req->dnsp->header.qdcount) != 1 || ntohs(req->dnsp->header.ancount))
  1831.     {
  1832.         sprintf(logBuff, "DNS Query Format Error");
  1833.         logTCPMess(req, logBuff, 1);
  1834.         addRRNone(req);
  1835.         req->dnsp->header.rcode = RCODE_FORMATERROR;
  1836.         sTCPmess(req);
  1837.         closesocket(req->sock);
  1838.         return;
  1839.     }
  1840.  
  1841.     req->data = &req->dnsp->data;
  1842.  
  1843.     for (int i = 1; i <= ntohs(req->dnsp->header.qdcount); i++)
  1844.     {
  1845.         req->data += fQu(req->query, req->dnsp, req->data);
  1846.         req->qtype = fUShort(req->data);
  1847.         req->data += 2;
  1848.         req->qclass = fUShort(req->data);
  1849.         req->data += 2;
  1850.     }
  1851.  
  1852.     if (req->qclass != DNS_CLASS_IN)
  1853.     {
  1854.         sprintf(logBuff, "DNS Class %u not supported", req->qclass);
  1855.         logTCPMess(req, logBuff, 1);
  1856.         addRRNone(req);
  1857.         req->dnsp->header.rcode = RCODE_NOTIMPL;
  1858.         sTCPmess(req);
  1859.         closesocket(req->sock);
  1860.         return;
  1861.     }
  1862.  
  1863.     if (!req->qtype)
  1864.     {
  1865.         sprintf(logBuff, "missing query type");
  1866.         logTCPMess(req, logBuff, 1);
  1867.         addRRNone(req);
  1868.         req->dnsp->header.rcode = RCODE_FORMATERROR;
  1869.         sTCPmess(req);
  1870.         closesocket(req->sock);
  1871.         return;
  1872.     }
  1873.  
  1874.     bool allowed = false;
  1875.     DWORD ip = req->addr.sin_addr.s_addr;
  1876.  
  1877.     for (int i = 0; i < MAX_SERVERS; i++)
  1878.     {
  1879.         if (ip == cfig.zoneServers[i] || ip == network.allServers[i])
  1880.         {
  1881.             allowed = true;
  1882.             break;
  1883.         }
  1884.     }
  1885.  
  1886.     if (!allowed)
  1887.     {
  1888.         sprintf(logBuff, "DNS TCP Query, Access Denied");
  1889.         logTCPMess(req, logBuff, 1);
  1890.         addRRNone(req);
  1891.         req->dnsp->header.rcode = RCODE_REFUSED;
  1892.         sTCPmess(req);
  1893.         closesocket(req->sock);
  1894.         return;
  1895.     }
  1896.  
  1897.     strcpy(req->mapname, req->query);
  1898.     strcpy(req->cname, req->query);
  1899.     bool AXFRError = false;
  1900.  
  1901.     if (req->qtype != DNS_TYPE_NS && req->qtype != DNS_TYPE_SOA && req->qtype != DNS_TYPE_AXFR && req->qtype != DNS_TYPE_IXFR)
  1902.     {
  1903.         addRRNone(req);
  1904.         req->dnsp->header.rcode = RCODE_NOTIMPL;
  1905.         sTCPmess(req);
  1906.         sprintf(logBuff, "DNS TCP Query Type %s not supported", strqtype(tempbuff, req->qtype));
  1907.         logTCPMess(req, logBuff, 1);
  1908.     }
  1909.     else if (strcasecmp(req->mapname, cfig.zone) && strcasecmp(req->mapname, cfig.authority))
  1910.     {
  1911.         addRRNone(req);
  1912.         req->dnsp->header.rcode = RCODE_NOTIMPL;
  1913.         sTCPmess(req);
  1914.         sprintf(logBuff, "%s, Forwarding TCP query not supported", req->query);
  1915.         logTCPMess(req, logBuff, 1);
  1916.     }
  1917.     else if (!cfig.authorized)
  1918.     {
  1919.         addRRNone(req);
  1920.         req->dnsp->header.rcode = RCODE_NOTAUTH;
  1921.         sTCPmess(req);
  1922.         sprintf(logBuff, "Server is not authorized for zone %s", req->query);
  1923.         logTCPMess(req, logBuff, 1);
  1924.     }
  1925.     else if (!dhcpService && cfig.expireTime < time(NULL))
  1926.     {
  1927.         addRRNone(req);
  1928.         req->dnsp->header.rcode = RCODE_NOTAUTH;
  1929.         sTCPmess(req);
  1930.         sprintf(logBuff, "Zone %s expired", req->query);
  1931.         logTCPMess(req, logBuff, 1);
  1932.     }
  1933.     else
  1934.     {
  1935.         switch (req->qtype)
  1936.         {
  1937.             case DNS_TYPE_SOA:
  1938.  
  1939.                 if (!strcasecmp(req->query, cfig.zone))
  1940.                 {
  1941.                     addRRNone(req);
  1942.                     req->dnsp->header.aa = 0;
  1943.                     req->dnsp->header.at = 0;
  1944.                     addRRSOA(req, cfig.serial1);
  1945.                     sTCPmess(req);
  1946.                     sprintf(logBuff, "SOA Sent for zone %s", req->query);
  1947.                     logTCPMess(req, logBuff, 2);
  1948.                 }
  1949.                 else if (!strcasecmp(req->query, cfig.authority))
  1950.                 {
  1951.                     addRRNone(req);
  1952.                     req->dnsp->header.aa = 0;
  1953.                     req->dnsp->header.at = 0;
  1954.                     addRRSOA(req, cfig.serial2);
  1955.                     sTCPmess(req);
  1956.                     sprintf(logBuff, "SOA Sent for zone %s", req->query);
  1957.                     logTCPMess(req, logBuff, 2);
  1958.                 }
  1959.                 break;
  1960.  
  1961.             case DNS_TYPE_NS:
  1962.                 if (!strcasecmp(req->mapname, cfig.zone))
  1963.                 {
  1964.                     addRRNone(req);
  1965.                     req->dnsp->header.aa = 0;
  1966.                     req->dnsp->header.at = 0;
  1967.                     addRRNSA(req);
  1968.                     addRRAd(req);
  1969.                     sTCPmess(req);
  1970.                     sprintf(logBuff, "NS Sent for Zone %s", req->query);
  1971.                     logTCPMess(req, logBuff, 2);
  1972.                 }
  1973.                 else if (!strcasecmp(req->query, cfig.authority))
  1974.                 {
  1975.                     addRRNone(req);
  1976.                     req->dnsp->header.aa = 0;
  1977.                     req->dnsp->header.at = 0;
  1978.                     addRRNSPtr(req);
  1979.                     addRRAd(req);
  1980.                     sTCPmess(req);
  1981.                     sprintf(logBuff, "NS Sent for Zone", req->query);
  1982.                     logTCPMess(req, logBuff, 2);
  1983.                 }
  1984.                 break;
  1985.  
  1986.             case DNS_TYPE_AXFR:
  1987.             case DNS_TYPE_IXFR:
  1988.  
  1989.                 if (!strcasecmp(req->mapname, cfig.zone))
  1990.                 {
  1991.                     DWORD tempserial = cfig.serial1;
  1992.                     WORD records = 0;
  1993.  
  1994.                     addRRNone(req);
  1995.                     req->data = &req->dnsp->data;
  1996.                     req->dnsp->header.qdcount = 0;
  1997.                     addRRSOA(req, cfig.serial1);
  1998.  
  1999.                     if (!sTCPmess(req))
  2000.                     {
  2001.                         AXFRError = true;
  2002.                         break;
  2003.                     }
  2004.                     else
  2005.                         records++;
  2006.  
  2007.                     addRRNone(req);
  2008.                     req->data = &req->dnsp->data;
  2009.                     req->dnsp->header.qdcount = 0;
  2010.                     addRRNSA(req);
  2011.  
  2012.                     if (!sTCPmess(req))
  2013.                     {
  2014.                         AXFRError = true;
  2015.                         break;
  2016.                     }
  2017.                     else
  2018.                         records++;
  2019.  
  2020.                     time_t t = time(NULL);
  2021.                     req->iterBegin = dnsCache[cacheInd].begin();
  2022.  
  2023.                     while (!AXFRError && req->iterBegin != dnsCache[cacheInd].end())
  2024.                     {
  2025.                         addRRNone(req);
  2026.                         req->dnsp->header.qdcount = 0;
  2027.                         req->data = &req->dnsp->data;
  2028.  
  2029.                         if (req->iterBegin->second->expiry > t)
  2030.                         {
  2031.                             switch (req->iterBegin->second->dataType)
  2032.                             {
  2033.                                 case LOCAL_A:
  2034.                                     addRRAOne(req);
  2035.                                     break;
  2036.  
  2037.                                 case SERVER_A:
  2038.                                     if (network.dnsTcpConn[req->sockInd].server == req->iterBegin->second->ip)
  2039.                                         addRRSTAOne(req);
  2040.                                     else
  2041.                                     {
  2042.                                         req->iterBegin++;
  2043.                                         continue;
  2044.                                     }
  2045.                                     break;
  2046.  
  2047.                                 case STATIC_A_AUTH:
  2048.                                     //case STATIC_A_NAUTH:
  2049.                                     addRRSTAOne(req);
  2050.                                     break;
  2051.  
  2052.                                 case LOCAL_CNAME:
  2053.                                 case EXT_CNAME:
  2054.                                     addRRCNOne(req);
  2055.                                     break;
  2056.  
  2057.                                 default:
  2058.                                     req->iterBegin++;
  2059.                                     continue;
  2060.                             }
  2061.  
  2062.                             if (tempserial != cfig.serial1)
  2063.                             {
  2064.                                 AXFRError = true;
  2065.                                 break;
  2066.                             }
  2067.  
  2068.                             if (!sTCPmess(req))
  2069.                             {
  2070.                                 AXFRError = true;
  2071.                                 break;
  2072.                             }
  2073.                             else
  2074.                                 records++;
  2075.                         }
  2076.                         req->iterBegin++;
  2077.                     }
  2078.  
  2079.                     for (int m = 0; m < cfig.mxCount[cacheInd]; m++)
  2080.                     {
  2081.                         addRRNone(req);
  2082.                         req->dnsp->header.qdcount = 0;
  2083.                         req->data = &req->dnsp->data;
  2084.                         addRRMXOne(req, m);
  2085.  
  2086.                         if (tempserial != cfig.serial1)
  2087.                         {
  2088.                             AXFRError = true;
  2089.                             break;
  2090.                         }
  2091.  
  2092.                         if (!sTCPmess(req))
  2093.                         {
  2094.                             AXFRError = true;
  2095.                             break;
  2096.                         }
  2097.                         else
  2098.                             records++;
  2099.                     }
  2100.  
  2101.                     addRRNone(req);
  2102.                     req->data = &req->dnsp->data;
  2103.                     req->dnsp->header.qdcount = 0;
  2104.                     addRRSOA(req, cfig.serial1);
  2105.  
  2106.                     if (!AXFRError && tempserial == cfig.serial1)
  2107.                     {
  2108.                         if (sTCPmess(req))
  2109.                         {
  2110.                             records++;
  2111.                             sprintf(logBuff, "Zone %s with %u RRs Sent", req->query, records);
  2112.                             logTCPMess(req, logBuff, 2);
  2113.                         }
  2114.                     }
  2115.                 }
  2116.                 else if (!strcasecmp(req->query, cfig.authority))
  2117.                 {
  2118.                     DWORD tempserial = cfig.serial2;
  2119.                     WORD records = 0;
  2120.  
  2121.                     addRRNone(req);
  2122.                     req->data = &req->dnsp->data;
  2123.                     req->dnsp->header.qdcount = 0;
  2124.                     addRRSOA(req, cfig.serial2);
  2125.  
  2126.                     if (!sTCPmess(req))
  2127.                     {
  2128.                         AXFRError = true;
  2129.                         break;
  2130.                     }
  2131.                     else
  2132.                         records++;
  2133.  
  2134.                     addRRNone(req);
  2135.                     req->data = &req->dnsp->data;
  2136.                     req->dnsp->header.qdcount = 0;
  2137.                     addRRNSPtr(req);
  2138.  
  2139.                     if (!sTCPmess(req))
  2140.                     {
  2141.                         AXFRError = true;
  2142.                         break;
  2143.                     }
  2144.                     else
  2145.                         records++;
  2146.  
  2147.                     time_t t = time(NULL);
  2148.                     req->iterBegin = dnsCache[cacheInd].begin();
  2149.  
  2150.                     while (!AXFRError && req->iterBegin != dnsCache[cacheInd].end())
  2151.                     {
  2152.                         addRRNone(req);
  2153.                         req->dnsp->header.qdcount = 0;
  2154.                         req->data = &req->dnsp->data;
  2155.  
  2156.                         if (req->iterBegin->second->expiry > t)
  2157.                         {
  2158.                             switch (req->iterBegin->second->dataType)
  2159.                             {
  2160.                                 case LOCAL_PTR_AUTH:
  2161.                                 case STATIC_PTR_AUTH:
  2162.  
  2163.                                     addRRPtrOne(req);
  2164.                                     break;
  2165.  
  2166.                                 case SERVER_PTR_AUTH:
  2167.                                     if (network.dnsTcpConn[req->sockInd].server == ntohl(my_inet_addr(req->iterBegin->second->mapname)))
  2168.                                         addRRPtrOne(req);
  2169.                                     else
  2170.                                     {
  2171.                                         req->iterBegin++;
  2172.                                         continue;
  2173.                                     }
  2174.                                     break;
  2175.  
  2176.                                 default:
  2177.                                     req->iterBegin++;
  2178.                                     continue;
  2179.                             }
  2180.  
  2181.                             if (tempserial != cfig.serial2)
  2182.                             {
  2183.                                 AXFRError = true;
  2184.                                 break;
  2185.                             }
  2186.  
  2187.                             if (!sTCPmess(req))
  2188.                             {
  2189.                                 AXFRError = true;
  2190.                                 break;
  2191.                             }
  2192.                             else
  2193.                                 records++;
  2194.  
  2195.                         }
  2196.                         req->iterBegin++;
  2197.                     }
  2198.  
  2199.                     addRRNone(req);
  2200.                     req->data = &req->dnsp->data;
  2201.                     req->dnsp->header.qdcount = 0;
  2202.                     addRRSOA(req, cfig.serial2);
  2203.  
  2204.                     if (!AXFRError && tempserial == cfig.serial2)
  2205.                     {
  2206.                         if (sTCPmess(req))
  2207.                         {
  2208.                             records++;
  2209.                             sprintf(logBuff, "Zone %s with %u RRs Sent", req->query, records);
  2210.                             logTCPMess(req, logBuff, 2);
  2211.                         }
  2212.                     }
  2213.                 }
  2214.                 break;
  2215.         }
  2216.     }
  2217.  
  2218.     closesocket(req->sock);
  2219.     return;
  2220. }
  2221.  
  2222. WORD sTCPmess(data5 *req)
  2223. {
  2224.     errno = 0;
  2225.     req->dnsp->header.ra = 0;
  2226.  
  2227.     pUShort(req->raw, req->bytes - 2);
  2228.  
  2229.     if (req->bytes != send(req->sock, req->raw, req->bytes, 0) || WSAGetLastError())
  2230.         return 0;
  2231.  
  2232.     return req->bytes;
  2233. }
  2234.  
  2235. WORD gdnmess(data5 *req, BYTE sockInd)
  2236. {
  2237.     memset(req, 0, sizeof(data5));
  2238.     req->sockLen = sizeof(req->addr);
  2239.     errno = 0;
  2240.  
  2241.     req->bytes = recvfrom(network.dnsUdpConn[sockInd].sock,
  2242.                           req->raw,
  2243.                           sizeof(req->raw),
  2244.                           0,
  2245.                           (sockaddr*)&req->addr,
  2246.                           &req->sockLen);
  2247.  
  2248.     errno = WSAGetLastError();
  2249.  
  2250.     if (errno || req->bytes <= 0)
  2251.         return 0;
  2252.  
  2253.     req->sockInd = sockInd;
  2254.     req->dnsp = (dnsPacket*)req->raw;
  2255.  
  2256.     if (req->dnsp->header.opcode != OPCODE_STANDARD_QUERY)
  2257.     {
  2258.         if (cfig.dnsLogLevel)
  2259.         {
  2260.             switch (req->dnsp->header.opcode)
  2261.             {
  2262.                 case OPCODE_INVERSE_QUERY:
  2263.                     sprintf(logBuff, "Inverse query not supported");
  2264.                     break;
  2265.  
  2266.                 case OPCODE_SRVR_STAT_REQ:
  2267.                     sprintf(logBuff, "Server Status Request not supported");
  2268.                     break;
  2269.  
  2270.                 case OPCODE_NOTIFY:
  2271.                     sprintf(logBuff, "Notify not supported");
  2272.                     break;
  2273.  
  2274.                 case OPCODE_DYNAMIC_UPDATE:
  2275.                     sprintf(logBuff, "Dynamic Update not needed/supported by Dual Server");
  2276.                     break;
  2277.  
  2278.                 default:
  2279.                     sprintf(logBuff, "OpCode %u not supported", req->dnsp->header.opcode);
  2280.             }
  2281.             logDNSMess(req, logBuff, 1);
  2282.         }
  2283.  
  2284.         addRRNone(req);
  2285.         req->dnsp->header.rcode = RCODE_NOTIMPL;
  2286.         return req->bytes;
  2287.     }
  2288.  
  2289.     if (req->dnsp->header.qr != 0 || ntohs(req->dnsp->header.qdcount) != 1 || ntohs(req->dnsp->header.ancount))
  2290.     {
  2291.         if (cfig.dnsLogLevel)
  2292.         {
  2293.             sprintf(logBuff, "DNS Query Format Error");
  2294.             logDNSMess(req, logBuff, 1);
  2295.         }
  2296.         addRRNone(req);
  2297.         req->dnsp->header.rcode = RCODE_FORMATERROR;
  2298.         return req->bytes;
  2299.     }
  2300.  
  2301.     req->data = &req->dnsp->data;
  2302.  
  2303.     for (int i = 1; i <= ntohs(req->dnsp->header.qdcount); i++)
  2304.     {
  2305.         req->data += fQu(req->query, req->dnsp, req->data);
  2306.         req->qtype = fUShort(req->data);
  2307.         req->data += 2;
  2308.         req->qclass = fUShort(req->data);
  2309.         req->data += 2;
  2310.     }
  2311.  
  2312.     if (req->qclass != DNS_CLASS_IN)
  2313.     {
  2314.         if (cfig.dnsLogLevel)
  2315.         {
  2316.             sprintf(logBuff, "DNS Class %u not supported", req->qclass);
  2317.             logDNSMess(req, logBuff, 1);
  2318.         }
  2319.         addRRNone(req);
  2320.         req->dnsp->header.rcode = RCODE_NOTIMPL;
  2321.         return req->bytes;
  2322.     }
  2323.  
  2324.     if (!req->qtype)
  2325.     {
  2326.         if (cfig.dnsLogLevel)
  2327.         {
  2328.             sprintf(logBuff, "missing query type");
  2329.             logDNSMess(req, logBuff, 1);
  2330.         }
  2331.         addRRNone(req);
  2332.         req->dnsp->header.rcode = RCODE_FORMATERROR;
  2333.         return req->bytes;
  2334.     }
  2335.  
  2336.     req->qLen = strlen(req->query);
  2337.     DWORD iip = ntohl(req->addr.sin_addr.s_addr);
  2338.  
  2339.     for (int i = 0; i < MAX_RANGES && cfig.dnsRanges[i].rangeStart; i++)
  2340.     {
  2341.         if (iip >= cfig.dnsRanges[i].rangeStart && iip <= cfig.dnsRanges[i].rangeEnd)
  2342.             return req->bytes;
  2343.     }
  2344.  
  2345.     for (int i = 0; i < MAX_RANGES && cfig.dhcpRanges[i].rangeStart; i++)
  2346.     {
  2347.         if (iip >= cfig.dhcpRanges[i].rangeStart && iip <= cfig.dhcpRanges[i].rangeEnd)
  2348.             return req->bytes;
  2349.     }
  2350.  
  2351.     if (findEntry(cacheInd, IP2String(req->cname, iip)))
  2352.         return req->bytes;
  2353.  
  2354.     if (req->addr.sin_addr.s_addr == cfig.zoneServers[0] || req->addr.sin_addr.s_addr == cfig.zoneServers[1])
  2355.         return req->bytes;
  2356.  
  2357.     addRRNone(req);
  2358.     req->dnsp->header.rcode = RCODE_REFUSED;
  2359.     if (cfig.dnsLogLevel)
  2360.     {
  2361.         sprintf(logBuff, "DNS UDP Query, Access Denied");
  2362.         logDNSMess(req, logBuff, 1);
  2363.     }
  2364.     return req->bytes;
  2365. }
  2366.  
  2367. WORD sdnmess(data5 *req)
  2368. {
  2369.     errno = 0;
  2370.  
  2371.       // If we are sending a response
  2372.     //sprintf(logBuff, "sending response with qr %d", req->dnsp->header.qr);
  2373.     //logDNSMess(req, logBuff, 1);
  2374.     if (cfig.defaultIP!=0 &&  req->dnsp->header.qr==1)
  2375.     {
  2376.         //sprintf(logBuff, "sending response with qdcount %d  ancount %d nscount %d adcount %d", ntohs(req->dnsp->header.qdcount), ntohs(req->dnsp->header.ancount), ntohs(req->dnsp->header.nscount), ntohs(req->dnsp->header.adcount));
  2377.         //logDNSMess(req, logBuff, 1);
  2378.         // If answer count is 0
  2379.         if (req->dnsp->header.ancount == 0 /*&& req->dnsp->header.nscount && req->dnsp->header.adcount*/)
  2380.         {
  2381.             sprintf(logBuff, "adding default ip");
  2382.             logDNSMess(req, logBuff, 1);
  2383.             addRRWildA(req, cfig.defaultIP);
  2384.             // Kill other name server respones
  2385.             req->dnsp->header.nscount=0;
  2386.             req->dnsp->header.adcount=0;
  2387.             req->dnsp->header.rcode=RCODE_NOERROR;
  2388.         }
  2389.         else
  2390.         {
  2391.             //sprintf(logBuff, "looping to search for blacklisted ips");
  2392.             //logDNSMess(req, logBuff, 1);
  2393. #if 1
  2394.  
  2395.                     
  2396.             tempbuff[0] = 0;
  2397.             extbuff[0] = 0;
  2398.             char *raw = &req->dnsp->data;
  2399.             WORD queueIndex;
  2400.  
  2401.             for (int i = 1; i <= ntohs(req->dnsp->header.qdcount); i++)
  2402.             {
  2403.                 //sprintf(logBuff, "skipping question");
  2404.                 //logDNSMess(req, logBuff, 1);
  2405.                 raw += fQu(extbuff, req->dnsp, raw);
  2406.                 raw += 4;
  2407.             }
  2408.  
  2409.             for (int i = 1; i <= ntohs(req->dnsp->header.ancount); i++)
  2410.             {
  2411.                 //sprintf(logBuff, "looking at response");
  2412.                 //logDNSMess(req, logBuff, 1);
  2413.                 raw += fQu(extbuff, req->dnsp, raw);
  2414.                 int type = fUShort(raw);
  2415.                 raw += 2; //type
  2416.                 raw += 2; //class
  2417.                 raw += 4; //ttl
  2418.                 int zLen = fUShort(raw);
  2419.                 raw += 2; //datalength
  2420.  
  2421.                 if (type == DNS_TYPE_A)
  2422.                 {
  2423.                     //sprintf(logBuff, "is an A type");
  2424.                     //logDNSMess(req, logBuff, 1);
  2425.                     for (BYTE j=0; j <= 32 && cfig.nxdBlacklist[j]; j++)
  2426.                     {
  2427.                         //sprintf(logBuff, "comparing to nxdBlacklist ip");
  2428.                         //logDNSMess(req, logBuff, 1);
  2429.                         if (fIP(raw)==cfig.nxdBlacklist[j])
  2430.                         {
  2431.                             sprintf(logBuff, "clobbering");
  2432.                             logDNSMess(req, logBuff, 1);
  2433.                             pIP(raw,cfig.defaultIP);
  2434.                         }
  2435.                     }
  2436.                 }
  2437.                 else if (type == DNS_TYPE_AAAA)
  2438.                 {
  2439.                     // Handle IPv6
  2440.                 }
  2441.                 else if (type == DNS_TYPE_PTR)
  2442.                 {
  2443.                     // This is a name, not an IP
  2444.                 }
  2445.                 else if (type == DNS_TYPE_MX)
  2446.                 {
  2447.                     // Mail stuff
  2448.                 }
  2449.                 else if (type == DNS_TYPE_CNAME)
  2450.                 {
  2451.                     // Canonical names
  2452.                 }
  2453.                 raw += zLen;
  2454.             }
  2455. #endif
  2456.         }
  2457.     }
  2458.  
  2459.     req->bytes = sendto(network.dnsUdpConn[req->sockInd].sock,
  2460.                         req->raw,
  2461.                         req->bytes,
  2462.                         0,
  2463.                         (sockaddr*)&req->addr,
  2464.                         sizeof(req->addr));
  2465.  
  2466.     errno = WSAGetLastError();
  2467.  
  2468.     if (errno || req->bytes <= 0)    
  2469.         return 0;
  2470.  
  2471.     return req->bytes;
  2472. }
  2473.  
  2474. WORD scanloc(data5 *req)
  2475. {
  2476.     if (!req->query[0])
  2477.         return 0;
  2478.  
  2479.     strcpy(req->cname, req->query);
  2480.     strcpy(req->mapname, req->query);
  2481.     myLower(req->mapname);
  2482.     //printf("%s\n",req->query);
  2483.  
  2484.     switch (req->qtype)
  2485.     {
  2486.         case DNS_TYPE_PTR:
  2487.             {
  2488.                 char *dp = strstr(req->mapname, arpa);
  2489.  
  2490.                 if (dp)
  2491.                     *dp = 0;
  2492.                 else
  2493.                     return 0;
  2494.             }
  2495.             break;
  2496.  
  2497.         case DNS_TYPE_A:
  2498.             req->localCode = makeLocal(req->mapname);
  2499.             if (req->localCode == 1)
  2500.             {
  2501.                 sprintf(req->cname, "%s.%s", req->query, cfig.zone);
  2502.             }
  2503.             break;
  2504.  
  2505.         case DNS_TYPE_MX:
  2506.             if (!strcasecmp(req->query, cfig.zone) && (cfig.authorized || cfig.mxServers[cacheInd][0].hostname[0]))
  2507.             {
  2508.                 addRRNone(req);
  2509.                 addRRMX(req);
  2510.                 addAuth(req);
  2511.                 return 1;
  2512.             }
  2513.             else
  2514.                 return 0;
  2515.  
  2516.             break;
  2517.  
  2518.         case DNS_TYPE_NS:
  2519.             if (cfig.authorized)
  2520.             {
  2521.                 if (!strcasecmp(req->query, cfig.authority))
  2522.                 {
  2523.                     addRRNone(req);
  2524.                     addRRNSPtr(req);
  2525.                     addRRAd(req);
  2526.                     return 1;
  2527.                 }
  2528.                 else if (!strcasecmp(req->query, cfig.zone))
  2529.                 {
  2530.                     addRRNone(req);
  2531.                     addRRNSA(req);
  2532.                     addRRAd(req);
  2533.                     return 1;
  2534.                 }
  2535.             }
  2536.             return 0;
  2537.             break;
  2538.  
  2539.         case DNS_TYPE_SOA:
  2540.             if (cfig.authorized)
  2541.             {
  2542.                 if (!strcasecmp(req->query, cfig.authority))
  2543.                 {
  2544.                     addRRNone(req);
  2545.                     addRRSOA(req, cfig.serial2);
  2546.                     return 1;
  2547.                 }
  2548.                 else if (!strcasecmp(req->query, cfig.zone))
  2549.                 {
  2550.                     addRRNone(req);
  2551.                     addRRSOA(req, cfig.serial1);
  2552.                     return 1;
  2553.                 }
  2554.             }
  2555.             return 0;
  2556.             break;
  2557.  
  2558.         case DNS_TYPE_AAAA:
  2559.             req->localCode = makeLocal(req->mapname);
  2560.             if (req->localCode && cfig.authorized)
  2561.             {
  2562.                 if (cfig.dnsLogLevel)
  2563.                 {
  2564.                     sprintf(logBuff, "%s, DNS Query Type %s not supported", req->query, strqtype(tempbuff, req->qtype));
  2565.                     logDNSMess(req, logBuff, 1);
  2566.                 }
  2567.                 addRRNone(req);
  2568.                 req->dnsp->header.rcode = RCODE_NOTIMPL;
  2569.                 addAuth(req);
  2570.                 return 1;
  2571.             }
  2572.             return 0;
  2573.             break;
  2574.  
  2575.         default:
  2576.             if (cfig.authorized)
  2577.             {
  2578.                 char *dp = strstr(req->mapname, cfig.zoneSmall);
  2579.  
  2580.                 if (!dp)
  2581.                     dp = strstr(req->mapname, cfig.authority);
  2582.  
  2583.                 if (dp && (!strcasecmp(dp, cfig.zoneSmall) || !strcasecmp(dp, cfig.authority)))
  2584.                 {
  2585.                     if (cfig.dnsLogLevel)
  2586.                     {
  2587.                         sprintf(logBuff, "%s, DNS Query Type %s not supported", req->query, strqtype(tempbuff, req->qtype));
  2588.                         logDNSMess(req, logBuff, 1);
  2589.                     }
  2590.                     addRRNone(req);
  2591.                     req->dnsp->header.rcode = RCODE_NOTIMPL;
  2592.                     addAuth(req);
  2593.                     return 1;
  2594.                 }
  2595.                 return 0;
  2596.             }
  2597.  
  2598.             return 0;
  2599.     }
  2600.     time_t t = time(NULL);
  2601.  
  2602.     for (int m = 0; m < 3; m++)
  2603.     {
  2604.         //printf("%s has %u Entries\n", req->mapname, dnsCache[cacheInd].count(req->mapname));
  2605.         req->iterBegin = dnsCache[cacheInd].find(req->mapname);
  2606.         if (req->iterBegin != dnsCache[cacheInd].end() && req->iterBegin->second->expiry > t)
  2607.         {
  2608.             memcpy(&req->cache, req->iterBegin->second, sizeof(data7));
  2609.             //printf("mapname=%s, datatype=%i exp=%u\n",req->cache.mapname, req->cache.dataType,req->cache.expiry);
  2610.  
  2611.             switch (req->cache.dataType)
  2612.             {
  2613.                 case LOCAL_A:
  2614.                 case STATIC_A_AUTH:
  2615.                     addRRNone(req);
  2616.                     addRRA(req);
  2617.                     addAuth(req);
  2618.                     return 1;
  2619.  
  2620.                 case LOCAL_PTR_AUTH:
  2621.                 case STATIC_PTR_AUTH:
  2622.                 case SERVER_PTR_AUTH:
  2623.                     addRRNone(req);
  2624.                     addRRPtr(req);
  2625.                     addAuth(req);
  2626.                     return 1;
  2627.  
  2628.                 case LOCALHOST_A:
  2629.                     addRRNone(req);
  2630.                     addRRLocalhostA(req);
  2631.                     addAuth(req);
  2632.                     return 1;
  2633.  
  2634.                 case LOCALHOST_PTR:
  2635.                     addRRNone(req);
  2636.                     addRRLocalhostPtr(req);
  2637.                     addAuth(req);
  2638.                     return 1;
  2639.  
  2640.                 case STATIC_A_NAUTH:
  2641.                     addRRNone(req);
  2642.                     addRRA(req);
  2643.                     return 1;
  2644.  
  2645.                 case LOCAL_PTR_NAUTH:
  2646.                 case SERVER_PTR_NAUTH:
  2647.                 case STATIC_PTR_NAUTH:
  2648.                     addRRNone(req);
  2649.                     addRRPtr(req);
  2650.                     return 1;
  2651.  
  2652.                 case SERVER_A:
  2653.                     addRRNone(req);
  2654.                     addRRServerA(req);
  2655.                     addAuth(req);
  2656.                     return 1;
  2657.  
  2658.                 case CACHED:
  2659.                     addRRNone(req);
  2660.                     addRRExt(req);
  2661.                     return 1;
  2662.  
  2663.                 case LOCAL_CNAME:
  2664.                 case EXT_CNAME:
  2665.                     if (!strchr(req->cache.hostname, '.'))
  2666.                         sprintf(req->cname, "%s.%s", req->cache.hostname, cfig.zone);
  2667.                     else
  2668.                         strcpy(req->cname, req->cache.hostname);
  2669.  
  2670.                     strcpy(req->mapname, req->cache.hostname);
  2671.                     myLower(req->mapname);
  2672.                     continue;
  2673.  
  2674.                 default:
  2675.                     break;
  2676.             }
  2677.         }
  2678.         break;
  2679.     }
  2680.  
  2681.     //printf("%u=%u\n", req->cache.dataType, req->localCode);
  2682.  
  2683.     if (req->cache.dataType == LOCAL_CNAME)
  2684.     {
  2685.         addRRNone(req);
  2686.         addRRA(req);
  2687.         addAuth(req);
  2688.         return 1;
  2689.     }
  2690.     else if (req->cache.dataType == EXT_CNAME)
  2691.     {
  2692.         //printf("%u=%u\n", req->cache.dataType, EXT_CNAME);
  2693.         req->data = &req->dnsp->data;
  2694.         req->data += pQu(req->data, req->cname);
  2695.         req->data += pUShort(req->data, DNS_TYPE_A);
  2696.         req->data += pUShort(req->data, DNS_CLASS_IN);
  2697.         req->bytes = (DWORD)req->data - (DWORD)req->raw;
  2698.     }
  2699.     else if (req->qtype == DNS_TYPE_A && cfig.wildHosts[0].wildcard[0])
  2700.     {
  2701.         for (BYTE i = 0; i < 32 && cfig.wildHosts[i].wildcard[0]; i++)
  2702.         {
  2703.             if (wildcmp(req->mapname, cfig.wildHosts[i].wildcard))
  2704.             {
  2705.                 addRRNone(req);
  2706.  
  2707.                 if (cfig.wildHosts[i].ip)
  2708.                     addRRWildA(req, cfig.wildHosts[i].ip);
  2709.  
  2710.                 return 1;
  2711.             }
  2712.         }
  2713.     } 
  2714.  
  2715.     return 0;
  2716. }
  2717.  
  2718. WORD fdnmess(data5 *req)
  2719. {
  2720.     //checkSize();
  2721.     req->qLen = strlen(req->cname);
  2722.     BYTE zoneDNS;
  2723.     int nRet = -1;
  2724.  
  2725.     char mapname[8];
  2726.     sprintf(mapname, "%u", req->dnsp->header.xid);
  2727.     data7 *queue = findEntry(cacheInd, mapname, QUEUE);
  2728.  
  2729.     for (zoneDNS = 0; zoneDNS < 32 && cfig.dnsRoutes[zoneDNS].zLen; zoneDNS++)
  2730.     {
  2731.         if (req->qLen == cfig.dnsRoutes[zoneDNS].zLen && !strcasecmp(req->cname, cfig.dnsRoutes[zoneDNS].zone))
  2732.             req->localCode = 4;
  2733.         else if (req->qLen > cfig.dnsRoutes[zoneDNS].zLen)
  2734.         {
  2735.             char *dp = req->cname + (req->qLen - cfig.dnsRoutes[zoneDNS].zLen - 1);
  2736.  
  2737.             if (*dp == '.' && !strcasecmp(dp + 1, cfig.dnsRoutes[zoneDNS].zone))
  2738.                 req->localCode = 4;
  2739.         }
  2740.  
  2741.         if (req->localCode == 4)
  2742.         {
  2743.             if (queue && cfig.dnsRoutes[zoneDNS].dns[1])
  2744.             {
  2745.                 cfig.dnsRoutes[zoneDNS].currentDNS = 1 - cfig.dnsRoutes[zoneDNS].currentDNS;
  2746.             }
  2747.  
  2748.             if (req->addr.sin_addr.s_addr != cfig.dnsRoutes[zoneDNS].dns[cfig.dnsRoutes[zoneDNS].currentDNS])
  2749.             {
  2750.                 req->target.sin_family = AF_INET;
  2751.                 req->target.sin_addr.s_addr = cfig.dnsRoutes[zoneDNS].dns[cfig.dnsRoutes[zoneDNS].currentDNS];
  2752.                 req->target.sin_port = htons(IPPORT_DNS);
  2753.                 errno = 0;
  2754.  
  2755.                 nRet = sendto(network.forwConn.sock,
  2756.                               req->raw,
  2757.                               req->bytes,
  2758.                               0,
  2759.                               (sockaddr*)&req->target,
  2760.                               sizeof(req->target));
  2761.  
  2762.                 errno = WSAGetLastError();
  2763.                 if (errno || nRet <= 0)
  2764.                 {
  2765.                     if (cfig.dnsLogLevel)
  2766.                     {
  2767.                         sprintf(logBuff, "Error Forwarding UDP DNS Message to Child Server %s", IP2String(tempbuff, req->target.sin_addr.s_addr));
  2768.                         logDNSMess(req, logBuff, 1);
  2769.                     }
  2770.  
  2771.                     if (cfig.dnsRoutes[zoneDNS].dns[1])
  2772.                     {
  2773.                         cfig.dnsRoutes[zoneDNS].currentDNS = 1 - cfig.dnsRoutes[zoneDNS].currentDNS;
  2774.                     }
  2775.                     return 0;
  2776.                 }
  2777.                 else
  2778.                 {
  2779.                     if (cfig.dnsLogLevel == 2)
  2780.                     {
  2781.                         sprintf(logBuff, "%s forwarded to Child Server %s", req->cname, IP2String(tempbuff, cfig.dnsRoutes[zoneDNS].dns[cfig.dnsRoutes[zoneDNS].currentDNS]));
  2782.                         logDNSMess(req, logBuff, 2);
  2783.                     }
  2784.                 }
  2785.             }
  2786. /*
  2787.             if (nRet <= 0)
  2788.             {
  2789.                 addRRNone(req);
  2790.                 req->dnsp->header.ra = 0;
  2791.                 req->dnsp->header.rcode = RCODE_SERVERFAIL;
  2792.                 return 0;
  2793.             }
  2794. */
  2795.             break;
  2796.         }
  2797.     }
  2798.  
  2799.     //    printf("%u\n", req->localCode);
  2800.  
  2801.     if (req->localCode != 4)
  2802.     {
  2803.         if (cfig.authorized)
  2804.         {
  2805.             if (req->localCode == 3)
  2806.             {
  2807.                 if (cfig.dnsLogLevel == 2)
  2808.                 {
  2809.                     sprintf(logBuff, "%s not found", req->query);
  2810.                     logDNSMess(req, logBuff, 2);
  2811.                 }
  2812.  
  2813.                 addRRNone(req);
  2814.                 req->dnsp->header.rcode = RCODE_NAMEERROR;
  2815.                 addAuth(req);
  2816.                 return 0;
  2817.             }
  2818.             else
  2819.             {
  2820.                 sprintf(logBuff, "req->localCode not 3");
  2821.                 logMess(logBuff, 1);
  2822.                 char *dp = 0;
  2823.  
  2824.                 if (req->qtype != DNS_TYPE_PTR && req->qLen > cfig.zLen)
  2825.                 {
  2826.                     dp = req->cname + (req->qLen - cfig.zLen - 1);
  2827.                     if (*dp != '.' || strcasecmp(dp + 1, cfig.zone))
  2828.                         dp = 0;
  2829.                 }
  2830.  
  2831.                 if (!dp && req->qLen > cfig.aLen)
  2832.                 {
  2833.                     dp = req->cname + (req->qLen - cfig.aLen - 1);
  2834.                     if (*dp != '.' || strcasecmp(dp + 1, cfig.authority))
  2835.                         dp = 0;
  2836.                 }
  2837.  
  2838.                 //printf("%s=%s\n", req->cname, dp);    
  2839.                 if (dp) //if child zone matches
  2840.                 {
  2841.                     switch (req->qtype)
  2842.                     {
  2843.                         case DNS_TYPE_A:
  2844.                         case DNS_TYPE_MX:
  2845.                         case DNS_TYPE_PTR:
  2846.  
  2847.                             if (cfig.dnsLogLevel == 2)
  2848.                             {
  2849.                                 if (dp != strchr(req->cname, '.'))
  2850.                                 {
  2851.                                     if (cfig.dnsLogLevel == 2)
  2852.                                     {
  2853.                                         while (dp > req->cname)
  2854.                                         {
  2855.                                             dp--;
  2856.                                             if (*dp == '.')
  2857.                                             {
  2858.                                                 dp++;
  2859.                                                 break;
  2860.                                             }
  2861.                                         }
  2862.                                         sprintf(logBuff, "%s (Child Zone %s) not found", req->query, dp);
  2863.                                         logDNSMess(req, logBuff, 2);
  2864.                                     }
  2865.                                 }
  2866.                                 else
  2867.                                 {
  2868.                                     sprintf(logBuff, "%s not found", req->query);
  2869.                                     logDNSMess(req, logBuff, 2);
  2870.                                 }
  2871.                             }
  2872.  
  2873.                             addRRNone(req);
  2874.                             req->dnsp->header.rcode = RCODE_NAMEERROR;
  2875.                             addAuth(req);
  2876.                             return 0;
  2877.                             break;
  2878.  
  2879.                         case DNS_TYPE_AXFR:
  2880.                         case DNS_TYPE_NS:
  2881.                         case DNS_TYPE_SOA:
  2882.  
  2883.                             if (cfig.dnsLogLevel == 2)
  2884.                             {
  2885.                                 if (dp != strchr(req->cname, '.'))
  2886.                                 {
  2887.                                     while (dp > req->cname)
  2888.                                     {
  2889.                                         dp--;
  2890.                                         if (*dp == '.')
  2891.                                         {
  2892.                                             dp++;
  2893.                                             break;
  2894.                                         }
  2895.                                     }
  2896.                                     sprintf(logBuff, "%s (Child Zone %s) not found", req->query, dp);
  2897.                                     logDNSMess(req, logBuff, 2);
  2898.                                 }
  2899.                                 else
  2900.                                 {
  2901.                                     sprintf(logBuff, "Child Zone %s not found", req->query);
  2902.                                     logDNSMess(req, logBuff, 2);
  2903.                                 }
  2904.                             }
  2905.  
  2906.                             addRRNone(req);
  2907.                             req->dnsp->header.rcode = RCODE_NOTZONE;
  2908.                             addAuth(req);
  2909.                             return 0;
  2910.                             break;
  2911.  
  2912.                         default:
  2913.                             if (cfig.dnsLogLevel == 2)
  2914.                             {
  2915.                                 sprintf(logBuff, "DNS UDP Query Type %s not supported", strqtype(tempbuff, req->qtype));
  2916.                                 logDNSMess(logBuff, 1);
  2917.                             }
  2918.                             addRRNone(req);
  2919.                             req->dnsp->header.rcode = RCODE_NOTIMPL;
  2920.                             addAuth(req);
  2921.                             return 0;
  2922.                     }
  2923.                 }
  2924.             }
  2925.         } //if (cfig.authorized)
  2926.  
  2927.         if (!req->dnsp->header.rd)
  2928.         {
  2929.             addRRNone(req);
  2930.             req->dnsp->header.rcode = RCODE_NAMEERROR;
  2931.             if (cfig.dnsLogLevel)
  2932.             {
  2933.                 sprintf(logBuff, "%s is not local (recursion not desired)", req->query);
  2934.                 logDNSMess(req, logBuff, 2);
  2935.             }
  2936.             return 0;
  2937.         }
  2938.  
  2939.         if (!network.dns[0])
  2940.         {
  2941.             addRRNone(req);
  2942.             req->dnsp->header.rcode = RCODE_NAMEERROR;
  2943.             req->dnsp->header.ra = 0;
  2944.             if (cfig.dnsLogLevel)
  2945.             {
  2946.                 sprintf(logBuff, "%s not found (recursion not available)", req->query);
  2947.                 logDNSMess(req, logBuff, 2);
  2948.             }
  2949.             return 0;
  2950.         }
  2951.  
  2952.         if (queue && network.dns[1] && queue->dnsIndex < MAX_SERVERS && cfig.currentDNS == queue->dnsIndex)
  2953.         {
  2954.             cfig.currentDNS++;
  2955.  
  2956.             if (cfig.currentDNS >= MAX_SERVERS || !network.dns[cfig.currentDNS])
  2957.                 cfig.currentDNS = 0;
  2958.         }
  2959.  
  2960.         if (req->addr.sin_addr.s_addr != network.dns[cfig.currentDNS])
  2961.         {
  2962.             req->target.sin_family = AF_INET;
  2963.             req->target.sin_addr.s_addr = network.dns[cfig.currentDNS];
  2964.             req->target.sin_port = htons(IPPORT_DNS);
  2965.             errno = 0;
  2966.  
  2967.             nRet = sendto(network.forwConn.sock,
  2968.                           req->raw,
  2969.                           req->bytes,
  2970.                           0,
  2971.                           (sockaddr*)&req->target,
  2972.                           sizeof(req->target));
  2973.  
  2974.             errno = WSAGetLastError();
  2975.  
  2976.             if (errno || nRet <= 0)
  2977.             {
  2978.                 if (cfig.dnsLogLevel)
  2979.                 {
  2980.                     sprintf(logBuff, "Error forwading UDP DNS Message to Forwarding Server %s", IP2String(tempbuff, network.dns[cfig.currentDNS]));
  2981.                     logDNSMess(req, logBuff, 1);
  2982.                 }
  2983.  
  2984.                 if (network.dns[1])
  2985.                 {
  2986.                     cfig.currentDNS++;
  2987.  
  2988.                     if (cfig.currentDNS >= MAX_SERVERS || !network.dns[cfig.currentDNS])
  2989.                         cfig.currentDNS = 0;
  2990.                 }
  2991.  
  2992.                 return 0;
  2993.             }
  2994.             else
  2995.             {
  2996.                 if (cfig.dnsLogLevel == 2)
  2997.                 {
  2998.                     sprintf(logBuff, "%s forwarded to Forwarding Server %s", req->cname, IP2String(tempbuff, network.dns[cfig.currentDNS]));
  2999.                     logDNSMess(req, logBuff, 2);
  3000.                 }
  3001.             }
  3002.         }
  3003.  
  3004. //        if (nRet <= 0)
  3005. //        {
  3006. //            addRRNone(req);
  3007. //            req->dnsp->header.ra = 0;
  3008. //            req->dnsp->header.rcode = RCODE_SERVERFAIL;
  3009. //            return 0;
  3010. //        }
  3011.     }
  3012.  
  3013.     time_t t = time(NULL);
  3014.  
  3015.     if (!queue)
  3016.     {
  3017.         queue = (data7*)calloc(1, sizeof(data7));
  3018.         if (queue)
  3019.         {
  3020.             queue->mapname = cloneString(mapname);
  3021.             queue->addr = (SOCKADDR_IN*)calloc(1, sizeof(req->addr));
  3022.             queue->query = cloneString(req->query);
  3023.  
  3024.             if (!queue->mapname || !queue->addr || !queue->query)
  3025.             {
  3026.                 if (queue->mapname)
  3027.                     free(queue->mapname);
  3028.  
  3029.                 if (queue->addr)
  3030.                     free(queue->addr);
  3031.  
  3032.                 if (queue->query)
  3033.                     free(queue->query);
  3034.  
  3035.                 free(queue);
  3036.                 sprintf(logBuff, "Memory Allocation Error");
  3037.                 logDNSMess(logBuff, 1);
  3038.                 return 0;
  3039.             }
  3040.  
  3041.             memcpy(queue->addr, &req->addr, sizeof(req->addr));
  3042.             queue->expiry = 2 + t;
  3043.             queue->dataType = QUEUE;
  3044.             addEntry(cacheInd, queue);
  3045.         }
  3046.         else
  3047.         {
  3048.             sprintf(logBuff, "Memory Allocation Error");
  3049.             logDNSMess(logBuff, 1);
  3050.             return 0;
  3051.         }
  3052.     }
  3053.     else
  3054.     {
  3055.         queue->expiry = 2 + t;
  3056.         memcpy(queue->addr, &req->addr, sizeof(req->addr));
  3057.  
  3058.         if (strcasecmp(queue->query, req->query))
  3059.         {
  3060.             char *query = cloneString(req->query);
  3061.  
  3062.             if (query)
  3063.             {
  3064.                 free(queue->query);
  3065.                 queue->query = query;
  3066.             }
  3067.             else
  3068.             {
  3069.                 sprintf(logBuff, "Memory Allocation Error");
  3070.                 logDNSMess(logBuff, 1);
  3071.                 return 0;
  3072.             }
  3073.         }
  3074.     }
  3075.  
  3076.     queue->sockInd = req->sockInd;
  3077.  
  3078.     if (req->localCode == 4)
  3079.         queue->dnsIndex = 128 + (2 * zoneDNS) + cfig.dnsRoutes[zoneDNS].currentDNS;
  3080.     else
  3081.         queue->dnsIndex = cfig.currentDNS;
  3082.  
  3083.     //printf("%u %u\n", zoneDNS, queue->dnsIndex);
  3084.  
  3085.     return (nRet);
  3086. }
  3087.  
  3088. WORD frdnmess(data5 *req)
  3089. {
  3090.     memset(req, 0, sizeof(data5));
  3091.     req->sockLen = sizeof(req->addr);
  3092.     errno = 0;
  3093.  
  3094.     req->bytes = recvfrom(network.forwConn.sock,
  3095.                           req->raw,
  3096.                           sizeof(req->raw),
  3097.                           0,
  3098.                           (sockaddr*)&req->addr,
  3099.                           &req->sockLen);
  3100.  
  3101.     //printf("%u\n", req->bytes);
  3102.  
  3103.     errno = WSAGetLastError();
  3104.  
  3105.     if (errno || req->bytes <= 0)
  3106.         return 0;
  3107.  
  3108.     req->dnsp = (dnsPacket*)req->raw;
  3109.  
  3110.     char mapname[8];
  3111.     WORD type = 0;
  3112.     sprintf(mapname, "%u", req->dnsp->header.xid);
  3113.     data7 *queue = findEntry(cacheInd, mapname);
  3114.  
  3115.     if (queue && queue->expiry)
  3116.     {
  3117.         queue->expiry = 0;
  3118.  
  3119.         if (queue->dnsIndex < MAX_SERVERS)
  3120.         {
  3121.             if (req->addr.sin_addr.s_addr != network.dns[cfig.currentDNS])
  3122.             {
  3123.                 for (BYTE i = 0; i < MAX_SERVERS && network.dns[i]; i++)
  3124.                 {
  3125.                     if (network.dns[i] == req->addr.sin_addr.s_addr)
  3126.                     {
  3127.                         cfig.currentDNS = i;
  3128.                         break;
  3129.                     }
  3130.                 }
  3131.             }
  3132.         }
  3133.         else if (queue->dnsIndex >= 128 && queue->dnsIndex < 192)
  3134.         {
  3135.             data6 *dnsRoute = &cfig.dnsRoutes[(queue->dnsIndex - 128) / 2];
  3136.  
  3137.             if (dnsRoute->dns[0] == req->addr.sin_addr.s_addr)
  3138.                 dnsRoute->currentDNS = 0;
  3139.             else if (dnsRoute->dns[1] == req->addr.sin_addr.s_addr)
  3140.                 dnsRoute->currentDNS = 1;
  3141.         }
  3142.  
  3143.         if (queue->dataType == DNS_CHECK)
  3144.         {
  3145.             if (cfig.dnsLogLevel)
  3146.             {
  3147.                 if (queue->dnsIndex < MAX_SERVERS)
  3148.                 {
  3149.                     sprintf(logBuff, "Forwarding DNS Server %s responded", IP2String(tempbuff, req->addr.sin_addr.s_addr));
  3150.                     logDNSMess(logBuff, 1);
  3151.                 }
  3152.                 else if (queue->dnsIndex >= 128 && queue->dnsIndex < 192)
  3153.                 {
  3154.                     sprintf(logBuff, "Child DNS Server %s responded", IP2String(tempbuff, req->addr.sin_addr.s_addr));
  3155.                     logDNSMess(logBuff, 1);
  3156.                 }
  3157.             }
  3158.  
  3159.             return 0;
  3160.         }
  3161.         else if (queue->dataType == QUEUE)
  3162.         {
  3163.             memcpy(&req->addr, queue->addr, sizeof(req->addr));
  3164.             strcpy(req->query, queue->query);
  3165.             req->sockInd = queue->sockInd;
  3166.             req->cache.dnsIndex = queue->dnsIndex;
  3167.  
  3168.             req->data = &req->dnsp->data;
  3169.  
  3170.             for (int i = 1; i <= ntohs(req->dnsp->header.qdcount); i++)
  3171.             {
  3172.                 req->data += fQu(req->cname, req->dnsp, req->data);
  3173.                 type = fUShort(req->data);
  3174.                 req->data += 4; //type and class
  3175.             }
  3176.  
  3177.             if ((type == DNS_TYPE_A || type == DNS_TYPE_PTR) && !req->dnsp->header.rcode && !req->dnsp->header.tc && req->dnsp->header.ancount)
  3178.             {
  3179.                 time_t expiry = 0;
  3180.                 bool resultFound = false;
  3181.  
  3182.                 for (int i = 1; i <= ntohs(req->dnsp->header.ancount); i++)
  3183.                 {
  3184.                     req->data += fQu(tempbuff, req->dnsp, req->data);
  3185.                     type = fUShort(req->data);
  3186.  
  3187.                     //printf("%s %u=%u\n", tempbuff, type, DNS_TYPE_A);
  3188.  
  3189.                     if (type == DNS_TYPE_A)
  3190.                     {
  3191.                         resultFound = true;
  3192.                         strcpy(req->mapname, req->cname);
  3193.                         myLower(req->mapname);
  3194.                         makeLocal(req->mapname);
  3195.                     }
  3196.                     else if (type == DNS_TYPE_PTR)
  3197.                     {
  3198.                         strcpy(req->mapname, req->cname);
  3199.                         myLower(req->mapname);
  3200.                         char *dp = strstr(req->mapname, arpa);
  3201.  
  3202.                         if (dp && !strcasecmp(dp, arpa))
  3203.                         {
  3204.                             *dp = 0;
  3205.                             resultFound = true;
  3206.                         }
  3207.                     }
  3208.  
  3209.                     req->data += 4; //type and class
  3210.  
  3211.                     if (!expiry || fULong(req->data) < (DWORD)expiry)
  3212.                         expiry = fULong(req->data);
  3213.  
  3214.                     req->data += 4; //ttl
  3215.                     int zLen = fUShort(req->data);
  3216.                     req->data += 2; //datalength
  3217.                     req->data += zLen;
  3218.                 }
  3219.  
  3220.                 time_t t = time(NULL);
  3221.  
  3222.                 if (resultFound)
  3223.                 {
  3224.                     WORD cacheSize = (DWORD)req->data - (DWORD)req->raw;
  3225.  
  3226.                     if (cfig.minCache && expiry < cfig.minCache)
  3227.                         expiry = cfig.minCache;
  3228.  
  3229.                     if (cfig.maxCache && expiry > cfig.maxCache)
  3230.                         expiry = cfig.maxCache;
  3231.  
  3232.                     if (expiry < LONG_MAX - t)
  3233.                         expiry += t;
  3234.                     else
  3235.                         expiry = LONG_MAX;
  3236.  
  3237.                     data7 *cache = findEntry(cacheInd, req->mapname, CACHED);
  3238.  
  3239.                     if (cache)
  3240.                     {
  3241.                         if (cache->bytes < cacheSize)
  3242.                         {
  3243.                             BYTE *response = (BYTE*)calloc(1, cacheSize);
  3244.  
  3245.                             if (response)
  3246.                             {
  3247.                                 if (cache->response)
  3248.                                     free(cache->response);
  3249.  
  3250.                                 cache->response = response;
  3251.                             }
  3252.                             else
  3253.                             {
  3254.                                 sprintf(logBuff, "Memory Allocation Error");
  3255.                                 logDNSMess(logBuff, 1);
  3256.                                 return 0;
  3257.                             }
  3258.                         }
  3259.                         cache->expiry = expiry;
  3260.                     }
  3261.                     else
  3262.                     {
  3263.                         //checkSize();
  3264.                         cache = (data7*)calloc(1, sizeof(data7));
  3265.  
  3266.                         if (!cache)
  3267.                         {
  3268.                             sprintf(logBuff, "Memory Allocation Error");
  3269.                             logDNSMess(logBuff, 1);
  3270.                             return 0;
  3271.                         }
  3272.  
  3273.                         cache->mapname = cloneString(req->mapname);
  3274.                         cache->response = (BYTE*)calloc(1, cacheSize);
  3275.  
  3276.                         if (!cache->mapname || !cache->response)
  3277.                         {
  3278.                             if (cache->mapname)
  3279.                                 free(cache->mapname);
  3280.  
  3281.                             if (cache->response)
  3282.                                 free(cache->response);
  3283.  
  3284.                             free(cache);
  3285.  
  3286.                             sprintf(logBuff, "Memory Allocation Error");
  3287.                             logDNSMess(logBuff, 1);
  3288.                             return 0;
  3289.                         }
  3290.  
  3291.                         cache->expiry = expiry;
  3292.                         cache->dataType = CACHED;
  3293.                         addEntry(cacheInd, cache);
  3294.  
  3295.                     }
  3296.  
  3297.                     memcpy(cache->response, req->dnsp, cacheSize);
  3298.                     ((dnsPacket*)cache->response)->header.nscount = 0;
  3299.                     ((dnsPacket*)cache->response)->header.adcount = 0;
  3300.                     cache->bytes = cacheSize;
  3301.                 }
  3302.             }
  3303.  
  3304.             req->cache.dataType = NON_CACHED;
  3305.             addRRExt(req);
  3306.             return 1;
  3307.         }    
  3308.     }
  3309.     return 0;
  3310. }
  3311.  
  3312. void addToCache(BYTE ind, char *hostname, DWORD ip, time_t expiry, BYTE aType, BYTE pType, DWORD serial)
  3313. {
  3314.     //printf("Adding to %u, %s=%s exp=%u\n",ind, hostname,IP2String(tempbuff, ip),expiry);
  3315.     char tempbuff[256];
  3316.     char logBuff[256];
  3317.  
  3318.     if (!hostname[0] || !ip)
  3319.         return;
  3320.  
  3321.     data7 *cache = NULL;
  3322.     hostMap::iterator p;
  3323.  
  3324.     if (pType)
  3325.     {
  3326.         IP2String(tempbuff, htonl(ip));
  3327.         p = dnsCache[ind].find(tempbuff);
  3328.  
  3329.         for (;p != dnsCache[ind].end(); p++)
  3330.         {
  3331.             if (strcasecmp(p->second->mapname, tempbuff))
  3332.                 break;
  3333.  
  3334.             if (!strcasecmp(p->second->hostname, hostname))
  3335.             {
  3336.                 cache = p->second;
  3337.                 break;
  3338.             }
  3339.         }
  3340.  
  3341.         if (!cache)
  3342.         {
  3343.             //checkSize();
  3344.             cache = (data7*)calloc(1, sizeof(data7));
  3345.             if (cache)
  3346.             {
  3347.                 cache->mapname = cloneString(tempbuff);
  3348.                 cache->hostname = cloneString(hostname);
  3349.  
  3350.                 if (!cache->mapname || !cache->hostname)
  3351.                 {
  3352.                     if (cache->mapname)
  3353.                         free(cache->mapname);
  3354.  
  3355.                     if (cache->hostname)
  3356.                         free(cache->hostname);
  3357.  
  3358.                     free(cache);
  3359.  
  3360.                     sprintf(logBuff, "Memory Allocation Error");
  3361.                     logDNSMess(logBuff, 1);
  3362.                     return ;
  3363.                 }
  3364.  
  3365.                 cache->dataType = pType;
  3366.                 cache->expiry = expiry;
  3367.                 addEntry(ind, cache);
  3368.             }
  3369.             else
  3370.             {
  3371.                 sprintf(logBuff, "Memory Allocation Error");
  3372.                 logDNSMess(logBuff, 1);
  3373.                 return ;
  3374.             }
  3375.         }
  3376.         else
  3377.         {
  3378.             if (strcasecmp(hostname, cache->hostname))
  3379.             {
  3380.                 free(cache->hostname);
  3381.                 cache->hostname = cloneString(hostname);
  3382.             }
  3383.  
  3384.             if (cache->expiry < expiry)
  3385.                 cache->expiry = expiry;
  3386.         }
  3387.         cache->serial = serial;
  3388.     }
  3389.  
  3390.     if (aType)
  3391.     {
  3392.         cache = NULL;
  3393.         strcpy(tempbuff, hostname);
  3394.         makeLocal(tempbuff);
  3395.         myLower(tempbuff);
  3396.  
  3397.         p = dnsCache[ind].find(tempbuff);
  3398.  
  3399.         for (; p != dnsCache[ind].end(); p++)
  3400.         {
  3401.             if (strcasecmp(p->second->mapname, tempbuff))
  3402.                 break;
  3403.  
  3404.             if (p->second->ip == ip)
  3405.             {
  3406.                 cache = p->second;
  3407.                 break;
  3408.             }
  3409.         }
  3410.  
  3411.         if (!cache)
  3412.         {
  3413.             //checkSize();
  3414.             cache = (data7*)calloc(1, sizeof(data7));
  3415.             if (cache)
  3416.             {
  3417.                 cache->mapname = cloneString(tempbuff);
  3418.  
  3419.                 if (!cache->mapname)
  3420.                 {
  3421.                     sprintf(logBuff, "Memory Allocation Error");
  3422.                     free(cache);
  3423.                     logDNSMess(logBuff, 1);
  3424.                     return ;
  3425.                 }
  3426.  
  3427.                 cache->ip = ip;
  3428.                 cache->dataType = aType;
  3429.                 cache->expiry = expiry;
  3430.                 addEntry(ind, cache);
  3431.             }
  3432.             else
  3433.             {
  3434.                 sprintf(logBuff, "Memory Allocation Error");
  3435.                 logDNSMess(logBuff, 1);
  3436.                 return ;
  3437.             }
  3438.         }
  3439.         else
  3440.         {
  3441.             cache->ip = ip;
  3442.  
  3443.             if (cache->expiry < expiry)
  3444.                 cache->expiry = expiry;
  3445.         }
  3446.         cache->serial = serial;
  3447.     }
  3448. }
  3449.  
  3450. char* getResult(data5 *req)
  3451. {
  3452.     tempbuff[0] = 0;
  3453.     extbuff[0] = 0;
  3454.     char *raw = &req->dnsp->data;
  3455.     WORD queueIndex;
  3456.  
  3457.     for (int i = 1; i <= ntohs(req->dnsp->header.qdcount); i++)
  3458.     {
  3459.         raw += fQu(extbuff, req->dnsp, raw);
  3460.         raw += 4;
  3461.     }
  3462.  
  3463.     for (int i = 1; i <= ntohs(req->dnsp->header.ancount); i++)
  3464.     {
  3465.         raw += fQu(extbuff, req->dnsp, raw);
  3466.         int type = fUShort(raw);
  3467.         raw += 2; //type
  3468.         raw += 2; //class
  3469.         raw += 4; //ttl
  3470.         int zLen = fUShort(raw);
  3471.         raw += 2; //datalength
  3472.  
  3473.         if (type == DNS_TYPE_A)
  3474.             return IP2String(tempbuff, fIP(raw));
  3475.         else if (type == DNS_TYPE_AAAA)
  3476.             return IP62String(tempbuff, (BYTE*)raw);
  3477.         else if (type == DNS_TYPE_PTR)
  3478.         {
  3479.             fQu(tempbuff, req->dnsp, raw);
  3480.             return tempbuff;
  3481.         }
  3482.         else if (type == DNS_TYPE_MX)
  3483.         {
  3484.             fQu(tempbuff, req->dnsp, ++++raw);
  3485.             return tempbuff;
  3486.         }
  3487.         else if (type == DNS_TYPE_CNAME)
  3488.         {
  3489.             fQu(tempbuff, req->dnsp, raw);
  3490.         }
  3491.         raw += zLen;
  3492.     }
  3493.  
  3494.     if (tempbuff[0])
  3495.         return tempbuff;
  3496.     else
  3497.         return NULL;
  3498. }
  3499.  
  3500.  
  3501. bool checkRange(char rangeInd, bool macFound, bool vendFound, bool userFound)
  3502. {
  3503.     if (!cfig.hasFilter)
  3504.         return true;
  3505.  
  3506.     BYTE rangeSetInd = cfig.dhcpRanges[rangeInd].rangeSetInd;
  3507.     data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
  3508.     //printf("checkRange entering, rangeInd=%i rangeSetInd=%i\n", rangeInd, rangeSetInd);
  3509.     //printf("checkRange entered, macFound=%i vendFound=%i userFound=%i\n", macFound, vendFound, userFound);
  3510.  
  3511.     if((!macFound && !rangeSet->macSize[0]) || (macFound && cfig.macArray[rangeSetInd]))
  3512.         if((!vendFound && !rangeSet->vendClassSize[0]) || (vendFound && cfig.vendArray[rangeSetInd]))
  3513.             if((!userFound && !rangeSet->userClassSize[0]) || (userFound && cfig.userArray[rangeSetInd]))
  3514.                 return true;
  3515.  
  3516.     //printf("checkRange, returning false rangeInd=%i rangeSetInd=%i\n", rangeInd, rangeSetInd);
  3517.     return false;
  3518. }
  3519.  
  3520. DWORD resad(data9 *req)
  3521. {
  3522.     time_t t = time(NULL);
  3523.     DWORD minRange = 0;
  3524.     DWORD maxRange = 0;
  3525.  
  3526.     if (req->dhcpp.header.bp_giaddr)
  3527.     {
  3528.         setLeaseExpiry(req->dhcpp.header.bp_giaddr, LONG_MAX);
  3529.         setLeaseExpiry(req->addr.sin_addr.s_addr, LONG_MAX);
  3530.     }
  3531.  
  3532.     DWORD iipNew = 0;
  3533.     DWORD iipExp = 0;
  3534.     DWORD rangeStart = 0;
  3535.     DWORD rangeEnd = 0;
  3536.     char rangeInd = -1;
  3537.     bool rangeFound = false;
  3538.     bool macFound = false;
  3539.     bool vendFound = false;
  3540.     bool userFound = false;
  3541.     memset(cfig.macArray, 0, sizeof(cfig.macArray));
  3542.     memset(cfig.vendArray, 0, sizeof(cfig.vendArray));
  3543.     memset(cfig.userArray, 0, sizeof(cfig.userArray));
  3544.  
  3545.     if (cfig.hasFilter)
  3546.     {
  3547.         for (BYTE rangeSetInd = 0; rangeSetInd < MAX_RANGES && cfig.rangeSet[rangeSetInd].active; rangeSetInd++)
  3548.         {
  3549.             data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
  3550.  
  3551.             for (BYTE i = 0; i < 32 && rangeSet->macSize[i]; i++)
  3552.             {
  3553.                 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)
  3554.                 {
  3555.                     cfig.macArray[rangeSetInd] = true;
  3556.                     macFound = true;
  3557.                     //printf("mac Found, rangeSetInd=%i\n", rangeSetInd);
  3558.                     break;
  3559.                 }
  3560.             }
  3561.  
  3562.             for (BYTE i = 0; i < 32 && rangeSet->vendClassSize[i]; i++)
  3563.             {
  3564.                 if(req->vendClassSize && rangeSet->vendClassSize[i] == req->vendClassSize && !memcmp(req->vendClass, rangeSet->vendClass[i], rangeSet->vendClassSize[i]))
  3565.                 {
  3566.                     cfig.vendArray[rangeSetInd] = true;
  3567.                     vendFound = true;
  3568.                     printf("vend Found, rangeSetInd=%i\n", rangeSetInd);
  3569.                     break;
  3570.                 }
  3571.             }
  3572.  
  3573.             for (BYTE i = 0; i < 32 && rangeSet->userClassSize[i]; i++)
  3574.             {
  3575.                 if(req->userClassSize && rangeSet->userClassSize[i] == req->userClassSize && !memcmp(req->userClass, rangeSet->userClass[i], rangeSet->userClassSize[i]))
  3576.                 {
  3577.                     cfig.userArray[rangeSetInd] = true;
  3578.                     userFound = true;
  3579.                     //printf("user Found, rangeSetInd=%i\n", rangeSetInd);
  3580.                     break;
  3581.                 }
  3582.             }
  3583.         }
  3584.  
  3585.     }
  3586.  
  3587. //    printArray("macArray", (char*)cfig.macArray);
  3588. //    printArray("vendArray", (char*)cfig.vendArray);
  3589. //    printArray("userArray", (char*)cfig.userArray);
  3590.  
  3591.     if (chad(req))
  3592.     {
  3593.         bool rangeOK = req->dhcpEntry->fixed;
  3594.  
  3595.         if (!rangeOK && req->dhcpEntry->rangeInd >= 0)
  3596.             rangeOK = checkRange(req->dhcpEntry->rangeInd, macFound, vendFound, userFound);
  3597.  
  3598.         if (rangeOK)
  3599.         {
  3600.             DWORD mask = INADDR_NONE;
  3601.  
  3602.             if (req->dhcpEntry->bitmask)
  3603.                 mask = htonl(mask << (32 - req->dhcpEntry->bitmask));
  3604.             else if (req->dhcpEntry->rangeInd >= 0)
  3605.                 mask = cfig.dhcpRanges[req->dhcpEntry->rangeInd].mask;
  3606.             else
  3607.                 mask = cfig.mask;
  3608.  
  3609.             if (req->dhcpp.header.bp_giaddr)
  3610.                 calcRangeLimits(req->dhcpp.header.bp_giaddr, mask, &minRange, &maxRange);
  3611.             else if (htonl(network.dhcpConn[req->sockInd].mask) > htonl(mask))
  3612.                 calcRangeLimits(network.dhcpConn[req->sockInd].server, network.dhcpConn[req->sockInd].mask, &minRange, &maxRange);
  3613.             else
  3614.                 calcRangeLimits(network.dhcpConn[req->sockInd].server, mask, &minRange, &maxRange);
  3615.  
  3616.             if (htonl(req->dhcpEntry->ip) >= minRange && htonl(req->dhcpEntry->ip) <= maxRange)
  3617.             {
  3618.                 setLeaseExpiry(req->dhcpEntry, 20, false);
  3619.                 return req->dhcpEntry->ip;
  3620.             }
  3621.             else if (req->dhcpEntry->fixed)
  3622.             {
  3623.                 req->dhcpEntry->no_route = 1;
  3624.                 setLeaseExpiry(req->dhcpEntry, 20, false);
  3625.                 return req->dhcpEntry->ip;
  3626.             }
  3627.         }
  3628.     }
  3629.  
  3630.     if (req->hostname[0])
  3631.     {
  3632.         char hostname[256];
  3633.         strcpy(hostname, req->hostname);
  3634.         myLower(hostname);
  3635.         hostMap::iterator it = dnsCache[cacheInd].find(hostname);
  3636.  
  3637.         for (; it != dnsCache[cacheInd].end(); it++)
  3638.         {
  3639.             data7 *cache = it->second;
  3640.  
  3641.             //printf("%u\n", cache->mapname);
  3642.  
  3643.             if (strcasecmp(cache->mapname, hostname))
  3644.                 break;
  3645.  
  3646.             if (cache && cache->ip)
  3647.             {
  3648.                 char k = getRangeInd(cache->ip);
  3649.  
  3650.                 if (k >= 0)
  3651.                 {
  3652.                     if (checkRange(k, macFound, vendFound, userFound))
  3653.                     {
  3654.                         char ind = getIndex(k, cache->ip);
  3655.                         data13 *range = &cfig.dhcpRanges[k];
  3656.  
  3657.                         if (ind >= 0 && range->expiry[ind] <= t && !range->dhcpEntry[ind])
  3658.                         {
  3659.                             if (req->dhcpp.header.bp_giaddr)
  3660.                                 calcRangeLimits(req->dhcpp.header.bp_giaddr, range->mask, &minRange, &maxRange);
  3661.                             else if (htonl(network.dhcpConn[req->sockInd].mask) > htonl(range->mask))
  3662.                                 calcRangeLimits(network.dhcpConn[req->sockInd].server, network.dhcpConn[req->sockInd].mask, &minRange, &maxRange);
  3663.                             else
  3664.                                 calcRangeLimits(network.dhcpConn[req->sockInd].server, range->mask, &minRange, &maxRange);
  3665.  
  3666.                             DWORD iip = htonl(cache->ip);
  3667.  
  3668.                             if (iip >= minRange && iip <= maxRange)
  3669.                             {
  3670.                                 iipNew = iip;
  3671.                                 rangeInd = k;
  3672.                                 break;
  3673.                             }
  3674.                         }
  3675.                     }
  3676.                 }
  3677.             }
  3678.         }
  3679.     }
  3680.  
  3681.     if (!iipNew && req->reqIP)
  3682.     {
  3683.         char k = getRangeInd(req->reqIP);
  3684.  
  3685.         if (k >= 0)
  3686.         {
  3687.             if (checkRange(k, macFound, vendFound, userFound))
  3688.             {
  3689.                 data13 *range = &cfig.dhcpRanges[k];
  3690.                 char ind = getIndex(k, req->reqIP);
  3691.  
  3692.                 if (ind >= 0 && range->expiry[ind] <= t)
  3693.                 {
  3694.                     if (req->dhcpp.header.bp_giaddr)
  3695.                         calcRangeLimits(req->dhcpp.header.bp_giaddr, range->mask, &minRange, &maxRange);
  3696.                     else if (htonl(network.dhcpConn[req->sockInd].mask) > htonl(range->mask))
  3697.                         calcRangeLimits(network.dhcpConn[req->sockInd].server, network.dhcpConn[req->sockInd].mask, &minRange, &maxRange);
  3698.                     else
  3699.                         calcRangeLimits(network.dhcpConn[req->sockInd].server, range->mask, &minRange, &maxRange);
  3700.  
  3701.                     DWORD iip = htonl(req->reqIP);
  3702.  
  3703.                     if (iip >= minRange && iip <= maxRange)
  3704.                     {
  3705.                         iipNew = iip;
  3706.                         rangeInd = k;
  3707.                     }
  3708.                 }
  3709.             }
  3710.         }
  3711.     }
  3712.  
  3713.     for (char k = 0; !iipNew && k < MAX_RANGES && cfig.dhcpRanges[k].rangeStart; k++)
  3714.     {
  3715.         if (checkRange(k, macFound, vendFound, userFound))
  3716.         {
  3717.             data13 *range = &cfig.dhcpRanges[k];
  3718.             rangeStart = range->rangeStart;
  3719.             rangeEnd = range->rangeEnd;
  3720.  
  3721.             if (req->dhcpp.header.bp_giaddr)
  3722.                 calcRangeLimits(req->dhcpp.header.bp_giaddr, range->mask, &minRange, &maxRange);
  3723.             else if (htonl(network.dhcpConn[req->sockInd].mask) > htonl(range->mask))
  3724.                 calcRangeLimits(network.dhcpConn[req->sockInd].server, network.dhcpConn[req->sockInd].mask, &minRange, &maxRange);
  3725.             else
  3726.                 calcRangeLimits(network.dhcpConn[req->sockInd].server, range->mask, &minRange, &maxRange);
  3727.  
  3728.             if (rangeStart < minRange)
  3729.                 rangeStart = minRange;
  3730.  
  3731.             if (rangeEnd > maxRange)
  3732.                 rangeEnd = maxRange;
  3733.  
  3734.             if (rangeStart <= rangeEnd)
  3735.             {
  3736.                 rangeFound = true;
  3737.  
  3738.                 for (DWORD m = rangeStart; m <= rangeEnd; m++)
  3739.                 {
  3740.                     if (!range->expiry[m - range->rangeStart])
  3741.                     {
  3742.                         iipNew = m;
  3743.                         rangeInd = k;
  3744.                         break;
  3745.                     }
  3746.                     else if (!iipExp && range->expiry[m - range->rangeStart] < t)
  3747.                     {
  3748.                         iipExp = m;
  3749.                         rangeInd = k;
  3750.                     }
  3751.                 }
  3752.             }
  3753.         }
  3754.     }
  3755.  
  3756.     if (!iipNew && iipExp)
  3757.     {
  3758.         char ind = iipExp - cfig.dhcpRanges[rangeInd].rangeStart;
  3759.         req->dhcpEntry = cfig.dhcpRanges[rangeInd].dhcpEntry[ind];
  3760.  
  3761.         if (req->dhcpEntry)
  3762.         {
  3763.             dhcpCache.erase(req->dhcpEntry->mapname);
  3764.             free(req->dhcpEntry->mapname);
  3765.             req->dhcpEntry->mapname = cloneString(toUUE(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen));
  3766.  
  3767.             if (!req->dhcpEntry->mapname)
  3768.             {
  3769.                 sprintf(logBuff, "Memory Allocation Error");
  3770.                 logDHCPMess(logBuff, 1);
  3771.                 return 0;
  3772.             }
  3773.  
  3774.             dhcpCache[req->dhcpEntry->mapname] = req->dhcpEntry;
  3775.             req->dhcpEntry->ip = htonl(iipExp);
  3776.             req->dhcpEntry->rangeInd = rangeInd;
  3777.             setLeaseExpiry(req->dhcpEntry, 20, false);
  3778.  
  3779.             if (!req->dhcpEntry->fixed)
  3780.             {
  3781.                 if (req->dhcpp.header.bp_giaddr)
  3782.                     req->dhcpEntry->source = req->dhcpp.header.bp_giaddr;
  3783.                 else
  3784.                     req->dhcpEntry->source = network.dhcpConn[req->sockInd].server;
  3785.             }
  3786.  
  3787.             return req->dhcpEntry->ip;
  3788.         }
  3789.         else
  3790.             iipNew = iipExp;
  3791.     }
  3792.  
  3793.     if (iipNew)
  3794.     {
  3795.         if (!req->dhcpEntry)
  3796.         {
  3797.             req->dhcpEntry = (data7*)calloc(1, sizeof(data7));
  3798.  
  3799.             if (!req->dhcpEntry)
  3800.             {
  3801.                 sprintf(logBuff, "Memory Allocation Error");
  3802.                 logDHCPMess(logBuff, 1);
  3803.                 return 0;
  3804.             }
  3805.  
  3806.             req->dhcpEntry->mapname = cloneString(toUUE(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen));
  3807.  
  3808.             if (!req->dhcpEntry->mapname)
  3809.             {
  3810.                 sprintf(logBuff, "Memory Allocation Error");
  3811.                 free(req->dhcpEntry);
  3812.                 logDHCPMess(logBuff, 1);
  3813.                 return 0;
  3814.             }
  3815.  
  3816.             dhcpCache[req->dhcpEntry->mapname] = req->dhcpEntry;
  3817.         }
  3818.  
  3819.         req->dhcpEntry->ip = htonl(iipNew);
  3820.         req->dhcpEntry->rangeInd = rangeInd;
  3821.         setLeaseExpiry(req->dhcpEntry, 20, false);
  3822.  
  3823.         if (!req->dhcpEntry->fixed)
  3824.         {
  3825.             if (req->dhcpp.header.bp_giaddr)
  3826.                 req->dhcpEntry->source = req->dhcpp.header.bp_giaddr;
  3827.             else
  3828.                 req->dhcpEntry->source = network.dhcpConn[req->sockInd].server;
  3829.         }
  3830.  
  3831.         return req->dhcpEntry->ip;
  3832.     }
  3833.  
  3834.     if (!iipNew)
  3835.     {
  3836.         if (cfig.dhcpLogLevel)
  3837.         {
  3838.             if (rangeFound)
  3839.             {
  3840.                 if (req->dhcpp.header.bp_giaddr)
  3841.                     sprintf(logBuff, "No free leases for DHCP discover for %s (%s) from RelayAgent %s", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_giaddr));
  3842.                 else
  3843.                     sprintf(logBuff, "No free leases for DHCP discover for %s (%s) from interface %s", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname, IP2String(tempbuff, network.dhcpConn[req->sockInd].server));
  3844.             }
  3845.             else
  3846.             {
  3847.                 if (req->dhcpp.header.bp_giaddr)
  3848.                     sprintf(logBuff, "No Matching DHCP Range for DHCP discover for %s (%s) from RelayAgent %s", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_giaddr));
  3849.                 else
  3850.                     sprintf(logBuff, "No Matching DHCP Range for DHCP discover for %s (%s) from interface %s", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname, IP2String(tempbuff, network.dhcpConn[req->sockInd].server));
  3851.             }
  3852.             logMess(logBuff, 1);
  3853.         }
  3854.     }
  3855.     return 0;
  3856. }
  3857.  
  3858. DWORD chad(data9 *req)
  3859. {
  3860.     req->dhcpEntry = dhcpCache[toUUE(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen)];
  3861.  
  3862.     if (req->dhcpEntry && req->dhcpEntry->ip && (req->dhcpEntry->fixed || (req->dhcpp.header.bp_giaddr && req->dhcpEntry->source == req->dhcpp.header.bp_giaddr) || req->dhcpEntry->source == network.dhcpConn[req->sockInd].server))
  3863.     {
  3864.         if (!req->hostname[0])
  3865.         {
  3866.             data7 *cache = findEntry(cacheInd, IP2String(tempbuff, htonl(req->dhcpEntry->ip)));
  3867.  
  3868.             if (cache && cache->hostname)
  3869.                 strcpy(req->hostname, cache->hostname);
  3870.             else
  3871.                 sprintf(req->hostname, "%s", hex2String(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, '-'));
  3872.         }
  3873.         return req->dhcpEntry->ip;
  3874.     }
  3875.     else
  3876.         return 0;
  3877. }
  3878.  
  3879. DWORD sdmess(data9 *req)
  3880. {
  3881.     time_t t = time(NULL);
  3882.  
  3883.     //printf("Request=%u Req IP=%s\n",req->req_type, IP2String(tempbuff, req->dhcpp.header.bp_ciaddr));
  3884.     if (req->req_type == DHCP_MESS_NONE)
  3885.     {
  3886.         req->dhcpp.header.bp_yiaddr = chad(req);
  3887.  
  3888.         if (!req->dhcpp.header.bp_yiaddr)
  3889.         {
  3890.             if (cfig.dhcpLogLevel)
  3891.             {
  3892.                 sprintf(logBuff, "No Static Entry found for BOOTP request from client %s", hex2String(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'));
  3893.                 logMess(logBuff, 1);
  3894.             }
  3895.             return 0;
  3896.         }
  3897.     }
  3898.     else if (req->req_type == DHCP_MESS_DECLINE)
  3899.     {
  3900.         if (chad(req) == req->dhcpp.header.bp_ciaddr)
  3901.         {
  3902.             setLeaseExpiry(req->dhcpp.header.bp_ciaddr, LONG_MAX);
  3903.  
  3904.             req->dhcpEntry->ip = 0;
  3905.  
  3906.             if (cfig.dhcpLogLevel)
  3907.             {
  3908.                 sprintf(logBuff, "IP Address %s declined by Client %s (%s), locked", IP2String(tempbuff, req->dhcpp.header.bp_ciaddr), req->hostname, hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'));
  3909.                 logMess(logBuff, 1);
  3910.             }
  3911.         }
  3912.  
  3913.         return 0;
  3914.     }
  3915.     else if (req->req_type == DHCP_MESS_RELEASE)
  3916.     {
  3917.         if (chad(req) == req->dhcpp.header.bp_ciaddr)
  3918.         {
  3919.             updateDHCP(req);
  3920.  
  3921.             if (req->dhcpEntry->local && cfig.replication)
  3922.                 sendRepl(req);
  3923.  
  3924.             if (cfig.dhcpLogLevel == 2)
  3925.             {
  3926.                 sprintf(logBuff, "IP Address %s released by Client %s (%s)", IP2String(tempbuff, req->dhcpp.header.bp_ciaddr), req->hostname, hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname);
  3927.                 logMess(logBuff, 2);
  3928.             }
  3929.         }
  3930.  
  3931.         return 0;
  3932.     }
  3933.     else if (req->req_type == DHCP_MESS_INFORM)
  3934.     {
  3935.         recvRepl(req);
  3936.         return 0;
  3937.     }
  3938.     else if (req->req_type == DHCP_MESS_DISCOVER && strcasecmp(req->hostname, cfig.servername))
  3939.     {
  3940.         req->dhcpp.header.bp_yiaddr = resad(req);
  3941.  
  3942.         if (!req->dhcpp.header.bp_yiaddr)
  3943.             return 0;
  3944.  
  3945.         req->resp_type = DHCP_MESS_OFFER;
  3946.     }
  3947.     else if (req->req_type == DHCP_MESS_REQUEST)
  3948.     {
  3949.         //printf("%s\n", IP2String(tempbuff, req->dhcpp.header.bp_ciaddr));
  3950.  
  3951.         if (req->server)
  3952.         {
  3953.             if (req->server == network.dhcpConn[req->sockInd].server)
  3954.             {
  3955.                 if (req->reqIP && req->reqIP == chad(req) && req->dhcpEntry->expiry > t)
  3956.                 {
  3957.                     req->resp_type = DHCP_MESS_ACK;
  3958.                     req->dhcpp.header.bp_yiaddr = req->reqIP;
  3959.                 }
  3960.                 else if (req->dhcpp.header.bp_ciaddr && req->dhcpp.header.bp_ciaddr == chad(req) && req->dhcpEntry->expiry > t)
  3961.                 {
  3962.                     req->resp_type = DHCP_MESS_ACK;
  3963.                     req->dhcpp.header.bp_yiaddr = req->dhcpp.header.bp_ciaddr;
  3964.                 }
  3965.                 else
  3966.                 {
  3967.                     req->resp_type = DHCP_MESS_NAK;
  3968.                     if (cfig.dhcpLogLevel >= 1)
  3969.                     {
  3970.                         sprintf(logBuff, "DHCP Request from Client %s (%s), without Discover, NAK'd", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname);
  3971.                         logMess(logBuff, 1);
  3972.                     }
  3973.                     //return 0;
  3974.                 }
  3975.             }
  3976.             else
  3977.             {
  3978.                 if (!req->hostname[0])
  3979.                     sprintf(req->hostname, "%s", hex2String(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, '-'));
  3980.  
  3981.                 if (cfig.dhcpLogLevel == 2)
  3982.                 {
  3983.                     if (req->dhcpp.header.bp_sname[0])
  3984.                         sprintf(logBuff, "DHCP Request from Client %s (%s), for Server %s, ignored", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname, req->dhcpp.header.bp_sname);
  3985.                     else
  3986.                         sprintf(logBuff, "DHCP Request from Client %s (%s), for Server %s, ignored", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname, IP2String(tempbuff, req->server));
  3987.  
  3988.                     logMess(logBuff, 2);
  3989.                 }
  3990.                 return 0;
  3991.             }
  3992.         }
  3993.         else if (req->dhcpp.header.bp_ciaddr && req->dhcpp.header.bp_ciaddr == chad(req) && req->dhcpEntry->expiry > t)
  3994.         {
  3995.             req->resp_type = DHCP_MESS_ACK;
  3996.             req->dhcpp.header.bp_yiaddr = req->dhcpp.header.bp_ciaddr;
  3997.         }
  3998.         else if (req->reqIP && req->reqIP == chad(req) && req->dhcpEntry->expiry > t)
  3999.         {
  4000.             req->resp_type = DHCP_MESS_ACK;
  4001.             req->dhcpp.header.bp_yiaddr = req->reqIP;
  4002.         }
  4003.         else
  4004.         {
  4005.             req->resp_type = DHCP_MESS_NAK;
  4006.             if (cfig.dhcpLogLevel == 2)
  4007.             {
  4008.                 sprintf(logBuff, "DHCP Request from Client %s (%s) without Discover, NAK'd", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname);
  4009.                 logMess(logBuff, 1);
  4010.             }
  4011.             //return 0;
  4012.         }
  4013.     }
  4014.     else
  4015.         return 0;
  4016.  
  4017.     addOptions(req);
  4018.     int packSize = (DWORD)(req->vp) - (DWORD)&req->dhcpp;
  4019.     packSize++;
  4020.  
  4021.     if (req->req_type == DHCP_MESS_NONE)
  4022.         packSize = req->bytes;
  4023.  
  4024.     if (req->dhcpp.header.bp_giaddr)
  4025.     {
  4026.         req->addr.sin_port = htons(IPPORT_DHCPS);
  4027.         req->addr.sin_addr.s_addr = req->dhcpp.header.bp_giaddr;
  4028.     }
  4029.     else if (req->dhcpp.header.bp_broadcast || !req->addr.sin_addr.s_addr)
  4030.     {
  4031.         req->addr.sin_port = htons(IPPORT_DHCPC);
  4032.         req->addr.sin_addr.s_addr = INADDR_BROADCAST;
  4033.     }
  4034.     else
  4035.     {
  4036.         req->addr.sin_port = htons(IPPORT_DHCPC);
  4037.     }
  4038.  
  4039.     req->dhcpp.header.bp_op = BOOTP_REPLY;
  4040.     errno = 0;
  4041.  
  4042.     req->bytes = sendto(network.dhcpConn[req->sockInd].sock,
  4043.                         req->raw,
  4044.                         packSize,
  4045.                         0, //MSG_DONTROUTE,
  4046.                         (sockaddr*)&req->addr,
  4047.                         sizeof(req->addr));
  4048.  
  4049.     if (errno || req->bytes <= 0)
  4050.         return 0;
  4051.  
  4052.     //printf("goes=%s %i\n",IP2String(tempbuff, req->dhcpp.header.bp_yiaddr),req->sockInd);
  4053.     return req->dhcpp.header.bp_yiaddr;
  4054. }
  4055.  
  4056. DWORD alad(data9 *req)
  4057. {
  4058.     time_t t = time(NULL);
  4059.  
  4060.     //printf("in\n");
  4061.     if (req->dhcpEntry && (req->req_type == DHCP_MESS_NONE || req->resp_type == DHCP_MESS_ACK))
  4062.     {
  4063.         if (req->reqIP || req->req_type == DHCP_MESS_NONE)
  4064.         {
  4065.             cfig.serial1 = t;
  4066.             cfig.serial2 = t;
  4067.  
  4068.             if (cfig.replication == 2)
  4069.             {
  4070.                 if (cfig.expire > (DWORD)(LONG_MAX - t))
  4071.                     cfig.expireTime = LONG_MAX;
  4072.                 else
  4073.                     cfig.expireTime = t + cfig.expire;
  4074.             }
  4075.             else
  4076.                 cfig.expireTime = LONG_MAX;
  4077.         }
  4078.  
  4079.         DWORD retVal = updateDHCP(req);
  4080.  
  4081.         if (retVal)
  4082.         {
  4083.             if (cfig.dhcpLogLevel == 2)
  4084.             {
  4085.                 if (req->lease && req->reqIP)
  4086.                 {
  4087.                     sprintf(logBuff, "Client %s (%s) allotted %s for %u seconds", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr), req->lease);
  4088.                 }
  4089.                 else if (req->req_type)
  4090.                 {
  4091.                     sprintf(logBuff, "Client %s (%s) renewed %s for %u seconds", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr), req->lease);
  4092.                 }
  4093.                 else
  4094.                 {
  4095.                     sprintf(logBuff, "BOOTP Client %s (%s) allotted %s", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr));
  4096.                 }
  4097.                 logMess(logBuff, 2);
  4098.             }
  4099.             
  4100.             sendRepl(req);
  4101.             return retVal;
  4102.         }
  4103.     }
  4104.     else if (cfig.dhcpLogLevel == 2 && req->resp_type == DHCP_MESS_OFFER)
  4105.     {
  4106.         sprintf(logBuff, "Client %s (%s) offered %s", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname, IP2String(tempbuff, req->dhcpp.header.bp_yiaddr));
  4107.         logMess(logBuff, 2);
  4108.     }
  4109.     //printf("%u=out\n", req->resp_type);
  4110.     return 0;
  4111. }
  4112.  
  4113. void addOptions(data9 *req)
  4114. {
  4115.     if (!req->messsize && req->req_type == DHCP_MESS_NONE)
  4116.         req->messsize = req->bytes;
  4117.     else if (!req->messsize)
  4118.         req->messsize = sizeof(dhcp_packet);
  4119.  
  4120.     data3 op;
  4121.     int i;
  4122.  
  4123.     if (req->req_type && req->resp_type)
  4124.     {
  4125.         op.opt_code = DHCP_OPTION_MESSAGETYPE;
  4126.         op.size = 1;
  4127.         op.value[0] = req->resp_type;
  4128.         pvdata(req, &op);
  4129.     }
  4130.  
  4131.     if (req->dhcpEntry && req->resp_type != DHCP_MESS_DECLINE && req->resp_type != DHCP_MESS_NAK)
  4132.     {
  4133.         strcpy(req->dhcpp.header.bp_sname, cfig.servername);
  4134.  
  4135.         if (req->dhcpEntry->fixed)
  4136.         {
  4137.             //printf("%u,%u\n", req->dhcpEntry->options, *req->dhcpEntry->options);
  4138.             BYTE *opPointer = req->dhcpEntry->options;
  4139.  
  4140.             if (opPointer)
  4141.             {
  4142.                 BYTE requestedOnly = *opPointer;
  4143.                 opPointer++;
  4144.  
  4145.                 while (*opPointer && *opPointer < UCHAR_MAX)
  4146.                 {
  4147.                     op.opt_code = *opPointer;
  4148.                     opPointer++;
  4149.                     op.size = *opPointer;
  4150.                     opPointer++;
  4151.  
  4152.                     if (!requestedOnly || req->paramreqlist[*opPointer])
  4153.                     {
  4154.                         memcpy(op.value, opPointer, op.size);
  4155.                         pvdata(req, &op);
  4156.                     }
  4157.                     opPointer += op.size;
  4158.                 }
  4159.             }
  4160.         }
  4161.  
  4162.         if (req->req_type && req->resp_type)
  4163.         {
  4164.             if (req->dhcpEntry->rangeInd >= 0)
  4165.             {
  4166.                 BYTE *opPointer = cfig.dhcpRanges[req->dhcpEntry->rangeInd].options;
  4167.                 //printf("Range=%i Pointer=%u\n", req->dhcpEntry->rangeInd,opPointer);
  4168.  
  4169.                 if (opPointer)
  4170.                 {
  4171.                     BYTE requestedOnly = *opPointer;
  4172.                     opPointer++;
  4173.  
  4174.                     while (*opPointer && *opPointer < UCHAR_MAX)
  4175.                     {
  4176.                         op.opt_code = *opPointer;
  4177.                         opPointer++;
  4178.                         op.size = *opPointer;
  4179.                         opPointer++;
  4180.  
  4181.                         if (!requestedOnly || req->paramreqlist[*opPointer])
  4182.                         {
  4183.                             memcpy(op.value, opPointer, op.size);
  4184.                             pvdata(req, &op);
  4185.                         }
  4186.                         opPointer += op.size;
  4187.                     }
  4188.                 }
  4189.             }
  4190.  
  4191.             BYTE *opPointer = cfig.options;
  4192.  
  4193.             if (opPointer)
  4194.             {
  4195.                 BYTE requestedOnly = *opPointer;
  4196.  
  4197.                 opPointer++;
  4198.                 while (*opPointer && *opPointer < UCHAR_MAX)
  4199.                 {
  4200.                     op.opt_code = *opPointer;
  4201.                     opPointer++;
  4202.                     op.size = *opPointer;
  4203.                     opPointer++;
  4204.  
  4205.                     if (!requestedOnly || req->paramreqlist[*opPointer])
  4206.                     {
  4207.                         memcpy(op.value, opPointer, op.size);
  4208.                         pvdata(req, &op);
  4209.                     }
  4210.                     opPointer += op.size;
  4211.                 }
  4212.             }
  4213.  
  4214.             op.opt_code = DHCP_OPTION_SERVERID;
  4215.             op.size = 4;
  4216.             pIP(op.value, network.dhcpConn[req->sockInd].server);
  4217.             pvdata(req, &op);
  4218.  
  4219.             op.opt_code = DHCP_OPTION_DOMAINNAME;
  4220.             op.size = strlen(cfig.zone);
  4221.             memcpy(op.value, cfig.zone, op.size);
  4222.             pvdata(req, &op);
  4223.  
  4224.             if (!req->opAdded[DHCP_OPTION_IPADDRLEASE])
  4225.             {
  4226.                 op.opt_code = DHCP_OPTION_IPADDRLEASE;
  4227.                 op.size = 4;
  4228.                 pULong(op.value, cfig.lease);
  4229.                 pvdata(req, &op);
  4230.             }
  4231.  
  4232.             if (!req->opAdded[DHCP_OPTION_NETMASK])
  4233.             {
  4234.                 op.opt_code = DHCP_OPTION_NETMASK;
  4235.                 op.size = 4;
  4236.  
  4237.                 if (req->dhcpEntry->rangeInd >= 0)
  4238.                     pIP(op.value, cfig.dhcpRanges[req->dhcpEntry->rangeInd].mask);
  4239.                 else
  4240.                     pIP(op.value, network.dhcpConn[req->sockInd].mask);
  4241.  
  4242.                 pvdata(req, &op);
  4243.             }
  4244.  
  4245. /*
  4246.             if (!req->opAdded[DHCP_OPTION_ROUTER])
  4247.             {
  4248.                 op.opt_code = DHCP_OPTION_ROUTER;
  4249.                 op.size = 4;
  4250.                 pIP(op.value, network.dhcpConn[req->sockInd].server);
  4251.                 pvdata(req, &op);
  4252.             }
  4253. */
  4254.             if (!req->opAdded[DHCP_OPTION_DNS])
  4255.             {
  4256.                 if (dnsService)
  4257.                 {
  4258.                     op.opt_code = DHCP_OPTION_DNS;
  4259.                     if (cfig.replication == 1)
  4260.                     {
  4261.                         op.size = 8;
  4262.                         pIP(op.value, network.dhcpConn[req->sockInd].server);
  4263.                         pIP(op.value + 4, cfig.zoneServers[1]);
  4264.                         pvdata(req, &op);
  4265.                     }
  4266.                     else if (cfig.replication == 2)
  4267.                     {
  4268.                         op.size = 8;
  4269.                         pIP(op.value, network.dhcpConn[req->sockInd].server);
  4270.                         pIP(op.value + 4, cfig.zoneServers[0]);
  4271.                         pvdata(req, &op);
  4272.                     }
  4273.                     else
  4274.                     {
  4275.                         op.size = 4;
  4276.                         pIP(op.value, network.dhcpConn[req->sockInd].server);
  4277.                         pvdata(req, &op);
  4278.                     }
  4279.                 }
  4280.                 else
  4281.                 {
  4282.                     for (i = 0; i < MAX_SERVERS; i++)
  4283.                         if (!network.dns[i])
  4284.                             break;
  4285.  
  4286.                     if (i > 0)
  4287.                     {
  4288.                         op.opt_code = DHCP_OPTION_DNS;
  4289.                         op.size = i * 4;
  4290.                         memcpy(op.value, network.dns, op.size);
  4291.                         pvdata(req, &op);
  4292.                     }
  4293.                 }
  4294.             }
  4295. /*
  4296.             if (!req->opAdded[DHCP_OPTION_HOSTNAME])
  4297.             {
  4298.                 op.opt_code = DHCP_OPTION_HOSTNAME;
  4299.                 op.size = strlen(req->hostname);
  4300.                 memcpy(op.value, req->hostname, op.size);
  4301.                 pvdata(req, &op);
  4302.             }
  4303.  
  4304.             if (req->clientId.opt_code == DHCP_OPTION_CLIENTID)
  4305.                 pvdata(req, &req->clientId);
  4306. */
  4307.             if (req->agentOption.opt_code == DHCP_OPTION_RELAYAGENTINFO)
  4308.                 pvdata(req, &req->agentOption);
  4309.         }
  4310.     }
  4311.  
  4312.     *(req->vp) = DHCP_OPTION_END;
  4313. }
  4314.  
  4315. void pvdata(data9 *req, data3 *op)
  4316. {
  4317.     if (!req->opAdded[op->opt_code] && (((DWORD)req->vp - (DWORD)&req->dhcpp) + op->size < req->messsize))
  4318.     {
  4319.         if (op->opt_code == DHCP_OPTION_BOOTFILE)
  4320.             memcpy(req->dhcpp.header.bp_file, op->value, op->size);
  4321.         else if (op->opt_code == DHCP_OPTION_NEXTSERVER)
  4322.             req->dhcpp.header.bp_siaddr = fIP(op->value);
  4323.         else if(op->size)
  4324.         {
  4325.             if (op->opt_code == DHCP_OPTION_IPADDRLEASE)
  4326.             {
  4327.                 if (!req->lease || req->lease > fULong(op->value))
  4328.                     req->lease = fULong(op->value);
  4329.  
  4330.                 if (req->dhcpEntry->no_route || req->lease >= LONG_MAX)
  4331.                     req->lease = ULONG_MAX;
  4332.  
  4333.                 pULong(op->value, req->lease);
  4334.             }
  4335.             else if (op->opt_code == DHCP_OPTION_HOSTNAME)
  4336.             {
  4337.                 memcpy(req->hostname, op->value, op->size);
  4338.                 req->hostname[op->size] = 0;
  4339.             }
  4340.  
  4341.             memcpy(req->vp, op, (op->size + 2));
  4342.             (req->vp) += 2;
  4343.             (req->vp) += op->size;
  4344.         }
  4345.         req->opAdded[op->opt_code] = true;
  4346.     }
  4347. }
  4348.  
  4349. DWORD updateDHCP(data9 *req)
  4350. {
  4351.     time_t t = time(NULL);
  4352.     data8 *dhcpData = (data8*)calloc(1, sizeof(data8));
  4353.     strcpy(dhcpData->hostname, req->hostname);
  4354.     memcpy(dhcpData->bp_chaddr, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen);
  4355.     dhcpData->bp_hlen = req->dhcpp.header.bp_hlen;
  4356.     dhcpData->ip = req->dhcpEntry->ip;
  4357.  
  4358.     if (!req->dhcpEntry->fixed)
  4359.         dhcpData->source = req->dhcpEntry->source;
  4360.  
  4361.     if (!req->req_type)
  4362.     {
  4363.         dhcpData->expiry = LONG_MAX;
  4364.         setLeaseExpiry(req->dhcpEntry, LONG_MAX, req->req_type == DHCP_MESS_REQUEST);
  4365.     }
  4366.     else if (req->lease > (DWORD)(LONG_MAX - t))
  4367.     {
  4368.         dhcpData->expiry = LONG_MAX;
  4369.         setLeaseExpiry(req->dhcpEntry, LONG_MAX, req->req_type == DHCP_MESS_REQUEST);
  4370.     }
  4371.     else if (req->lease)
  4372.     {
  4373.         dhcpData->expiry = t + req->lease;
  4374.         setLeaseExpiry(req->dhcpEntry, req->lease, req->req_type == DHCP_MESS_REQUEST);
  4375.     }
  4376.     else
  4377.     {
  4378.         dhcpData->expiry = 0;
  4379.         req->dhcpEntry->expiry = 0;
  4380.     }
  4381.  
  4382.     addToCache(cacheInd, req->hostname, req->dhcpEntry->ip, dhcpData->expiry, LOCAL_A, NONE, cfig.serial1);
  4383.  
  4384.     if (makeLocal(req->dhcpEntry->ip))
  4385.         addToCache(cacheInd, req->hostname, req->dhcpEntry->ip, dhcpData->expiry, NONE, LOCAL_PTR_AUTH, cfig.serial2);
  4386.     else
  4387.         addToCache(cacheInd, req->hostname, req->dhcpEntry->ip, dhcpData->expiry, NONE, LOCAL_PTR_NAUTH, cfig.serial2);
  4388.  
  4389.     if (req->dhcpEntry->dhcpInd)
  4390.         dhcpData->dhcpInd = req->dhcpEntry->dhcpInd;
  4391.     else
  4392.     {
  4393.         cfig.dhcpIndex++;
  4394.         req->dhcpEntry->dhcpInd = cfig.dhcpIndex;
  4395.     }
  4396.  
  4397.     dhcpData->local = req->dhcpEntry->local;
  4398.  
  4399.     if (!(_beginthread(updateStateFile, 0, (void*)dhcpData) > 0))
  4400.     {
  4401.         free(dhcpData);
  4402.     }
  4403.  
  4404.     return req->dhcpEntry->ip;
  4405. }
  4406.  
  4407. void setLeaseExpiry(data7 *dhcpEntry, time_t expiry, bool active)
  4408. {
  4409.     //printf("%u\n", active);
  4410.  
  4411.     time_t t = time(NULL);
  4412.  
  4413.     if (dhcpService && dhcpEntry && dhcpEntry->ip)
  4414.     {
  4415.         if (LONG_MAX - t < expiry)
  4416.             dhcpEntry->expiry = LONG_MAX;
  4417.         else
  4418.             dhcpEntry->expiry = t + expiry;
  4419.  
  4420.         if (active && !dhcpEntry->local)
  4421.         {
  4422.             dhcpAge.insert(pair<long, data7*>(dhcpEntry->expiry, dhcpEntry));
  4423.             dhcpEntry->local = 1;
  4424.         }
  4425.  
  4426.         if (dhcpEntry->rangeInd >= 0 && dhcpEntry->rangeInd < MAX_RANGES)
  4427.         {
  4428.             DWORD iip = htonl(dhcpEntry->ip);
  4429.  
  4430.             if (iip >= cfig.dhcpRanges[dhcpEntry->rangeInd].rangeStart && iip <= cfig.dhcpRanges[dhcpEntry->rangeInd].rangeEnd)
  4431.             {
  4432.                 int ind = iip - cfig.dhcpRanges[dhcpEntry->rangeInd].rangeStart;
  4433.  
  4434.                 if (cfig.dhcpRanges[dhcpEntry->rangeInd].expiry[ind] != LONG_MAX)
  4435.                     cfig.dhcpRanges[dhcpEntry->rangeInd].expiry[ind] = dhcpEntry->expiry;
  4436.  
  4437.                 cfig.dhcpRanges[dhcpEntry->rangeInd].dhcpEntry[ind] = dhcpEntry;
  4438.             }
  4439.         }
  4440.     }
  4441. }
  4442.  
  4443. void setLeaseExpiry(DWORD ip, time_t expiry)
  4444. {
  4445.     time_t t = time(NULL);
  4446.  
  4447.     if (dhcpService && ip)
  4448.     {
  4449.         DWORD iip = htonl(ip);
  4450.  
  4451.         for (char rangeInd = 0; rangeInd < MAX_RANGES && cfig.dhcpRanges[rangeInd].rangeStart; rangeInd++)
  4452.         {
  4453.             if (iip >= cfig.dhcpRanges[rangeInd].rangeStart && iip <= cfig.dhcpRanges[rangeInd].rangeEnd)
  4454.             {
  4455.                 int ind = iip - cfig.dhcpRanges[rangeInd].rangeStart;
  4456.  
  4457.                 if (cfig.dhcpRanges[rangeInd].expiry[ind] != LONG_MAX)
  4458.                 {
  4459.                     if (LONG_MAX - t < expiry)
  4460.                         cfig.dhcpRanges[rangeInd].expiry[ind] = LONG_MAX;
  4461.                     else
  4462.                         cfig.dhcpRanges[rangeInd].expiry[ind] = t + expiry;
  4463.                 }
  4464.  
  4465.                 break;
  4466.             }
  4467.         }
  4468.     }
  4469. }
  4470.  
  4471. DWORD sendRepl(data9 *req)
  4472. {
  4473.     data3 op;
  4474.  
  4475.     if (cfig.replication == 1) {
  4476.         req->target.sin_addr.s_addr = cfig.zoneServers[1];
  4477.     } else if (cfig.replication == 2) {
  4478.         req->target.sin_addr.s_addr = cfig.zoneServers[0];
  4479.     } else {
  4480.         return 0;
  4481.     }
  4482.  
  4483.     req->target.sin_port = htons(IPPORT_DHCPS);
  4484.     req->target.sin_family = AF_INET;
  4485.  
  4486.     BYTE *opPointer = req->dhcpp.vend_data;
  4487.  
  4488.     while ((*opPointer) < UCHAR_MAX && opPointer < req->vp)
  4489.     {
  4490.         if ((*opPointer) == DHCP_OPTION_MESSAGETYPE)
  4491.         {
  4492.             *(opPointer + 2) = DHCP_MESS_INFORM;
  4493.             break;
  4494.         }
  4495.         opPointer = opPointer + *(opPointer + 1) + 2;
  4496.     }
  4497.  
  4498.     if (opPointer >= req->vp)
  4499.     {
  4500.         op.opt_code = DHCP_OPTION_MESSAGETYPE;
  4501.         op.size = 1;
  4502.         op.value[0] = DHCP_MESS_INFORM;
  4503.         memcpy(req->vp, &op, (op.size + 2));
  4504.         (req->vp) += 2;
  4505.         (req->vp) += op.size;
  4506.     }
  4507.  
  4508.     op.opt_code = DHCP_OPTION_SERIAL;
  4509.     op.size = 4;
  4510.     pULong(op.value, cfig.serial1);
  4511.     memcpy(req->vp, &op, (op.size + 2));
  4512.     (req->vp) += 2;
  4513.     (req->vp) += op.size;
  4514.  
  4515.     //printf("Here1 %u\n",req->vp);
  4516.  
  4517.     *(req->vp) = 255;
  4518.     req->bytes = (DWORD)req->vp - (DWORD)req->raw;
  4519.     req->bytes++;
  4520.  
  4521.     //printf("Here2\n");
  4522.  
  4523.     req->dhcpp.header.bp_op = BOOTP_REQUEST;
  4524.     errno = 0;
  4525.  
  4526.     //printf("%i\n", req->bytes);
  4527.  
  4528.     req->bytes = sendto(network.dhcpReplConn.sock,
  4529.                         req->raw,
  4530.                         req->bytes,
  4531.                         0,
  4532.                         (sockaddr*)&req->target,
  4533.                         sizeof(req->target));
  4534.  
  4535.     //printf("Here3\n");
  4536.  
  4537.     errno = WSAGetLastError();
  4538.  
  4539.     if (errno || req->bytes <= 0)
  4540.     {
  4541.         if (cfig.dhcpLogLevel)
  4542.         {
  4543.             if (cfig.replication == 1)
  4544.                 sprintf(logBuff, "Error %u Sending DHCP Update to Secondary Server", errno);
  4545.             else
  4546.                 sprintf(logBuff, "Error %u Sending DHCP Update to Primary Server", errno);
  4547.  
  4548.             logDHCPMess(logBuff, 2);
  4549.         }
  4550.  
  4551.         return 0;
  4552.     }
  4553.     else if (cfig.dhcpLogLevel == 2)
  4554.     {
  4555.         if (cfig.replication == 1)
  4556.             sprintf(logBuff, "DHCP Update for host %s (%s) sent to Secondary Server", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), IP2String(tempbuff, req->dhcpEntry->ip));
  4557.         else
  4558.             sprintf(logBuff, "DHCP Update for host %s (%s) sent to Primary Server", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), IP2String(tempbuff, req->dhcpEntry->ip));
  4559.  
  4560.         logDHCPMess(logBuff, 2);
  4561.     }
  4562.  
  4563.     return req->dhcpp.header.bp_yiaddr;
  4564. }
  4565.  
  4566. DWORD sendRepl(data7 *dhcpEntry)
  4567. {
  4568.     data9 req;
  4569.     data3 op;
  4570.     req.vp = req.dhcpp.vend_data;
  4571.     req.messsize = sizeof(dhcp_packet);
  4572.     req.dhcpEntry = dhcpEntry;
  4573.  
  4574.     if (cfig.replication == 1)
  4575.         req.target.sin_addr.s_addr = cfig.zoneServers[1];
  4576.     else if (cfig.replication == 2)
  4577.         req.target.sin_addr.s_addr = cfig.zoneServers[0];
  4578.     else
  4579.         return 0;
  4580.  
  4581.     req.target.sin_port = htons(IPPORT_DHCPS);
  4582.     req.target.sin_family = AF_INET;
  4583.  
  4584.     req.dhcpp.header.bp_op = BOOTP_REQUEST;
  4585.     req.dhcpp.header.bp_xid = time(NULL);
  4586.     req.dhcpp.header.bp_ciaddr = dhcpEntry->ip;
  4587.     req.dhcpp.header.bp_yiaddr = dhcpEntry->ip;;
  4588.     req.dhcpp.header.bp_hlen = fromUUE(req.dhcpp.header.bp_chaddr, dhcpEntry->mapname);
  4589.     req.dhcpp.header.bp_magic_num[0] = 99;
  4590.     req.dhcpp.header.bp_magic_num[1] = 130;
  4591.     req.dhcpp.header.bp_magic_num[2] = 83;
  4592.     req.dhcpp.header.bp_magic_num[3] = 99;
  4593.  
  4594.     op.opt_code = DHCP_OPTION_MESSAGETYPE;
  4595.     op.size = 1;
  4596.     op.value[0] = DHCP_MESS_INFORM;
  4597.     memcpy(req.vp, &op, (op.size + 2));
  4598.     (req.vp) += 2;
  4599.     (req.vp) += op.size;
  4600.  
  4601.     op.opt_code = DHCP_OPTION_SERIAL;
  4602.     op.size = 4;
  4603.     pULong(op.value, cfig.serial1);
  4604.     memcpy(req.vp, &op, (op.size + 2));
  4605.     (req.vp) += 2;
  4606.     (req.vp) += op.size;
  4607.  
  4608.     op.opt_code = DHCP_OPTION_IPADDRLEASE;
  4609.     op.size = 4;
  4610.     pULong(op.value, 0);
  4611.     memcpy(req.vp, &op, (op.size + 2));
  4612.     (req.vp) += 2;
  4613.     (req.vp) += op.size;
  4614.  
  4615.     data7 *cache = findEntry(cacheInd, IP2String(tempbuff, htonl(dhcpEntry->ip)));
  4616.  
  4617.     if (cache)
  4618.     {
  4619.         op.opt_code = DHCP_OPTION_HOSTNAME;
  4620.         op.size = strlen(cache->hostname);
  4621.         memcpy(op.value, cache->hostname, op.size);
  4622.         memcpy(req.vp, &op, (op.size + 2));
  4623.         (req.vp) += 2;
  4624.         (req.vp) += op.size;
  4625.     }
  4626.  
  4627.     *(req.vp) = 255;
  4628.     req.bytes = (DWORD)req.vp - (DWORD)req.raw;
  4629.     req.bytes++;
  4630.  
  4631.     errno = 0;
  4632.  
  4633.     req.bytes = sendto(network.dhcpReplConn.sock,
  4634.                         req.raw,
  4635.                         req.bytes,
  4636.                         0,
  4637.                         (sockaddr*)&req.target,
  4638.                         sizeof(req.target));
  4639.  
  4640.     errno = WSAGetLastError();
  4641.  
  4642.     if (errno || req.bytes <= 0)
  4643.     {
  4644.         if (cfig.dhcpLogLevel)
  4645.         {
  4646.             if (cfig.replication == 1)
  4647.                 sprintf(logBuff, "Error %u Sending DHCP Update to Secondary Server", errno);
  4648.             else
  4649.                 sprintf(logBuff, "Error %u Sending DHCP Update to Primary Server", errno);
  4650.  
  4651.             logDHCPMess(logBuff, 2);
  4652.         }
  4653.  
  4654.         return 0;
  4655.     }
  4656.     else if (cfig.dhcpLogLevel == 2)
  4657.     {
  4658.         if (cfig.replication == 1)
  4659.             sprintf(logBuff, "DHCP Update for host %s (%s) sent to Secondary Server", hex2String(extbuff, req.dhcpp.header.bp_chaddr, req.dhcpp.header.bp_hlen, ':'), IP2String(tempbuff, req.dhcpEntry->ip));
  4660.         else
  4661.             sprintf(logBuff, "DHCP Update for host %s (%s) sent to Primary Server", hex2String(extbuff, req.dhcpp.header.bp_chaddr, req.dhcpp.header.bp_hlen, ':'), IP2String(tempbuff, req.dhcpEntry->ip));
  4662.  
  4663.         logDHCPMess(logBuff, 2);
  4664.     }
  4665.  
  4666.     return req.dhcpp.header.bp_yiaddr;
  4667. }
  4668.  
  4669. void recvRepl(data9 *req)
  4670. {
  4671.     time_t t = time(NULL);
  4672.  
  4673.     //printf("Here 2\n");
  4674.  
  4675.     DWORD ip = req->dhcpp.header.bp_yiaddr ? req->dhcpp.header.bp_yiaddr : req->dhcpp.header.bp_ciaddr;
  4676.  
  4677.     if (!cfig.replication || !ip || !req->lease)
  4678.         return;
  4679.     else if (cfig.replication == 1 && req->addr.sin_addr.s_addr != cfig.zoneServers[1])
  4680.         return;
  4681.     else if (cfig.replication == 2 && req->addr.sin_addr.s_addr != cfig.zoneServers[0])
  4682.         return;
  4683.  
  4684.     //printf("Here 3\n");
  4685.     char rInd = -1;
  4686.  
  4687.     if (dhcpService)
  4688.     {
  4689.         rInd = getRangeInd(ip);
  4690.         req->dhcpEntry = dhcpCache[toUUE(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen)];
  4691.  
  4692.         if (!req->dhcpEntry && rInd >= 0)
  4693.         {
  4694.             req->dhcpEntry = (data7*)calloc(1, sizeof(data7));
  4695.  
  4696.             if (!req->dhcpEntry)
  4697.             {
  4698.                 sprintf(logBuff, "Memory Allocation Error");
  4699.                 logDHCPMess(logBuff, 1);
  4700.                 return;
  4701.             }
  4702.  
  4703.             req->dhcpEntry->mapname = cloneString(toUUE(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen));
  4704.  
  4705.             if (!req->dhcpEntry->mapname)
  4706.             {
  4707.                 sprintf(logBuff, "Memory Allocation Error");
  4708.                 free(req->dhcpEntry);
  4709.                 logDHCPMess(logBuff, 1);
  4710.                 return;
  4711.             }
  4712.  
  4713.             //req->dhcpEntry->dataType = DHCP;
  4714.             dhcpCache[req->dhcpEntry->mapname] = req->dhcpEntry;
  4715.         }
  4716.     }
  4717.  
  4718.     if (dhcpService && req->dhcpEntry)
  4719.     {
  4720.         req->dhcpEntry->ip = ip;
  4721.         req->dhcpEntry->rangeInd = rInd;
  4722.         //printf("Here 4\n");
  4723.  
  4724.         if (updateDHCP(req))
  4725.         {
  4726.             cfig.serial1 = req->serial;
  4727.             cfig.serial2 = req->serial;
  4728.  
  4729.             if (cfig.replication == 2)
  4730.             {
  4731.                 if (cfig.expire > (DWORD)(LONG_MAX - t))
  4732.                     cfig.expireTime = LONG_MAX;
  4733.                 else
  4734.                     cfig.expireTime = t + cfig.expire;
  4735.             }
  4736.             else
  4737.                 cfig.expireTime = LONG_MAX;
  4738.         }
  4739.     }
  4740.     else
  4741.     {
  4742.         cfig.serial1 = req->serial;
  4743.         cfig.serial2 = req->serial;
  4744.  
  4745.         if (cfig.replication == 2)
  4746.         {
  4747.             if (cfig.expire > (DWORD)(LONG_MAX - t))
  4748.                 cfig.expireTime = LONG_MAX;
  4749.             else
  4750.                 cfig.expireTime = t + cfig.expire;
  4751.         }
  4752.         else
  4753.             cfig.expireTime = LONG_MAX;
  4754.  
  4755.         time_t expiry = 0;
  4756.  
  4757.         if (req->lease > (DWORD)(LONG_MAX - t))
  4758.             expiry = LONG_MAX;
  4759.         else
  4760.             expiry = t + req->lease;
  4761.  
  4762.         addToCache(cacheInd, req->hostname, ip, expiry, LOCAL_A, NONE, cfig.serial1);
  4763.  
  4764.         if (makeLocal(ip))
  4765.             addToCache(cacheInd, req->hostname, ip, expiry, NONE, LOCAL_PTR_AUTH, cfig.serial2);
  4766.         else
  4767.             addToCache(cacheInd, req->hostname, ip, expiry, NONE, LOCAL_PTR_NAUTH, cfig.serial2);
  4768.     }
  4769.  
  4770.     if (cfig.dhcpLogLevel == 2)
  4771.     {
  4772.         if (cfig.replication == 1)
  4773.             sprintf(logBuff, "DHCP Update received for %s (%s) from Secondary Server", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), IP2String(tempbuff, req->dhcpEntry->ip));
  4774.         else
  4775.             sprintf(logBuff, "DHCP Update received for %s (%s) from Primary Server", hex2String(extbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), IP2String(tempbuff, req->dhcpEntry->ip));
  4776.  
  4777.         logDHCPMess(logBuff, 2);
  4778.     }
  4779. }
  4780.  
  4781. char getRangeInd(DWORD ip)
  4782. {
  4783.     if (dhcpService && ip)
  4784.     {
  4785.         DWORD iip = htonl(ip);
  4786.         for (char k = 0; k < MAX_RANGES && cfig.dhcpRanges[k].rangeStart; k++)
  4787.             if (iip >= cfig.dhcpRanges[k].rangeStart && iip <= cfig.dhcpRanges[k].rangeEnd)
  4788.                 return k;
  4789.     }
  4790.     return -1;
  4791. }
  4792.  
  4793. int getIndex(char rangeInd, DWORD ip)
  4794. {
  4795.     if (dhcpService && ip && rangeInd >= 0 && rangeInd < MAX_RANGES)
  4796.     {
  4797.         DWORD iip = htonl(ip);
  4798.         if (iip >= cfig.dhcpRanges[rangeInd].rangeStart && iip <= cfig.dhcpRanges[rangeInd].rangeEnd)
  4799.             return (iip - cfig.dhcpRanges[rangeInd].rangeStart);
  4800.     }
  4801.     return -1;
  4802. }
  4803.  
  4804. void loadOptions(char *iniStr, char *sectionName, data20 *optionData)
  4805. {
  4806.     optionData->options = 0;
  4807.     optionData->ip = 0;
  4808.     optionData->mask = 0;
  4809.     BYTE maxInd = sizeof(opData) / sizeof(data4);
  4810.     BYTE options[sizeof(dhcp_packet) - sizeof(dhcp_header)];
  4811.     WORD buffsize = sizeof(options);
  4812.     BYTE *dp = options;
  4813.     *dp = 0;
  4814.     dp++;
  4815.  
  4816.     char *iniStrPtr = myGetToken(iniStr, 0);
  4817.  
  4818.     for (; iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  4819.     {
  4820.         char name[512];
  4821.         char value[512];
  4822.         BYTE hoption[256];
  4823.         BYTE valueSize = sizeof(hoption) - 1;
  4824.         BYTE opTag = 0;
  4825.         BYTE opType = 0;
  4826.         BYTE valType = 0;
  4827.         bool tagFound = false;
  4828.  
  4829.         mySplit(name, value, iniStrPtr, '=');
  4830.  
  4831.         if (!name[0])
  4832.         {
  4833.             sprintf(logBuff, "Warning: section [%s] invalid option %s ignored", sectionName, iniStrPtr);
  4834.             logMess(logBuff, 1);
  4835.             continue;
  4836.         }
  4837.  
  4838.         if (!strcasecmp(name, "DHCP_Range"))
  4839.         {
  4840.             if (!strcasecmp(sectionName, "DHCP-RANGE"))
  4841.             {
  4842.                 addDHCPRange(value);
  4843.             }
  4844.             else
  4845.             {
  4846.                 sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, iniStrPtr);
  4847.                 logMess(logBuff, 1);
  4848.             }
  4849.             continue;
  4850.         }
  4851.         else if (!strcasecmp(name, "IP_Addr"))
  4852.         {
  4853.             if (!strcasecmp(sectionName, "DHCP-OPTIONS") || !strcasecmp(sectionName, "DHCP-RANGE"))
  4854.             {
  4855.                 sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, iniStrPtr);
  4856.                 logMess(logBuff, 1);
  4857.             }
  4858.             else if (!isIP(value))
  4859.             {
  4860.                 sprintf(logBuff, "Warning: section [%s] option %s Invalid IP Addr %s option ignored", sectionName, value);
  4861.                 logMess(logBuff, 1);
  4862.             }
  4863.             else
  4864.                 optionData->ip = my_inet_addr(value);
  4865.  
  4866.             continue;
  4867.         }
  4868.         else if (!strcasecmp(name, "Subnet_Mask"))
  4869.         {
  4870.             if (!isIP(value) || !checkMask(my_inet_addr(value)))
  4871.             {
  4872.                 sprintf(logBuff, "Warning: section [%s] Invalid %s %s, option ignored", sectionName, name, value);
  4873.                 logMess(logBuff, 1);
  4874.                 continue;
  4875.             }
  4876.             else
  4877.                 optionData->mask = my_inet_addr(value);
  4878.         }
  4879.         else if (!strcasecmp(name, "Filter_Mac_Range"))
  4880.         {
  4881.             if (!strcasecmp(sectionName, "DHCP-RANGE"))
  4882.                 addMacRange(optionData->rangeSetInd, value);
  4883.             else
  4884.             {
  4885.                 sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, iniStrPtr);
  4886.                 logMess(logBuff, 1);
  4887.             }
  4888.             continue;
  4889.         }
  4890.         else if (!strcasecmp(name, "Filter_Vendor_Class"))
  4891.         {
  4892.             if (!strcasecmp(sectionName, "DHCP-RANGE"))
  4893.             {
  4894.                 valueSize = strlen(value);
  4895.                 addVendClass(optionData->rangeSetInd, value, valueSize);
  4896.             }
  4897.             else
  4898.             {
  4899.                 sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, iniStrPtr);
  4900.                 logMess(logBuff, 1);
  4901.             }
  4902.             continue;
  4903.         }
  4904.         else if (!strcasecmp(name, "Filter_User_Class"))
  4905.         {
  4906.             if (!strcasecmp(sectionName, "DHCP-RANGE"))
  4907.             {
  4908.                 valueSize = strlen(value);
  4909.                 addUserClass(optionData->rangeSetInd, value, valueSize);
  4910.             }
  4911.             else
  4912.             {
  4913.                 sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, iniStrPtr);
  4914.                 logMess(logBuff, 1);
  4915.             }
  4916.             continue;
  4917.         }
  4918.  
  4919.         if (!value[0])
  4920.             valType = 8;
  4921.         else if (value[0] == '"' && value[strlen(value)-1] == '"')
  4922.         {
  4923.             valType = 1;
  4924.             value[0] = 32;
  4925.             value[strlen(value)-1] = 32;
  4926.             myTrim(value, value);
  4927.  
  4928.             if (strlen(value) <= 255)
  4929.                 valueSize = strlen(value);
  4930.             else
  4931.             {
  4932.                 sprintf(logBuff, "Warning: section [%s] option %s value too big, option ignored", sectionName, iniStrPtr);
  4933.                 logMess(logBuff, 1);
  4934.                 continue;
  4935.             }
  4936.         }
  4937.         else if (strchr(value, ':'))
  4938.         {
  4939.             valType = 2;
  4940.             valueSize = sizeof(hoption) - 1;
  4941.             char *errorPos = getHexValue(hoption, value, &valueSize);
  4942.  
  4943.             if (errorPos)
  4944.             {
  4945.                 sprintf(logBuff, "Warning: section [%s] option %s position %u, Invalid char %c, option ignored", sectionName, name, ((DWORD)errorPos - (DWORD)value) + 1, *(errorPos));
  4946.                 logMess(logBuff, 1);
  4947.                 continue;
  4948.             }
  4949.             else
  4950.                 memcpy(value, hoption, valueSize);
  4951.         }
  4952.         else if (isInt(value) && atol(value) > USHRT_MAX)
  4953.             valType = 4;
  4954.         else if (isInt(value) && atoi(value) > UCHAR_MAX)
  4955.             valType = 5;
  4956.         else if (isInt(value))
  4957.             valType = 6;
  4958.         else
  4959.         {
  4960.             if (myTokenize(tempbuff, value, "/,", true) && isIP(tempbuff))
  4961.             {
  4962.                 char *ptr = tempbuff;
  4963.  
  4964.                 for (; *ptr; ptr = myGetToken(ptr, 1))
  4965.                 {
  4966.                     if (!isIP(ptr) || (!my_inet_addr(ptr) && strcasecmp(ptr, "255.255.255.255") && strcasecmp(ptr, "0.0.0.0")))
  4967.                         break;
  4968.                 }
  4969.  
  4970.                 if (*ptr)
  4971.                 {
  4972.                     sprintf(logBuff, "Warning: section [%s] option %s invalid IP %s, entry ignored", sectionName, iniStrPtr, ptr);
  4973.                     logMess(logBuff, 1);
  4974.                     continue;
  4975.                 }
  4976.                 valType = 3;
  4977.             }
  4978.             else
  4979.             {
  4980.                 if (strlen(value) <= 255)
  4981.                     valueSize = strlen(value);
  4982.                 else
  4983.                 {
  4984.                     sprintf(logBuff, "Warning: section [%s] option %s value too big, option ignored", sectionName, iniStrPtr);
  4985.                     logMess(logBuff, 1);
  4986.                     continue;
  4987.                 }
  4988.                 valType = 1;
  4989.             }
  4990.         }
  4991.  
  4992.         if (isInt(name))
  4993.         {
  4994.             opTag = atoi(name);
  4995.             opType = 0;
  4996.         }
  4997.  
  4998.         for (BYTE i = 0; i < maxInd; i++)
  4999.             if (!strcasecmp(name, opData[i].opName) || (opTag && opTag == opData[i].opTag))
  5000.             {
  5001.                 opTag = opData[i].opTag;
  5002.                 opType = opData[i].opType;
  5003.                 tagFound = true;
  5004.                 break;
  5005.             }
  5006.  
  5007.         if (!opTag)
  5008.         {
  5009.             sprintf(logBuff, "Warning: section [%s] invalid option %s, ignored", sectionName, iniStrPtr);
  5010.             logMess(logBuff, 1);
  5011.             continue;
  5012.         }
  5013.  
  5014.         //sprintf(logBuff, "Tag %i ValType %i opType %i value=%s", opTag, valType, opType, value);
  5015.         //logMess(logBuff, 1);
  5016.  
  5017.         if (valType == 8)
  5018.         {
  5019.             if (buffsize > 2)
  5020.             {
  5021.                 *dp = opTag;
  5022.                 dp++;
  5023.                 *dp = 0;
  5024.                 dp++;
  5025.                 buffsize -= 2;
  5026.             }
  5027.             else
  5028.             {
  5029.                 sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, iniStrPtr);
  5030.                 logMess(logBuff, 1);
  5031.             }
  5032.             continue;
  5033.         }
  5034.  
  5035.         switch (opType)
  5036.         {
  5037.             case 1:
  5038.             {
  5039.                 if (valType != 1 && valType != 2)
  5040.                 {
  5041.                     sprintf(logBuff, "Warning: section [%s] option %s, need string value, option ignored", sectionName, iniStrPtr);
  5042.                     logMess(logBuff, 1);
  5043.                 }
  5044.                 else if (opTag == DHCP_OPTION_DOMAINNAME)
  5045.                 {
  5046.                     sprintf(logBuff, "Warning: section [%s] option %u should be under [DOMAIN-NAME], ignored", sectionName, opTag);
  5047.                     logMess(logBuff, 1);
  5048.                     continue;
  5049.                 }
  5050.                 else if (buffsize > strlen(value) + 2)
  5051.                 {
  5052.                     *dp = opTag;
  5053.                     dp++;
  5054.                     *dp = strlen(value);
  5055.                     dp++;
  5056.                     memcpy(dp, value, valueSize);
  5057.                     dp += (strlen(value));
  5058.                     buffsize -= (valueSize + 2);
  5059.                 }
  5060.                 else
  5061.                 {
  5062.                     sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, iniStrPtr);
  5063.                     logMess(logBuff, 1);
  5064.                 }
  5065.             }
  5066.             break;
  5067.  
  5068.             case 3:
  5069.             {
  5070.                 if (valType == 2)
  5071.                 {
  5072.                     if (valueSize % 4)
  5073.                     {
  5074.                         sprintf(logBuff, "Warning: section [%s] option %s, hex value should be multiple of 4 hex bytes, option ignored", sectionName, iniStrPtr);
  5075.                         logMess(logBuff, 1);
  5076.                         continue;
  5077.                     }
  5078.  
  5079.                     if (buffsize > valueSize + 2)
  5080.                     {
  5081.                         *dp = opTag;
  5082.                         dp++;
  5083.                         *dp = valueSize;
  5084.                         dp++;
  5085.                         memcpy(dp, value, valueSize);
  5086.                         dp += valueSize;
  5087.                         buffsize -= (valueSize + 2);
  5088.                     }
  5089.                     else
  5090.                     {
  5091.                         sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, iniStrPtr);
  5092.                         logMess(logBuff, 1);
  5093.                     }
  5094.                 }
  5095.                 else
  5096.                 {
  5097.                     BYTE *lastOptionIndex = 0;
  5098.                     myTokenize(tempbuff, value, "/,", true);
  5099.                     char *ptr = tempbuff;
  5100.  
  5101.                     for (; *ptr; ptr = myGetToken(ptr, 1))
  5102.                     {
  5103.                         DWORD j = my_inet_addr(ptr);
  5104.  
  5105.                         if (buffsize > 6)
  5106.                         {
  5107.                             if (lastOptionIndex)
  5108.                                 *(lastOptionIndex + 1) += 4;
  5109.                             else
  5110.                             {
  5111.                                 lastOptionIndex = dp;
  5112.                                 *dp = opTag;
  5113.                                 dp++;
  5114.                                 *dp = 4;
  5115.                                 dp++;
  5116.                                 buffsize -= 2;
  5117.                             }
  5118.                             dp += pIP(dp, j);
  5119.                             buffsize -= 4;
  5120.                         }
  5121.                         else
  5122.                         {
  5123.                             sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, iniStrPtr);
  5124.                             logMess(logBuff, 1);
  5125.                         }
  5126.                     }
  5127.                 }
  5128.             }
  5129.             break;
  5130.  
  5131.             case 4:
  5132.             {
  5133.                 DWORD j;
  5134.  
  5135.                 if (valType == 2 && valueSize == 4)
  5136.                     j = fULong(value);
  5137.                 else if (valType >= 4 && valType <= 6)
  5138.                     j = atol(value);
  5139.                 else
  5140.                 {
  5141.                     sprintf(logBuff, "Warning: section [%s] option %s, value should be between 0 & %u, option ignored", sectionName, iniStrPtr, ULONG_MAX);
  5142.                     logMess(logBuff, 1);
  5143.                     continue;
  5144.                 }
  5145.  
  5146.                 if (opTag == DHCP_OPTION_IPADDRLEASE)
  5147.                 {
  5148.                     if (!strcasecmp(sectionName, "DHCP-OPTIONS"))
  5149.                     {
  5150.                         sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, please set it in [TIMINGS] section", sectionName, iniStrPtr);
  5151.                         logDHCPMess(logBuff, 1);
  5152.                         continue;
  5153.                     }
  5154.  
  5155.                     if (j == 0)
  5156.                         j = ULONG_MAX;
  5157.  
  5158.                     if (j > cfig.lease)
  5159.                     {
  5160.                         sprintf(logBuff, "Warning: section [%s] option %s value should be less then %u, ignored", sectionName, name, cfig.lease);
  5161.                         logDHCPMess(logBuff, 1);
  5162.                         continue;
  5163.                     }
  5164.                 }
  5165.  
  5166.                 if (buffsize > 6)
  5167.                 {
  5168.                     *dp = opTag;
  5169.                     dp++;
  5170.                     *dp = 4;
  5171.                     dp++;
  5172.                     dp += pULong(dp, j);
  5173.                     buffsize -= 6;
  5174.                     //printf("%s=%u=%u\n",opData[op_index].opName,opData[op_index].opType,htonl(j));
  5175.                 }
  5176.                 else
  5177.                 {
  5178.                     sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, iniStrPtr);
  5179.                     logMess(logBuff, 1);
  5180.                 }
  5181.             }
  5182.             break;
  5183.  
  5184.             case 5:
  5185.             {
  5186.                 WORD j;
  5187.  
  5188.                 if (valType == 2 && valueSize == 2)
  5189.                     j = fUShort(value);
  5190.                 else if (valType == 5 || valType == 6)
  5191.                     j = atol(value);
  5192.                 else
  5193.                 {
  5194.                     sprintf(logBuff, "Warning: section [%s] option %s, value should be between 0 & %u, option ignored", sectionName, iniStrPtr, USHRT_MAX);
  5195.                     logMess(logBuff, 1);
  5196.                     continue;
  5197.                 }
  5198.  
  5199.                 if (buffsize > 4)
  5200.                 {
  5201.                     *dp = opTag;
  5202.                     dp++;
  5203.                     *dp = 2;
  5204.                     dp++;
  5205.                     dp += pUShort(dp, j);
  5206.                     buffsize -= 4;
  5207.                 }
  5208.                 else
  5209.                 {
  5210.                     sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, iniStrPtr);
  5211.                     logMess(logBuff, 1);
  5212.                 }
  5213.             }
  5214.             break;
  5215.  
  5216.             case 6:
  5217.             {
  5218.                 BYTE j;
  5219.  
  5220.                 if (valType == 2 && valueSize == 1)
  5221.                     j = *value;
  5222.                 else if (valType == 6)
  5223.                     j = atol(value);
  5224.                 else
  5225.                 {
  5226.                     sprintf(logBuff, "Warning: section [%s] option %s, value should be between 0 & %u, option ignored", sectionName, iniStrPtr, UCHAR_MAX);
  5227.                     logMess(logBuff, 1);
  5228.                     continue;
  5229.                 }
  5230.  
  5231.                 if (buffsize > 3)
  5232.                 {
  5233.                     *dp = opTag;
  5234.                     dp++;
  5235.                     *dp = 1;
  5236.                     dp++;
  5237.                     *dp = j;
  5238.                     dp++;
  5239.                     buffsize -= 3;
  5240.                 }
  5241.                 else
  5242.                 {
  5243.                     sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, iniStrPtr);
  5244.                     logMess(logBuff, 1);
  5245.                 }
  5246.             }
  5247.             break;
  5248.  
  5249.             case 7:
  5250.             {
  5251.                 BYTE j;
  5252.  
  5253.                 if (valType == 2 && valueSize == 1 && *value < 2)
  5254.                     j = *value;
  5255.                 else if (valType == 1 && !strcasecmp(value, "yes"))
  5256.                     j = 1;
  5257.                 else if (valType == 1 && !strcasecmp(value, "no"))
  5258.                     j = 0;
  5259.                 else
  5260.                 {
  5261.                     sprintf(logBuff, "Warning: section [%s] option %s, value should be yes or no, option ignored", sectionName, iniStrPtr);
  5262.                     logMess(logBuff, 1);
  5263.                     continue;
  5264.                 }
  5265.  
  5266.                 if (buffsize > 3)
  5267.                 {
  5268.                     *dp = opTag;
  5269.                     dp++;
  5270.                     *dp = 1;
  5271.                     dp++;
  5272.                     *dp = j;
  5273.                     dp++;
  5274.                     buffsize -= 3;
  5275.                 }
  5276.                 else
  5277.                 {
  5278.                     sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, iniStrPtr);
  5279.                     logMess(logBuff, 1);
  5280.                 }
  5281.             }
  5282.             break;
  5283.  
  5284.             default:
  5285.             {
  5286.                 if (opType == 2 && valType != 2)
  5287.                 {
  5288.                     sprintf(logBuff, "Warning: section [%s] option %s, value should be hex string, option ignored", sectionName, iniStrPtr);
  5289.                     logMess(logBuff, 1);
  5290.                     continue;
  5291.                 }
  5292.  
  5293.                 if (buffsize > valueSize + 2)
  5294.                 {
  5295.                     *dp = opTag;
  5296.                     dp++;
  5297.                     *dp = valueSize;
  5298.                     dp++;
  5299.                     memcpy(dp, value, valueSize);
  5300.                     dp += valueSize;
  5301.                     buffsize -= (valueSize + 2);
  5302.                 }
  5303.                 else
  5304.                 {
  5305.                     sprintf(logBuff, "Warning: section [%s] option %s, no more space for options", sectionName, iniStrPtr);
  5306.                     logMess(logBuff, 1);
  5307.                 }
  5308.             }
  5309.             break;
  5310.         }
  5311.  
  5312.         //printf("%s\n", iniStrPtr);
  5313.         //printf("%u %s\n", ddp, hex2String(tempbuff, ddp, (*(ddp+1))+2, ':'));
  5314.     }
  5315.  
  5316.     //printf("%s=%s\n", sectionName, optionData->vendClass);
  5317.  
  5318.     *dp = DHCP_OPTION_END;
  5319.     dp++;
  5320.     WORD optionSize = ((DWORD)dp - (DWORD)options);
  5321.  
  5322.     if (optionSize > 2)
  5323.     {
  5324.         optionData->options = (BYTE*)calloc(1, optionSize);
  5325.  
  5326.         if (!optionData->options)
  5327.         {
  5328.             sprintf(logBuff, "DHCP Option Load, Memory Allocation Error");
  5329.             logMess(logBuff, 1);
  5330.         }
  5331.  
  5332.         memcpy(optionData->options, options, optionSize);
  5333.     }
  5334. }
  5335.  
  5336. void lockOptions(char *iniStr)
  5337. {
  5338.     char name[512];
  5339.     char value[512];
  5340.     char *iniStrPtr = myGetToken(iniStr, 0);
  5341.  
  5342.     for (; iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  5343.     {
  5344.         mySplit(name, value, iniStrPtr, '=');
  5345.  
  5346.         if (!name[0])
  5347.             continue;
  5348.  
  5349.         int op_index;
  5350.         BYTE n = sizeof(opData) / sizeof(data4);
  5351.  
  5352.         for (op_index = 0; op_index < n; op_index++)
  5353.             if (!strcasecmp(name, opData[op_index].opName) || (opData[op_index].opTag && atoi(name) == opData[op_index].opTag))
  5354.                 break;
  5355.  
  5356.         if (op_index >= n)
  5357.             continue;
  5358.  
  5359.         if (opData[op_index].opType == 0)
  5360.         {
  5361.             //printf("Tag %s Locked\n", value);
  5362.  
  5363.             DWORD inetAddr = my_inet_addr(value);
  5364.  
  5365.             if (inetAddr != INADDR_ANY && inetAddr != INADDR_NONE)
  5366.                 setLeaseExpiry(inetAddr, LONG_MAX);
  5367.         }
  5368.     }
  5369. }
  5370.  
  5371. char* myGetToken(char* buff, BYTE index)
  5372. {
  5373.     while (*buff)
  5374.     {
  5375.         if (index)
  5376.             index--;
  5377.         else
  5378.             break;    
  5379.  
  5380.         buff += strlen(buff) + 1;
  5381.     }
  5382.  
  5383.     return buff;
  5384. }
  5385.  
  5386. WORD myTokenize(char *target, char *source, char *sep, bool whiteSep)
  5387. {
  5388.     bool found = true;
  5389.     char *dp = target;
  5390.     WORD kount = 0;
  5391.  
  5392.     while (*source)
  5393.     {
  5394.         if (sep && sep[0] && strchr(sep, (*source)))
  5395.         {
  5396.             found = true;
  5397.             source++;
  5398.             continue;
  5399.         }
  5400.         else if (whiteSep && *source <= 32)
  5401.         {
  5402.             found = true;
  5403.             source++;
  5404.             continue;
  5405.         }
  5406.  
  5407.         if (found)
  5408.         {
  5409.             if (target != dp)
  5410.             {
  5411.                 *dp = 0;
  5412.                 dp++;
  5413.             }
  5414.             kount++;
  5415.         }
  5416.  
  5417.         found = false;
  5418.         *dp = *source;
  5419.         dp++;
  5420.         source++;
  5421.     }
  5422.  
  5423.     *dp = 0;
  5424.     dp++;
  5425.     *dp = 0;
  5426.  
  5427.     //printf("%s\n", target);
  5428.  
  5429.     return kount;
  5430. }
  5431.  
  5432. char* myTrim(char *target, char *source)
  5433. {
  5434.     while ((*source) && (*source) <= 32)
  5435.         source++;
  5436.  
  5437.     int i = 0;
  5438.  
  5439.     for (; i < 511 && source[i]; i++)
  5440.         target[i] = source[i];
  5441.  
  5442.     target[i] = source[i];
  5443.     i--;
  5444.  
  5445.     for (; i >= 0 && target[i] <= 32; i--)
  5446.         target[i] = 0;
  5447.  
  5448.     return target;
  5449. }
  5450.  
  5451. void mySplit(char *name, char *value, char *source, char splitChar)
  5452. {
  5453.     int i = 0;
  5454.     int j = 0;
  5455.     int k = 0;
  5456.  
  5457.     for (; source[i] && j <= 510 && source[i] != splitChar; i++, j++)
  5458.     {
  5459.         name[j] = source[i];
  5460.     }
  5461.  
  5462.     if (source[i])
  5463.     {
  5464.         i++;
  5465.         for (; k <= 510 && source[i]; i++, k++)
  5466.         {
  5467.             value[k] = source[i];
  5468.         }
  5469.     }
  5470.  
  5471.     name[j] = 0;
  5472.     value[k] = 0;
  5473.  
  5474.     myTrim(name, name);
  5475.     myTrim(value, value);
  5476.     //printf("%s %s\n", name, value);
  5477. }
  5478.  
  5479.  
  5480. char *strqtype(char *buff, BYTE qtype)
  5481. {
  5482.     switch (qtype)
  5483.     {
  5484.         case 1:
  5485.             strcpy(buff, "A");
  5486.             break;
  5487.         case 2:
  5488.             strcpy(buff, "NS");
  5489.             break;
  5490.         case 3:
  5491.             strcpy(buff, "MD");
  5492.             break;
  5493.         case 4:
  5494.             strcpy(buff, "MF");
  5495.             break;
  5496.         case 5:
  5497.             strcpy(buff, "CNAME");
  5498.             break;
  5499.         case 6:
  5500.             strcpy(buff, "SOA");
  5501.             break;
  5502.         case 7:
  5503.             strcpy(buff, "MB");
  5504.             break;
  5505.         case 8:
  5506.             strcpy(buff, "MG");
  5507.             break;
  5508.         case 9:
  5509.             strcpy(buff, "MR");
  5510.             break;
  5511.         case 10:
  5512.             strcpy(buff, "NULL");
  5513.             break;
  5514.         case 11:
  5515.             strcpy(buff, "WKS");
  5516.             break;
  5517.         case 12:
  5518.             strcpy(buff, "PTR");
  5519.             break;
  5520.         case 13:
  5521.             strcpy(buff, "HINFO");
  5522.             break;
  5523.         case 14:
  5524.             strcpy(buff, "MINFO");
  5525.             break;
  5526.         case 15:
  5527.             strcpy(buff, "MX");
  5528.             break;
  5529.         case 16:
  5530.             strcpy(buff, "TXT");
  5531.             break;
  5532.         case 28:
  5533.             strcpy(buff, "AAAA");
  5534.             break;
  5535.         case 251:
  5536.             strcpy(buff, "IXFR");
  5537.             break;
  5538.         case 252:
  5539.             strcpy(buff, "AXFR");
  5540.             break;
  5541.         case 253:
  5542.             strcpy(buff, "MAILB");
  5543.             break;
  5544.         case 254:
  5545.             strcpy(buff, "MAILA");
  5546.             break;
  5547.         default:
  5548.             strcpy(buff, "ANY");
  5549.             break;
  5550.     }
  5551.     return buff;
  5552. }
  5553.  
  5554. bool getSection(const char *sectionName, char *buffer, BYTE serial, char *fileName)
  5555. {
  5556.     //printf("%s=%s\n",fileName,sectionName);
  5557.     char section[128];
  5558.     sprintf(section, "[%s]", sectionName);
  5559.     myUpper(section);
  5560.     FILE *f = fopen(fileName, "rt");
  5561.     char buff[512];
  5562.     BYTE found = 0;
  5563.  
  5564.     if (f)
  5565.     {
  5566.         while (fgets(buff, 511, f))
  5567.         {
  5568.             myUpper(buff);
  5569.             myTrim(buff, buff);
  5570.  
  5571.             if (strstr(buff, section) == buff)
  5572.             {
  5573.                 found++;
  5574.                 if (found == serial)
  5575.                 {
  5576.                     //printf("%s=%s\n",fileName,sectionName);
  5577.                     while (fgets(buff, 511, f))
  5578.                     {
  5579.                         myTrim(buff, buff);
  5580.  
  5581.                         if (strstr(buff, "[") == buff)
  5582.                             break;
  5583.  
  5584.                         if ((*buff) >= '0' && (*buff) <= '9' || (*buff) >= 'A' && (*buff) <= 'Z' || (*buff) >= 'a' && (*buff) <= 'z' || ((*buff) && strchr("/\\?*", (*buff))))
  5585.                         {
  5586.                             buffer += sprintf(buffer, "%s", buff);
  5587.                             buffer++;
  5588.                         }
  5589.                     }
  5590.                     break;
  5591.                 }
  5592.             }
  5593.         }
  5594.         fclose(f);
  5595.     }
  5596.  
  5597.     *buffer = 0;
  5598.     *(buffer + 1) = 0;
  5599.     return (found == serial);
  5600. }
  5601.  
  5602. DWORD getClassNetwork(DWORD ip)
  5603. {
  5604.     data15 data;
  5605.     data.ip = ip;
  5606.     data.octate[3] = 0;
  5607.  
  5608.     if (data.octate[0] < 192)
  5609.         data.octate[2] = 0;
  5610.  
  5611.     if (data.octate[0] < 128)
  5612.         data.octate[1] = 0;
  5613.  
  5614.     return data.ip;
  5615. }
  5616.  
  5617. /*
  5618. char *IP2Auth(DWORD ip)
  5619. {
  5620. data15 data;
  5621. data.ip = ip;
  5622.  
  5623. if (data.octate[0] >= 192)
  5624. sprintf(tempbuff, "%u.%u.%u", data.octate[2], data.octate[1], data.octate[0]);
  5625. else if (data.octate[0] >= 128)
  5626. sprintf(tempbuff, "%u.%u", data.octate[1], data.octate[0]);
  5627. else
  5628. sprintf(tempbuff, "%u", data.octate[0]);
  5629.  
  5630. strcat(tempbuff, arpa);
  5631. return tempbuff;
  5632. }
  5633. */
  5634.  
  5635. char *IP2String(char *target, DWORD ip)
  5636. {
  5637.     data15 inaddr;
  5638.     inaddr.ip = ip;
  5639.     sprintf(target, "%u.%u.%u.%u", inaddr.octate[0], inaddr.octate[1], inaddr.octate[2], inaddr.octate[3]);
  5640.     //BYTE *octate = (BYTE*)&ip;
  5641.     //sprintf(target, "%u.%u.%u.%u", octate[0], octate[1], octate[2], octate[3]);
  5642.     return target;
  5643. }
  5644.  
  5645. bool addServer(DWORD *array, DWORD ip)
  5646. {
  5647.     for (BYTE i = 0; i < MAX_SERVERS; i++)
  5648.     {
  5649.         if (!ip || array[i] == ip)
  5650.             return 0;
  5651.         else if (!array[i])
  5652.         {
  5653.             array[i] = ip;
  5654.             return 1;
  5655.         }
  5656.     }
  5657.     return 0;
  5658. }
  5659.  
  5660. DWORD *findServer(DWORD *array, DWORD ip)
  5661. {
  5662.     if (ip)
  5663.     {
  5664.         for (BYTE i = 0; i < MAX_SERVERS && array[i]; i++)
  5665.         {
  5666.             if (array[i] == ip)
  5667.                 return &(array[i]);
  5668.         }
  5669.     }
  5670.     return 0;
  5671. }
  5672.  
  5673. bool isInt(char *string)
  5674. {
  5675.     if (!(*string))
  5676.         return false;
  5677.  
  5678.     for(; *string; string++)
  5679.         if (*string <  '0' || *string > '9')
  5680.             return false;
  5681.  
  5682.     return true;
  5683. }
  5684.  
  5685. bool isIP(char *string)
  5686. {
  5687.     int j = 0;
  5688.  
  5689.     for (; *string; string++)
  5690.     {
  5691.         if (*string == '.' && *(string + 1) != '.')
  5692.             j++;
  5693.         else if (*string < '0' || *string > '9')
  5694.             return 0;
  5695.     }
  5696.  
  5697.     if (j == 3)
  5698.         return 1;
  5699.     else
  5700.         return 0;
  5701. }
  5702.  
  5703. char *toBase64(BYTE *source, BYTE length)
  5704. {
  5705.     BYTE a = 0, b = 0, i = 0;
  5706.     char *dp = tempbuff;
  5707.  
  5708.     for (; length; length--, source++)
  5709.     {
  5710.         i += 2;
  5711.         a = (*source) >> i;
  5712.         *dp = base64[a + b];
  5713.         dp++;
  5714.         b = (*source) << (8 - i);
  5715.         b >>= 2;
  5716.         if (i == 6)
  5717.         {
  5718.             *dp = base64[b];
  5719.             dp++;
  5720.             i = b = 0;
  5721.         }
  5722.     }
  5723.     if (i)
  5724.     {
  5725.         *dp = base64[b];
  5726.         dp++;
  5727.     }
  5728.     *dp = 0;
  5729.     //printf("%s\n",tempbuff);
  5730.     return tempbuff;
  5731. }
  5732.  
  5733. BYTE getBaseValue(BYTE a)
  5734. {
  5735.     if (a >= 'A' && a <= 'Z')
  5736.         a -= 'A';
  5737.     else if (a >= 'a' && a <= 'z')
  5738.         a = a - 'a' + 26;
  5739.     else if (a >= '0' && a <= '9')
  5740.         a = a - '0' + 52;
  5741.     else if (a == '+')
  5742.         a = 62;
  5743.     else if (a == '/')
  5744.         a = 63;
  5745.     else
  5746.         a = 255;
  5747.  
  5748.     return a;
  5749. }
  5750.  
  5751. BYTE fromBase64(BYTE *target, char *source)
  5752. {
  5753.     //printf("SOURCE=%s\n", source);
  5754.     BYTE b = 0;
  5755.     BYTE shift = 4;
  5756.     BYTE bp_hlen = (3 * strlen(source))/4;
  5757.     *target = 0;
  5758.  
  5759.     if (*source)
  5760.     {
  5761.         b = getBaseValue(*source);
  5762.         *target = b << 2;
  5763.         source++;
  5764.  
  5765.         while (*source)
  5766.         {
  5767.             b = getBaseValue(*source);
  5768.             (*target) += (b >> (8 - shift));
  5769.             target++;
  5770.             (*target) = (b << shift);
  5771.             shift += 2;
  5772.  
  5773.             if (shift > 8)
  5774.             {
  5775.                 source++;
  5776.  
  5777.                 if (*source)
  5778.                 {
  5779.                     b = getBaseValue(*source);
  5780.                     *target = b << 2;
  5781.                     shift = 4;
  5782.                 }
  5783.                 else
  5784.                     break;
  5785.             }
  5786.  
  5787.             source++;
  5788.         }
  5789.     }
  5790.     //printf("SIZE=%u\n", bp_hlen);
  5791.     return bp_hlen;
  5792. }
  5793.  
  5794. char *toUUE(char *tempbuff, BYTE *source, BYTE length)
  5795. {
  5796.     BYTE a = 0, b = 0, i = 0;
  5797.     char *dp = tempbuff;
  5798.  
  5799.     for (; length; length--, source++)
  5800.     {
  5801.         i += 2;
  5802.         a = (*source) >> i;
  5803.         *dp = a + b + 32;
  5804.         dp++;
  5805.         b = (*source) << (8 - i);
  5806.         b >>= 2;
  5807.         if (i == 6)
  5808.         {
  5809.             *dp = b + 32;
  5810.             dp++;
  5811.             i = b = 0;
  5812.         }
  5813.     }
  5814.     if (i)
  5815.     {
  5816.         *dp = b + 32;
  5817.         dp++;
  5818.     }
  5819.     *dp = 0;
  5820.     //printf("%s\n",tempbuff);
  5821.     return tempbuff;
  5822. }
  5823.  
  5824. BYTE fromUUE(BYTE *target, char *source)
  5825. {
  5826.     //printf("SOURCE=%s\n", source);
  5827.     BYTE b = 0;
  5828.     BYTE shift = 4;
  5829.     BYTE bp_hlen = (3 * strlen(source))/4;
  5830.     *target = 0;
  5831.  
  5832.     if (*source)
  5833.     {
  5834.         b = *source - 32;
  5835.         *target = b << 2;
  5836.         source++;
  5837.  
  5838.         while (*source)
  5839.         {
  5840.             b = *source - 32;
  5841.             (*target) += (b >> (8 - shift));
  5842.             target++;
  5843.             (*target) = (b << shift);
  5844.             shift += 2;
  5845.  
  5846.             if (shift > 8)
  5847.             {
  5848.                 source++;
  5849.  
  5850.                 if (*source)
  5851.                 {
  5852.                     b = *source - 32;
  5853.                     *target = b << 2;
  5854.                     shift = 4;
  5855.                 }
  5856.                 else
  5857.                     break;
  5858.             }
  5859.  
  5860.             source++;
  5861.         }
  5862.     }
  5863.     //printf("SIZE=%u\n", bp_hlen);
  5864.     return bp_hlen;
  5865. }
  5866.  
  5867. char *hex2String(char *target, BYTE *hex, BYTE bytes, char sepChar)
  5868. {
  5869.     char *dp = target;
  5870.  
  5871.     if (bytes)
  5872.         dp += sprintf(target, "%02x", *hex);
  5873.     else
  5874.         *target = 0;
  5875.  
  5876.     for (BYTE i = 1; i < bytes; i++)
  5877.         if (sepChar)
  5878.             dp += sprintf(dp, "%c%02x", sepChar, *(hex + i));
  5879.         else
  5880.             dp += sprintf(dp, "%02x", *(hex + i));
  5881.  
  5882.     return target;
  5883. }
  5884.  
  5885. char *IP62String(char *target, BYTE *source)
  5886. {
  5887.     bool started = false;
  5888.  
  5889.     for (BYTE i = 0; i < 16; i += 2, source += 2)
  5890.     {
  5891.         if (source[0])
  5892.         {
  5893.             target += sprintf(target, "%x", source[0]);
  5894.             target += sprintf(target, "%02x", source[1]);
  5895.             started = true;
  5896.         }
  5897.         else if (source[1] || started)
  5898.         {
  5899.             target += sprintf(target, "%0x", source[1]);
  5900.             started = true;
  5901.         }
  5902.         else if (i == 8)
  5903.             target += sprintf(target, ":");
  5904.  
  5905.         if (i < 14 && started)
  5906.             target += sprintf(target, ":");
  5907.  
  5908.         if (i == 6)
  5909.             started = false;
  5910.     }
  5911.     return NULL;
  5912. }
  5913.  
  5914. char *getHexValue(BYTE *target, char *source, BYTE *size)
  5915. {
  5916.     if (*size)
  5917.         memset(target, 0, (*size));
  5918.  
  5919.     if (*source == ':')
  5920.         source++;
  5921.  
  5922.     for ((*size) = 0; (*source) && (*size) < UCHAR_MAX; (*size)++, target++)
  5923.     {
  5924.         if ((*source) >= '0' && (*source) <= '9')
  5925.         {
  5926.             (*target) = (*source) - '0';
  5927.         }
  5928.         else if ((*source) >= 'a' && (*source) <= 'f')
  5929.         {
  5930.             (*target) = (*source) - 'a' + 10;
  5931.         }
  5932.         else if ((*source) >= 'A' && (*source) <= 'F')
  5933.         {
  5934.             (*target) = (*source) - 'A' + 10;
  5935.         }
  5936.         else
  5937.         {
  5938.             return source;
  5939.         }
  5940.  
  5941.         source++;
  5942.  
  5943.         if ((*source) >= '0' && (*source) <= '9')
  5944.         {
  5945.             (*target) *= 16;
  5946.             (*target) += ((*source) - '0');
  5947.         }
  5948.         else if ((*source) >= 'a' && (*source) <= 'f')
  5949.         {
  5950.             (*target) *= 16;
  5951.             (*target) += (((*source) - 'a') + 10);
  5952.         }
  5953.         else if ((*source) >= 'A' && (*source) <= 'F')
  5954.         {
  5955.             (*target) *= 16;
  5956.             (*target) += (((*source) - 'A') + 10);
  5957.         }
  5958.         else if ((*source) == ':')
  5959.         {
  5960.             source++;
  5961.             continue;
  5962.         }
  5963.         else if (*source)
  5964.             return source;
  5965.         else
  5966.             continue;
  5967.  
  5968.         source++;
  5969.  
  5970.         if ((*source) == ':')
  5971.             source++;
  5972.         else if (*source)
  5973.             return source;
  5974.     }
  5975.  
  5976.     if (*source)
  5977.         return source;
  5978.  
  5979.     return NULL;
  5980. }
  5981.  
  5982. char *myUpper(char *string)
  5983. {
  5984.     char diff = 'a' - 'A';
  5985.     WORD len = strlen(string);
  5986.     for (int i = 0; i < len; i++)
  5987.         if (string[i] >= 'a' && string[i] <= 'z')
  5988.             string[i] -= diff;
  5989.     return string;
  5990. }
  5991.  
  5992. char *myLower(char *string)
  5993. {
  5994.     char diff = 'a' - 'A';
  5995.     WORD len = strlen(string);
  5996.     for (int i = 0; i < len; i++)
  5997.         if (string[i] >= 'A' && string[i] <= 'Z')
  5998.             string[i] += diff;
  5999.     return string;
  6000. }
  6001.  
  6002. bool wildcmp(char *string, char *wild)
  6003. {
  6004.     // Written by Jack Handy - jakkhandy@hotmail.com
  6005.     // slightly modified
  6006.     char *cp = NULL;
  6007.     char *mp = NULL;
  6008.  
  6009.     while ((*string) && (*wild != '*'))
  6010.     {
  6011.         if ((*wild != *string) && (*wild != '?'))
  6012.         {
  6013.             return 0;
  6014.         }
  6015.         wild++;
  6016.         string++;
  6017.     }
  6018.  
  6019.     while (*string)
  6020.     {
  6021.         if (*wild == '*')
  6022.         {
  6023.             if (!*++wild)
  6024.                 return 1;
  6025.  
  6026.             mp = wild;
  6027.             cp = string + 1;
  6028.         }
  6029.         else if ((*wild == *string) || (*wild == '?'))
  6030.         {
  6031.             wild++;
  6032.             string++;
  6033.         }
  6034.         else
  6035.         {
  6036.             wild = mp;
  6037.             string = cp++;
  6038.         }
  6039.     }
  6040.  
  6041.     while (*wild == '*')
  6042.         wild++;
  6043.  
  6044.     return !(*wild);
  6045. }
  6046.  
  6047. BYTE makeLocal(DWORD ip)
  6048. {
  6049.     if (cfig.rangeStart && htonl(ip) >= cfig.rangeStart && htonl(ip) <= cfig.rangeEnd)
  6050.         return 1;
  6051.     else if (getRangeInd(ip) >= 0)
  6052.         return 1;
  6053.     else
  6054.         return 0;
  6055. }
  6056.  
  6057. BYTE makeLocal(char *query)
  6058. {
  6059.     if (!strcasecmp(query, cfig.zone))
  6060.         return 3;
  6061.     else
  6062.     {
  6063.         char *dp = strchr(query, '.');
  6064.  
  6065.         if (dp)
  6066.         {
  6067.             if (!strcasecmp(dp + 1, cfig.zone))
  6068.             {
  6069.                 *dp = 0;
  6070.                 return 2;
  6071.             }
  6072.             return 0;
  6073.         }
  6074.         return 1;
  6075.     }
  6076.     return 0;
  6077. }
  6078.  
  6079. void checkSize(BYTE ind)
  6080. {
  6081.     //printf("Start %u=%u\n",dnsCache[ind].size(),dnsAge[ind].size());
  6082.     time_t t = time(NULL);
  6083.     data7 *cache = NULL;
  6084.     //BYTE maxDelete = 3;
  6085.     expiryMap::iterator p = dnsAge[ind].begin();
  6086.     expiryMap::iterator q;
  6087.  
  6088.     //while (p != dnsAge[ind].end() && p->first < t && maxDelete > 0)
  6089.     while (p != dnsAge[ind].end() && p->first < t)
  6090.     {
  6091.         cache = p->second;
  6092.         //printf("processing %s=%i\n", cache->mapname, p->first - t);
  6093.  
  6094.         if (cache->expiry < t)
  6095.         {
  6096.             q = p;
  6097.             p++;
  6098.             dnsAge[ind].erase(q);
  6099.  
  6100.             if (cache->expiry)
  6101.             {
  6102.                 if (cache->dnsIndex < MAX_SERVERS)
  6103.                 {
  6104.                     if (cfig.currentDNS == cache->dnsIndex)
  6105.                     {
  6106.                         if (network.dns[1])
  6107.                         {
  6108.                             cfig.currentDNS++;
  6109.  
  6110.                             if (cfig.currentDNS >= MAX_SERVERS || !network.dns[cfig.currentDNS])
  6111.                                 cfig.currentDNS = 0;
  6112.                         }
  6113.                     }
  6114.                 }
  6115.                 else if (cache->dnsIndex >= 128 && cache->dnsIndex < 192)
  6116.                 {
  6117.                     data6 *dnsRoute = &cfig.dnsRoutes[(cache->dnsIndex - 128) / 2];
  6118.                     BYTE currentDNS = cache->dnsIndex % 2;
  6119.  
  6120.                     if (dnsRoute->currentDNS == currentDNS && dnsRoute->dns[1])
  6121.                         dnsRoute->currentDNS = 1 - dnsRoute->currentDNS;
  6122.                 }
  6123.             }
  6124.  
  6125.             //printf("t=%u expiry=%u DataType=%u Size=%u, Entry %s being deleted\n", t, cache->expiry, cache->dataType, dnsCache[ind].size(), cache->mapname);
  6126.             delDnsEntry(ind, cache);
  6127.             //maxDelete--;
  6128.         }
  6129.         else if (cache->expiry > p->first)
  6130.         {
  6131.             q = p;
  6132.             p++;
  6133.             dnsAge[ind].erase(q);
  6134.             dnsAge[ind].insert(pair<long, data7*>(cache->expiry, cache));
  6135.         }
  6136.         else
  6137.             p++;
  6138.     }
  6139.  
  6140.     if (ind == cacheInd && dhcpService)
  6141.     {
  6142.         //printf("dhcpAge=%u\n", dhcpAge.size());
  6143.  
  6144.         p = dhcpAge.begin();
  6145.  
  6146.         while (p != dhcpAge.end() && p->first < t)
  6147.         {
  6148.             cache = p->second;
  6149.             //printf("processing %s=%i\n", cache->mapname, p->first - t);
  6150.  
  6151.             if (cache->local && cache->expiry < t)
  6152.             {
  6153.                 q = p;
  6154.                 p++;
  6155.                 cache->local = 0;
  6156.                 dhcpAge.erase(q);
  6157.                 cfig.serial1 = time(NULL);
  6158.                 cfig.serial2 = time(NULL);
  6159.  
  6160.                 if (cfig.expire > (DWORD)(LONG_MAX - t))
  6161.                     cfig.expireTime = LONG_MAX;
  6162.                 else
  6163.                     cfig.expireTime = t + cfig.expire;
  6164.  
  6165.                 sendRepl(cache);
  6166.                 //printf("Lease released\n");
  6167.             }
  6168.             else if (cache->expiry > p->first)
  6169.             {
  6170.                 q = p;
  6171.                 p++;
  6172.                 dhcpAge.erase(q);
  6173.                 dhcpAge.insert(pair<long, data7*>(cache->expiry, cache));
  6174.             }
  6175.             else
  6176.                 p++;
  6177.         }
  6178.     }
  6179.     //printf("Done %u=%u\n",dnsCache[ind].size(),dnsAge[ind].size());
  6180. }
  6181.  
  6182. void calcRangeLimits(DWORD ip, DWORD mask, DWORD *rangeStart, DWORD *rangeEnd)
  6183. {
  6184.     *rangeStart = htonl(ip & mask) + 1;
  6185.     *rangeEnd = htonl(ip | (~mask)) - 1;
  6186. }
  6187.  
  6188. bool checkMask(DWORD mask)
  6189. {
  6190.     mask = htonl(mask);
  6191.     while (mask)
  6192.     {
  6193.         if (mask < (mask << 1))
  6194.             return false;
  6195.  
  6196.         mask <<= 1;
  6197.     }
  6198.     return true;
  6199. }
  6200.  
  6201. DWORD calcMask(DWORD rangeStart, DWORD rangeEnd)
  6202. {
  6203.     data15 ip1, ip2, mask;
  6204.  
  6205.     ip1.ip = htonl(rangeStart);
  6206.     ip2.ip = htonl(rangeEnd);
  6207.  
  6208.     for (BYTE i = 0; i < 4; i++)
  6209.     {
  6210.         mask.octate[i] = ip1.octate[i] ^ ip2.octate[i];
  6211.  
  6212.         if (i && mask.octate[i - 1] < 255)
  6213.             mask.octate[i] = 0;
  6214.         else if (mask.octate[i] == 0)
  6215.             mask.octate[i] = 255;
  6216.         else if (mask.octate[i] < 2)
  6217.             mask.octate[i] = 254;
  6218.         else if (mask.octate[i] < 4)
  6219.             mask.octate[i] = 252;
  6220.         else if (mask.octate[i] < 8)
  6221.             mask.octate[i] = 248;
  6222.         else if (mask.octate[i] < 16)
  6223.             mask.octate[i] = 240;
  6224.         else if (mask.octate[i] < 32)
  6225.             mask.octate[i] = 224;
  6226.         else if (mask.octate[i] < 64)
  6227.             mask.octate[i] = 192;
  6228.         else if (mask.octate[i] < 128)
  6229.             mask.octate[i] = 128;
  6230.         else
  6231.             mask.octate[i] = 0;
  6232.     }
  6233.     return mask.ip;
  6234. }
  6235.  
  6236. data7 *findEntry(BYTE ind, char *key, BYTE entryType)
  6237. {
  6238.     myLower(key);
  6239.     hostMap::iterator it = dnsCache[ind].find(key);
  6240.  
  6241.     while (it != dnsCache[ind].end() && !strcasecmp(it->second->mapname, key))
  6242.         if (it->second->dataType == entryType)
  6243.             return it->second;
  6244.         else
  6245.             it++;
  6246.  
  6247.     return NULL;
  6248. }
  6249.  
  6250. data7 *findEntry(BYTE ind, char *key)
  6251. {
  6252.     //printf("finding %u=%s\n",ind,key);
  6253.     myLower(key);
  6254.     hostMap::iterator it = dnsCache[ind].find(key);
  6255.  
  6256.     if (it != dnsCache[ind].end())
  6257.         return it->second;
  6258.     else
  6259.         return NULL;
  6260. }
  6261.  
  6262. void addEntry(BYTE ind, data7 *entry)
  6263. {
  6264.     myLower(entry->mapname);
  6265.     dnsCache[ind].insert(pair<string, data7*>(entry->mapname, entry));
  6266.  
  6267.     if (entry->expiry && entry->expiry < LONG_MAX)
  6268.         dnsAge[ind].insert(pair<long, data7*>(entry->expiry, entry));
  6269. }
  6270.  
  6271. void delDnsEntry(BYTE ind, data7* cache)
  6272. {
  6273.     if (cache)
  6274.     {
  6275.         //printf("DataType=%u Size=%u, Entry %s being deleted\n", cache->dataType, dnsCache[ind].size(), cache->mapname);
  6276.  
  6277.         if (ind <= 1)
  6278.         {
  6279.             hostMap::iterator r = dnsCache[ind].find(cache->mapname);
  6280.  
  6281.             for (; r != dnsCache[ind].end(); r++)
  6282.                 if (strcasecmp(r->second->mapname, cache->mapname))
  6283.                     break;
  6284.                 else if (r->second == cache)
  6285.                 {
  6286.                     dnsCache[ind].erase(r);
  6287.                     break;
  6288.                 }
  6289.  
  6290.             switch (cache->dataType)
  6291.             {
  6292.                 case QUEUE:
  6293.  
  6294.                     if (cache->addr)
  6295.                         free(cache->addr);
  6296.  
  6297.                     if (cache->query)
  6298.                         free(cache->query);
  6299.  
  6300.                     if (cache->mapname)
  6301.                         free(cache->mapname);
  6302.  
  6303.                     break;
  6304.  
  6305.                 case LOCAL_PTR_AUTH:
  6306.                 case LOCAL_PTR_NAUTH:
  6307.                 case LOCALHOST_PTR:
  6308.                 case SERVER_PTR_AUTH:
  6309.                 case SERVER_PTR_NAUTH:
  6310.                 case STATIC_PTR_AUTH:
  6311.                 case STATIC_PTR_NAUTH:
  6312.                 case LOCAL_CNAME:
  6313.                 case EXT_CNAME:
  6314.                 case CACHED:
  6315.  
  6316.                     if (cache->hostname)
  6317.                         free(cache->hostname);
  6318.  
  6319.                     if (cache->mapname)
  6320.                         free(cache->mapname);
  6321.  
  6322.                     break;
  6323.  
  6324.                 default:
  6325.  
  6326.                     if (cache->mapname)
  6327.                         free(cache->mapname);
  6328.  
  6329.                     break;
  6330.             }
  6331.  
  6332.             free(cache);
  6333.         }
  6334.     }
  6335.     return ;
  6336. }
  6337.  
  6338. char *cloneString(char *string)
  6339. {
  6340.     char *s = (char*)calloc(1, strlen(string) + 1);
  6341.  
  6342.     if (s)
  6343.     {
  6344.         strcpy(s, string);
  6345.     }
  6346.     return s;
  6347. }
  6348.  
  6349. DWORD getSerial(char *zone)
  6350. {
  6351.     time_t t = time(NULL);
  6352.     char tempbuff[256];
  6353.     char logBuff[256];
  6354.     DWORD serial1 = 0;
  6355.     data5 req;
  6356.     memset(&req, 0, sizeof(data5));
  6357.     req.addr.sin_family = AF_INET;
  6358.     req.addr.sin_port = htons(IPPORT_DNS);
  6359.     timeval tv1;
  6360.     fd_set readfds1;
  6361.  
  6362.     if (cfig.replication == 2)
  6363.         req.addr.sin_addr.s_addr = cfig.zoneServers[0];
  6364.     else
  6365.         req.addr.sin_addr.s_addr = cfig.zoneServers[1];
  6366.  
  6367.     req.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  6368.     req.dnsp = (dnsPacket*)req.raw;
  6369.     req.dnsp->header.qdcount = htons(1);
  6370.     req.dnsp->header.xid = (t % USHRT_MAX);
  6371.     req.data = &req.dnsp->data;
  6372.     req.data += pQu(req.data, zone);
  6373.     req.data += pUShort(req.data, DNS_TYPE_SOA);
  6374.     req.data += pUShort(req.data, DNS_CLASS_IN);
  6375.     req.bytes = (DWORD)req.data - (DWORD)req.raw;
  6376.     //pUShort(req.raw, req.bytes - 2);
  6377.  
  6378.     if ((req.bytes = sendto(req.sock, req.raw, req.bytes, 0, (sockaddr*)&req.addr, sizeof(req.addr))) <= 0)
  6379.     {
  6380.         closesocket(req.sock);
  6381.         sprintf(logBuff, "Failed to send request to Primary Server %s", IP2String(tempbuff, req.addr.sin_addr.s_addr));
  6382.         logDNSMess(logBuff, 1);
  6383.         return 0;
  6384.     }
  6385.  
  6386.     FD_ZERO(&readfds1);
  6387.     tv1.tv_sec = 3;
  6388.     tv1.tv_usec = 0;
  6389.     FD_SET(req.sock, &readfds1);
  6390.     select(USHRT_MAX, &readfds1, NULL, NULL, &tv1);
  6391.  
  6392.     if (FD_ISSET(req.sock, &readfds1))
  6393.     {
  6394.         req.sockLen = sizeof(req.addr);
  6395.         req.bytes = recvfrom(req.sock, req.raw, sizeof(req.raw), 0, (sockaddr*)&req.addr, &req.sockLen);
  6396.  
  6397.         if (req.bytes > 0 && req.dnsp->header.qr && !req.dnsp->header.rcode && ntohs(req.dnsp->header.ancount))
  6398.         {
  6399.             req.data = &req.dnsp->data;
  6400.             for (int j = 1; j <= ntohs(req.dnsp->header.qdcount); j++)
  6401.             {
  6402.                 req.data += fQu(tempbuff, req.dnsp, req.data);
  6403.                 req.data += 4;
  6404.             }
  6405.  
  6406.             for (int i = 1; i <= ntohs(req.dnsp->header.ancount); i++)
  6407.             {
  6408.                 req.data += fQu(tempbuff, req.dnsp, req.data);
  6409.                 req.qtype = fUShort(req.data);
  6410.                 req.data += 2; //type
  6411.                 req.qclass = fUShort(req.data);
  6412.                 req.data += 2; //class
  6413.                 fULong(req.data);
  6414.                 req.data += 4; //ttl
  6415.                 req.data += 2; //datalength
  6416.  
  6417.                 if (req.qtype == DNS_TYPE_SOA)
  6418.                 {
  6419.                     req.data += fQu(tempbuff, req.dnsp, req.data);
  6420.                     req.data += fQu(tempbuff, req.dnsp, req.data);
  6421.                     serial1 = fULong(req.data);
  6422.                 }
  6423.             }
  6424.         }
  6425.     }
  6426.  
  6427.     closesocket(req.sock);
  6428.     return serial1;
  6429. }
  6430.  
  6431. void checkDNS(BYTE dnsIndex)
  6432. {
  6433.     time_t t = time(NULL);
  6434.     //printf("DNS Index %u\n", dnsIndex);
  6435.     data5 req;
  6436.     memset(&req, 0, sizeof(data5));
  6437.     strcpy(req.query, "1.0.0.127.in-addr.arpa");
  6438.     req.addr.sin_family = AF_INET;
  6439.     req.addr.sin_port = htons(IPPORT_DNS);
  6440.  
  6441.     if (dnsIndex < MAX_SERVERS)
  6442.     {
  6443.         if (cfig.currentDNS == dnsIndex)
  6444.             req.addr.sin_addr.s_addr = network.dns[dnsIndex];
  6445.         else
  6446.             return ;
  6447.     }
  6448.     else if (dnsIndex >= 128 && dnsIndex < 192)
  6449.     {
  6450.         BYTE childIndex = (dnsIndex - 128) / 2;
  6451.         data6 *dnsRoute = &cfig.dnsRoutes[childIndex];
  6452.         BYTE currentDNS = dnsIndex % 2;
  6453.  
  6454.         if (dnsRoute->currentDNS == currentDNS)
  6455.             req.addr.sin_addr.s_addr = dnsRoute->dns[currentDNS];
  6456.         else
  6457.             return ;
  6458.     }
  6459.     else
  6460.         return ;
  6461.  
  6462.     req.dnsp = (dnsPacket*)req.raw;
  6463.     req.dnsp->header.qdcount = htons(1);
  6464.     req.dnsp->header.xid = (t % USHRT_MAX);
  6465.     req.data = &req.dnsp->data;
  6466.     req.data += pQu(req.data, req.query);
  6467.     req.data += pUShort(req.data, DNS_TYPE_PTR);
  6468.     req.data += pUShort(req.data, DNS_CLASS_IN);
  6469.     req.bytes = (DWORD)req.data - (DWORD)req.raw;
  6470.  
  6471.     char mapname[8];
  6472.     sprintf(mapname, "%u", req.dnsp->header.xid);
  6473.     data7 *queue = findEntry(cacheInd, mapname, DNS_CHECK);
  6474.  
  6475.     if (!queue)
  6476.     {
  6477.         if ((req.bytes = sendto(network.forwConn.sock, req.raw, req.bytes, 0, (sockaddr*)&req.addr, sizeof(req.addr))) > 0)
  6478.         {
  6479.             queue = (data7*)calloc(1, sizeof(data7));
  6480.             if (queue)
  6481.             {
  6482.                 queue->mapname = cloneString(mapname);
  6483.  
  6484.                 if (!queue->mapname)
  6485.                 {
  6486.                     free(queue);
  6487.                     return ;
  6488.                 }
  6489.  
  6490.                 queue->expiry = 2 + t;
  6491.                 queue->dataType = DNS_CHECK;
  6492.                 queue->sockInd = 255;
  6493.                 queue->dnsIndex = dnsIndex;
  6494.                 addEntry(cacheInd, queue);
  6495.             }
  6496.             else
  6497.                 return ;
  6498.  
  6499.             if (cfig.dnsLogLevel)
  6500.             {
  6501.                 if (dnsIndex < MAX_SERVERS)
  6502.                     sprintf(logBuff, "Verification sent to Forwarding DNS Server %s", IP2String(tempbuff, req.addr.sin_addr.s_addr));
  6503.                 else
  6504.                     sprintf(logBuff, "Verification sent to Child DNS Server %s", IP2String(tempbuff, req.addr.sin_addr.s_addr));
  6505.  
  6506.                 logDNSMess(logBuff, 1);
  6507.             }
  6508.         }
  6509.     }
  6510. }
  6511.  
  6512. char *getServerName(char *target, DWORD ip)
  6513. {
  6514.     time_t t = time(NULL);
  6515.     data5 req;
  6516.     memset(&req, 0, sizeof(data5));
  6517.     req.addr.sin_family = AF_INET;
  6518.     req.addr.sin_port = htons(IPPORT_DNS);
  6519.     req.addr.sin_addr.s_addr = ip;
  6520.  
  6521.     timeval tv1;
  6522.     fd_set readfds1;
  6523.  
  6524.     req.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  6525.  
  6526.     req.dnsp = (dnsPacket*)req.raw;
  6527.     req.dnsp->header.qdcount = htons(1);
  6528.     req.dnsp->header.xid = (t % USHRT_MAX);
  6529.     req.data = &req.dnsp->data;
  6530.     IP2String(target, htonl(ip));
  6531.     strcat(target, arpa);
  6532.     req.data += pQu(req.data, target);
  6533.     req.data += pUShort(req.data, DNS_TYPE_PTR);
  6534.     req.data += pUShort(req.data, DNS_CLASS_IN);
  6535.     req.bytes = (DWORD)req.data - (DWORD)req.raw;
  6536.     //pUShort(req.raw, req.bytes - 2);
  6537.  
  6538.     if ((req.bytes = sendto(req.sock, req.raw, req.bytes, 0, (sockaddr*)&req.addr, sizeof(req.addr))) <= 0)
  6539.     {
  6540.         closesocket(req.sock);
  6541.         return NULL;
  6542.     }
  6543.  
  6544.     FD_ZERO(&readfds1);
  6545.     tv1.tv_sec = 5;
  6546.     tv1.tv_usec = 0;
  6547.     FD_SET(req.sock, &readfds1);
  6548.     select(USHRT_MAX, &readfds1, NULL, NULL, &tv1);
  6549.  
  6550.     if (FD_ISSET(req.sock, &readfds1))
  6551.     {
  6552.         req.sockLen = sizeof(req.addr);
  6553.         req.bytes = recvfrom(req.sock, req.raw, sizeof(req.raw), 0, (sockaddr*)&req.addr, &req.sockLen);
  6554.         if (req.bytes > 0 && req.dnsp->header.qr && !req.dnsp->header.rcode && ntohs(req.dnsp->header.ancount))
  6555.         {
  6556.             closesocket(req.sock);
  6557.             return getResult(&req);
  6558.         }
  6559.     }
  6560.  
  6561.     closesocket(req.sock);
  6562.     return NULL;
  6563. }
  6564.  
  6565. WORD recvTcpDnsMess(SOCKET sock, char *target, bool ready)
  6566. {
  6567.     timeval tv1;
  6568.     fd_set readfds1;
  6569.  
  6570.     if (!ready)
  6571.     {
  6572.         FD_ZERO(&readfds1);
  6573.         tv1.tv_sec = 5;
  6574.         tv1.tv_usec = 0;
  6575.         FD_SET(sock, &readfds1);
  6576.  
  6577.         if (!select(sock + 1, &readfds1, NULL, NULL, &tv1))
  6578.             return 0;
  6579.     }
  6580.  
  6581.     errno = 0;
  6582.     WORD rcd = recv(sock, target, 2, 0);
  6583.     errno = WSAGetLastError();
  6584.  
  6585.     if (errno)
  6586.         return 0;
  6587.  
  6588.     if (rcd == 2)
  6589.     {
  6590.         WORD bytes = fUShort(target) + rcd;
  6591.         char *ptr;
  6592.  
  6593.         while (rcd < bytes)
  6594.         {
  6595.             FD_ZERO(&readfds1);
  6596.             tv1.tv_sec = 5;
  6597.             tv1.tv_usec = 0;
  6598.             FD_SET(sock, &readfds1);
  6599.             ptr = target + rcd;
  6600.  
  6601.             if (select(sock + 1, &readfds1, NULL, NULL, &tv1))
  6602.             {
  6603.                 errno = 0;
  6604.                 rcd += recv(sock, ptr, bytes - rcd, 0);
  6605.                 errno = WSAGetLastError();
  6606.  
  6607.                 if (errno)
  6608.                     return 0;
  6609.             }
  6610.             else
  6611.                 return 0;
  6612.         }
  6613.         return rcd;
  6614.     }
  6615.     return 0;
  6616. }
  6617.  
  6618. void checkZone(void *lpParam)
  6619. {
  6620.     char tempbuff[256];
  6621.     char logBuff[256];
  6622.  
  6623.     while (true)
  6624.     {
  6625.         if (!network.ready || network.busy)
  6626.         {
  6627.             Sleep(100);
  6628.             continue;
  6629.         }
  6630.  
  6631.         time_t t = time(NULL);
  6632.         sprintf(logBuff, "Checking Serial from Primary Server %s", IP2String(tempbuff, cfig.zoneServers[0]));
  6633.         logDNSMess(logBuff, 2);
  6634.  
  6635.         DWORD serial1 = getSerial(cfig.zone);
  6636.         DWORD serial2 = getSerial(cfig.authority);
  6637.  
  6638.         if (!serial1 || !serial2)
  6639.         {
  6640.             sprintf(logBuff, "Failed to get Serial from %s", IP2String(tempbuff, cfig.zoneServers[0]));
  6641.             logDNSMess(logBuff, 1);
  6642.             Sleep(1000*(cfig.retry));
  6643.             continue;
  6644.         }
  6645.         else if (cfig.serial1 && cfig.serial1 == serial1 && cfig.serial2 && cfig.serial2 == serial2)
  6646.         {
  6647.             sprintf(logBuff, "Zone Refresh not required");
  6648.             logDNSMess(logBuff, 2);
  6649.  
  6650.             if (cfig.expire > (DWORD)(LONG_MAX - t))
  6651.                 cfig.expireTime = LONG_MAX;
  6652.             else
  6653.                 cfig.expireTime = t + cfig.expire;
  6654.  
  6655.             Sleep(1000*(cfig.refresh));
  6656.         }
  6657.         else
  6658.         {
  6659.             serial1 = getZone(1 - cacheInd, cfig.zone);
  6660.             serial2 = getZone(1 - cacheInd, cfig.authority);
  6661.  
  6662.             if (!serial1 || !serial2)
  6663.             {
  6664.                 sprintf(logBuff, "Waiting %u seconds to retry", cfig.retry);
  6665.                 logDNSMess(logBuff, 1);
  6666.                 Sleep(1000*(cfig.retry));
  6667.             }
  6668.             else
  6669.             {
  6670.                 newInd = 1 - cacheInd;
  6671.                 cfig.serial1 = serial1;
  6672.                 cfig.serial2 = serial2;
  6673.  
  6674.                 if (cfig.expire > (DWORD)(LONG_MAX - t))
  6675.                     cfig.expireTime = LONG_MAX;
  6676.                 else
  6677.                     cfig.expireTime = t + cfig.expire;
  6678.  
  6679.                 if (!lpParam)
  6680.                     break;
  6681.  
  6682.                 Sleep(1000*(cfig.refresh));
  6683.             }
  6684.         }
  6685.     }
  6686.     _endthread();
  6687.     return;
  6688. }
  6689.  
  6690. DWORD getZone(BYTE updateCache, char *zone)
  6691. {
  6692.     char tempbuff[256];
  6693.     char logBuff[256];
  6694.     char hostname[256];
  6695.     char cname[256];
  6696.     DWORD serial1 = 0;
  6697.     DWORD serial2 = 0;
  6698.     DWORD hostExpiry = 0;
  6699.     DWORD refresh = 0;
  6700.     DWORD retry = 0;
  6701.     DWORD expire = 0;
  6702.     DWORD expiry;
  6703.     DWORD minimum = 0;
  6704.     int added = 0;
  6705.     char *data;
  6706.     char *dp;
  6707.     DWORD ip;
  6708.     data5 req;
  6709.     memset(&req, 0, sizeof(data5));
  6710.     req.addr.sin_family = AF_INET;
  6711.     req.addr.sin_port = htons(IPPORT_DNS);
  6712.     req.addr.sin_addr.s_addr = cfig.zoneServers[0];
  6713.     req.sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  6714.  
  6715.     if (req.sock == INVALID_SOCKET)
  6716.     {
  6717.         sprintf(logBuff, "Failed to Create Socket, Zone Transfer Failed", IP2String(tempbuff, req.addr.sin_addr.s_addr));
  6718.         logDNSMess(logBuff, 1);
  6719.         return 0;
  6720.     }
  6721.  
  6722.     req.sockLen = sizeof(req.addr);
  6723.     time_t t = time(NULL);
  6724.  
  6725.     if (connect(req.sock, (sockaddr*)&req.addr, req.sockLen) >= 0)
  6726.     {
  6727.         req.data = req.raw;
  6728.         req.data += 2;
  6729.         req.dnsp = (dnsPacket*)req.data;
  6730.         req.dnsp->header.qdcount = htons(1);
  6731.         req.dnsp->header.xid = (t % USHRT_MAX);
  6732.         req.data = &req.dnsp->data;
  6733.         req.data += pQu(req.data, zone);
  6734.         req.data += pUShort(req.data, DNS_TYPE_AXFR);
  6735.         req.data += pUShort(req.data, DNS_CLASS_IN);
  6736.         req.bytes = (DWORD)req.data - (DWORD)req.raw;
  6737.         pUShort(req.raw, req.bytes - 2);
  6738.  
  6739.         if (send(req.sock, req.raw, req.bytes, 0) < req.bytes)
  6740.         {
  6741.             closesocket(req.sock);
  6742.             sprintf(logBuff, "Failed to send request to Replication Server %s, Zone Transfer Failed", IP2String(tempbuff, req.addr.sin_addr.s_addr));
  6743.             logDNSMess(logBuff, 1);
  6744.             return 0;
  6745.         }
  6746.  
  6747.         if (!strcasecmp(zone, cfig.zone))
  6748.         {
  6749.             for (; cfig.mxCount[updateCache]; cfig.mxCount[updateCache]--)
  6750.                 strcpy(cfig.mxServers[updateCache][cfig.mxCount[updateCache]].hostname, "");
  6751.         }
  6752.  
  6753.         while (true)
  6754.         {
  6755.             req.bytes = recvTcpDnsMess(req.sock, req.raw, false);
  6756.             //printf("bytes = %u\n", req.bytes);
  6757.  
  6758.             if (req.bytes < 2)
  6759.                 break;
  6760.  
  6761.             WORD pktSize = fUShort(req.raw);
  6762.  
  6763.             if ((WORD)req.bytes < pktSize + 2)
  6764.                 break;
  6765.  
  6766.             req.dnsp = (dnsPacket*)(req.raw + 2);
  6767.             req.data = &req.dnsp->data;
  6768.  
  6769.             if (!req.dnsp->header.qr || req.dnsp->header.rcode || !ntohs(req.dnsp->header.ancount))
  6770.                 break;
  6771.  
  6772.             for (int j = 1; j <= ntohs(req.dnsp->header.qdcount); j++)
  6773.             {
  6774.                 req.data += fQu(hostname, req.dnsp, req.data);
  6775.                 req.data += 4;
  6776.             }
  6777.  
  6778.             for (int i = 1; i <= ntohs(req.dnsp->header.ancount); i++)
  6779.             {
  6780.                 //char *dp = req.data;
  6781.                 req.data += fQu(hostname, req.dnsp, req.data);
  6782.                 //printf("%s\n", hostname);
  6783.                 req.qtype = fUShort(req.data);
  6784.                 req.data += 2; //type
  6785.                 req.qclass = fUShort(req.data);
  6786.                 req.data += 2; //class
  6787.                 expiry = fULong(req.data);
  6788.                 req.data += 4; //ttl
  6789.                 int zLen = fUShort(req.data);
  6790.                 req.data += 2; //datalength
  6791.                 data = req.data;
  6792.                 req.data += zLen;
  6793.  
  6794.                 switch (req.qtype)
  6795.                 {
  6796.                     case DNS_TYPE_SOA:
  6797.  
  6798.                         data += fQu(hostname, req.dnsp, data);
  6799.                         data += fQu(cname, req.dnsp, data);
  6800.  
  6801.                         if (!serial1)
  6802.                         {
  6803.                             hostExpiry = expiry;
  6804.                             serial1 = fULong(data);
  6805.                             data += 4;
  6806.                             refresh = fULong(data);
  6807.                             data += 4;
  6808.                             retry = fULong(data);
  6809.                             data += 4;
  6810.                             expire = fULong(data);
  6811.                             data += 4;
  6812.                             minimum = fULong(data);
  6813.                             data += 4;
  6814.                             added++;
  6815.                         }
  6816.                         else if (!serial2)
  6817.                             serial2 = fULong(data);
  6818.  
  6819.                         break;
  6820.  
  6821.                     case DNS_TYPE_A:
  6822.  
  6823.                         ip = fIP(data);
  6824.                         makeLocal(hostname);
  6825.  
  6826.                         if (dhcpService && expiry < hostExpiry)
  6827.                         {
  6828.                             char rInd = getRangeInd(ip);
  6829.                             int ind = getIndex(rInd, ip);
  6830.  
  6831.                             if (expiry > LONG_MAX)
  6832.                                 expiry = LONG_MAX;
  6833.  
  6834.                             if (ind >= 0 && cfig.dhcpRanges[rInd].dhcpEntry[ind])
  6835.                                 setLeaseExpiry(cfig.dhcpRanges[rInd].dhcpEntry[ind], expiry, false);
  6836.                             else
  6837.                                 setLeaseExpiry(ip, 0);
  6838.  
  6839.                             if (expiry < (DWORD)(LONG_MAX - t))
  6840.                                 expiry += t;
  6841.  
  6842.                             addToCache(updateCache, hostname, ip, expiry, LOCAL_A, NONE, serial1);
  6843.                             added++;
  6844.                         }
  6845.                         else
  6846.                         {
  6847.                             setLeaseExpiry(ip, LONG_MAX);
  6848.                             addToCache(updateCache, hostname, ip, LONG_MAX, STATIC_A_AUTH, NONE, serial1);
  6849.                             added++;
  6850.                         }
  6851.                         break;
  6852.  
  6853.                     case DNS_TYPE_PTR:
  6854.  
  6855.                         myLower(hostname);
  6856.                         dp = strstr(hostname, arpa);
  6857.  
  6858.                         if (dp)
  6859.                         {
  6860.                             *dp = 0;
  6861.                             ip = ntohl(my_inet_addr(hostname));
  6862.                             fQu(hostname, req.dnsp, data);
  6863.                             makeLocal(hostname);
  6864.  
  6865.                             if (dhcpService && expiry < hostExpiry)
  6866.                             {
  6867.                                 char rInd = getRangeInd(ip);
  6868.                                 int ind = getIndex(rInd, ip);
  6869.  
  6870.                                 if (expiry > LONG_MAX)
  6871.                                     expiry = LONG_MAX;
  6872.  
  6873.                                 if (ind >= 0 && cfig.dhcpRanges[rInd].dhcpEntry[ind])
  6874.                                     setLeaseExpiry(cfig.dhcpRanges[rInd].dhcpEntry[ind], expiry, false);
  6875.                                 else
  6876.                                     setLeaseExpiry(ip, 0);
  6877.  
  6878.                                 if (expiry < (DWORD)(LONG_MAX - t))
  6879.                                     expiry += t;
  6880.  
  6881.                                 addToCache(updateCache, hostname, ip, expiry, NONE, LOCAL_PTR_AUTH, serial1);
  6882.                                 added++;
  6883.                             }
  6884.                             else
  6885.                             {
  6886.                                 setLeaseExpiry(ip, LONG_MAX);
  6887.                                 addToCache(updateCache, hostname, ip, LONG_MAX, NONE, STATIC_PTR_AUTH, serial1);
  6888.                                 added++;
  6889.                             }
  6890.                         }
  6891.                         break;
  6892.  
  6893.                     case DNS_TYPE_MX:
  6894.  
  6895.                         if (cfig.replication == 2 && makeLocal(hostname) == 3)
  6896.                         {
  6897.                             cfig.mxServers[updateCache][cfig.mxCount[updateCache]].pref = fUShort(data);
  6898.                             data += sizeof(WORD);
  6899.                             fQu(cname, req.dnsp, data);
  6900.                             strcpy(cfig.mxServers[updateCache][cfig.mxCount[updateCache]].hostname, cname);
  6901.                             cfig.mxCount[updateCache]++;
  6902.                             added++;
  6903.                         }
  6904.                         break;
  6905.  
  6906.                     case DNS_TYPE_NS:
  6907.                         if (cfig.replication == 2)
  6908.                             fQu(cfig.ns, req.dnsp, data);
  6909.                         break;
  6910.  
  6911.                     case DNS_TYPE_CNAME:
  6912.                         if (cfig.replication == 2)
  6913.                         {
  6914.                             fQu(cname, req.dnsp, data);
  6915.                             BYTE cname_type = 0;
  6916.  
  6917.                             if (makeLocal(cname))
  6918.                                 cname_type = LOCAL_CNAME;
  6919.                             else
  6920.                                 cname_type = EXT_CNAME;
  6921.  
  6922.                             makeLocal(hostname);
  6923.  
  6924.                             data7 *cache = findEntry(updateCache, hostname, cname_type);
  6925.  
  6926.                             if (!cache)
  6927.                             {
  6928.                                 cache = (data7*)calloc(1, sizeof(data7));
  6929.  
  6930.                                 if (cache)
  6931.                                 {
  6932.                                     cache->mapname = cloneString(hostname);
  6933.                                     cache->dataType = cname_type;
  6934.                                     cache->hostname = cloneString(cname);
  6935.  
  6936.                                     if (cache->mapname && cache->hostname)
  6937.                                     {
  6938.                                         addEntry(updateCache, cache);
  6939.                                     }
  6940.                                     else
  6941.                                     {
  6942.                                         sprintf(logBuff, "Memory Error");
  6943.                                         logDNSMess(logBuff, 1);
  6944.                                         continue;
  6945.                                     }
  6946.                                 }
  6947.                                 else
  6948.                                 {
  6949.                                     sprintf(logBuff, "Memory Error");
  6950.                                     logDNSMess(logBuff, 1);
  6951.                                     continue;
  6952.                                 }
  6953.                             }
  6954.                             else
  6955.                             {
  6956.                                 if (strcasecmp(cname, cache->hostname))
  6957.                                 {
  6958.                                     free(cache->hostname);
  6959.                                     cache->hostname = cloneString(cname);
  6960.                                 }
  6961.                             }
  6962.  
  6963.                             cache->expiry = LONG_MAX;
  6964.                             cache->serial = serial1;
  6965.                             added++;
  6966.                         }
  6967.                         break;
  6968.                 }
  6969.                 //printf("serial=%u %u %u\n", serial1, serial2, hostExpiry);
  6970.             }
  6971.         }
  6972.  
  6973.  
  6974.         strcpy(hostname, cfig.ns);
  6975.         makeLocal(hostname);
  6976.  
  6977.         data7 *cache = findEntry(updateCache, hostname, STATIC_A_AUTH);
  6978.  
  6979.         if (!cache)
  6980.             cache = findEntry(updateCache, hostname, STATIC_A_NAUTH);
  6981.  
  6982.         if (cache)
  6983.             cfig.nsIP = cache->ip;
  6984.  
  6985.         closesocket(req.sock);
  6986.  
  6987.         if (serial1 && serial1 == serial2 && hostExpiry)
  6988.         {
  6989.             if (cfig.replication == 2)
  6990.             {
  6991.                 //printf("Here %u %u %u %u %u \n",hostExpiry,refresh,retry,expire,minimum);
  6992.                 cfig.lease = hostExpiry;
  6993.                 cfig.refresh = refresh;
  6994.                 cfig.retry = retry;
  6995.                 cfig.expire = expire;
  6996.                 cfig.minimum = minimum;
  6997.             }
  6998.  
  6999.             if (cacheInd != updateCache)
  7000.             {
  7001.                 if (!strcasecmp(zone, cfig.zone))
  7002.                 {
  7003.                     hostMap::iterator q = dnsCache[updateCache].begin();
  7004.  
  7005.                     while (q != dnsCache[updateCache].end())
  7006.                     {
  7007.                         //printf("%s=%u\n", q->second->mapname,q->second->serial);
  7008.                         switch (q->second->dataType)
  7009.                         {
  7010.                             case LOCAL_A:
  7011.                             case SERVER_A:
  7012.                             case STATIC_A_AUTH:
  7013.                             case LOCAL_CNAME:
  7014.                             case EXT_CNAME:
  7015.                                 if (q->second->serial < serial1)
  7016.                                     q->second->expiry = 0;
  7017.                         }
  7018.                         q++;
  7019.                     }
  7020.                 }
  7021.                 else if (!strcasecmp(zone, cfig.authority))
  7022.                 {
  7023.                     hostMap::iterator q = dnsCache[updateCache].begin();
  7024.  
  7025.                     while (q != dnsCache[updateCache].end())
  7026.                     {
  7027.                         //printf("%s=%u\n", q->second->mapname,q->second->serial);
  7028.                         switch (q->second->dataType)
  7029.                         {
  7030.                             case LOCAL_PTR_AUTH:
  7031.                             case STATIC_PTR_AUTH:
  7032.                             case SERVER_PTR_AUTH:
  7033.                                 if (q->second->serial < serial1)
  7034.                                     q->second->expiry = 0;
  7035.                         }
  7036.                         q++;
  7037.                     }
  7038.                 }
  7039.  
  7040.                 checkSize(updateCache);
  7041.  
  7042.             }
  7043.  
  7044.             //printf("Refresh ind %i serial %u size %i\n", updateCache, serial1, dnsCache[updateCache].size());
  7045.             sprintf(logBuff, "Zone %s Transferred from %s, %u RRs imported", zone, IP2String(tempbuff, req.addr.sin_addr.s_addr), added);
  7046.             logDNSMess(logBuff, 2);
  7047.             return serial1;
  7048.         }
  7049.         else if (!serial1)
  7050.         {
  7051.             sprintf(logBuff, "Replication Server %s, Missing Serial", IP2String(tempbuff, req.addr.sin_addr.s_addr));
  7052.             logDNSMess(logBuff, 1);
  7053.         }
  7054.         else if (serial1 != serial2)
  7055.         {
  7056.             sprintf(logBuff, "Replication Server %s, Serial Changed %u %u", IP2String(tempbuff, req.addr.sin_addr.s_addr), serial1, serial2);
  7057.             logDNSMess(logBuff, 1);
  7058.         }
  7059.         else
  7060.         {
  7061.             sprintf(logBuff, "Replication Server %s, Invalid AXFR data", IP2String(tempbuff, req.addr.sin_addr.s_addr));
  7062.             logDNSMess(logBuff, 1);
  7063.         }
  7064.     }
  7065.     else
  7066.     {
  7067.         errno = WSAGetLastError();
  7068.         sprintf(logBuff, "Server %s, Error %u", IP2String(tempbuff, req.addr.sin_addr.s_addr), errno);
  7069.         logDNSMess(logBuff, 1);
  7070.         closesocket(req.sock);
  7071.     }
  7072.  
  7073.     return 0;
  7074. }
  7075.  
  7076. void getSecondary()
  7077. {
  7078.     char hostname[256];
  7079.     DWORD ip;
  7080.     DWORD hostExpiry = 0;
  7081.     DWORD expiry;
  7082.     char *data;
  7083.     char *dp;
  7084.     WORD rr = 0;
  7085.     data5 req;
  7086.     memset(&req, 0, sizeof(data5));
  7087.     req.addr.sin_family = AF_INET;
  7088.     req.addr.sin_port = htons(IPPORT_DNS);
  7089.  
  7090.     if (dhcpService && cfig.replication == 1)
  7091.         req.addr.sin_addr.s_addr = cfig.zoneServers[1];
  7092.     else
  7093.         return;
  7094.  
  7095.     req.sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  7096.  
  7097.     if (req.sock == INVALID_SOCKET)
  7098.         return;
  7099.  
  7100.     req.sockLen = sizeof(req.addr);
  7101.     time_t t = time(NULL);
  7102.  
  7103.     if (connect(req.sock, (sockaddr*)&req.addr, req.sockLen) >= 0)
  7104.     {
  7105.         req.data = req.raw;
  7106.         req.data += 2;
  7107.         req.dnsp = (dnsPacket*)req.data;
  7108.         req.dnsp->header.qdcount = htons(1);
  7109.         req.dnsp->header.xid = (t % USHRT_MAX);
  7110.         req.data = &req.dnsp->data;
  7111.         req.data += pQu(req.data, cfig.authority);
  7112.         req.data += pUShort(req.data, DNS_TYPE_AXFR);
  7113.         req.data += pUShort(req.data, DNS_CLASS_IN);
  7114.         req.bytes = (DWORD)req.data - (DWORD)req.raw;
  7115.         pUShort(req.raw, req.bytes - 2);
  7116.  
  7117.         if (send(req.sock, req.raw, req.bytes, 0) < req.bytes)
  7118.         {
  7119.             closesocket(req.sock);
  7120.             return;
  7121.         }
  7122.  
  7123.         while (true)
  7124.         {
  7125.             req.bytes = recvTcpDnsMess(req.sock, req.raw, false);
  7126.             //printf("bytes = %u\n", req.bytes);
  7127.  
  7128.             if (req.bytes < 2)
  7129.                 break;
  7130.  
  7131.             WORD pktSize = fUShort(req.raw);
  7132.  
  7133.             if ((WORD)req.bytes < pktSize + 2)
  7134.                 break;
  7135.  
  7136.             req.dnsp = (dnsPacket*)(req.raw + 2);
  7137.             req.data = &req.dnsp->data;
  7138.  
  7139.             if (!req.dnsp->header.qr || req.dnsp->header.rcode || !ntohs(req.dnsp->header.ancount))
  7140.                 break;
  7141.  
  7142.             for (int j = 1; j <= ntohs(req.dnsp->header.qdcount); j++)
  7143.             {
  7144.                 req.data += fQu(hostname, req.dnsp, req.data);
  7145.                 req.data += 4;
  7146.             }
  7147.  
  7148.             for (int i = 1; i <= ntohs(req.dnsp->header.ancount); i++)
  7149.             {
  7150.                 //char *dp = req.data;
  7151.                 req.data += fQu(hostname, req.dnsp, req.data);
  7152.                 //printf("%s\n", hostname);
  7153.                 req.qtype = fUShort(req.data);
  7154.                 req.data += 2; //type
  7155.                 req.qclass = fUShort(req.data);
  7156.                 req.data += 2; //class
  7157.                 expiry = fULong(req.data);
  7158.                 req.data += 4; //ttl
  7159.                 int zLen = fUShort(req.data);
  7160.                 req.data += 2; //datalength
  7161.                 data = req.data;
  7162.                 req.data += zLen;
  7163.  
  7164.                 switch (req.qtype)
  7165.                 {
  7166.                     case DNS_TYPE_PTR:
  7167.  
  7168.                         myLower(hostname);
  7169.                         dp = strstr(hostname, arpa);
  7170.  
  7171.                         if (dp)
  7172.                         {
  7173.                             *dp = 0;
  7174.                             ip = ntohl(my_inet_addr(hostname));
  7175.                             fQu(hostname, req.dnsp, data);
  7176.                             makeLocal(hostname);
  7177.  
  7178.                             if (dhcpService && expiry < hostExpiry)
  7179.                             {
  7180.                                 char rInd = getRangeInd(ip);
  7181.                                 int ind = getIndex(rInd, ip);
  7182.  
  7183.                                 if (expiry > LONG_MAX)
  7184.                                     expiry = LONG_MAX;
  7185.  
  7186.                                 if (ind >= 0 && cfig.dhcpRanges[rInd].dhcpEntry[ind])
  7187.                                     setLeaseExpiry(cfig.dhcpRanges[rInd].dhcpEntry[ind], expiry, false);
  7188.                                 else
  7189.                                     setLeaseExpiry(ip, 0);
  7190.  
  7191.                                 if (expiry < (DWORD)(LONG_MAX - t))
  7192.                                     expiry += t;
  7193.  
  7194.                                 addToCache(cacheInd, hostname, ip, expiry, LOCAL_A, NONE, cfig.serial1);
  7195.                                 addToCache(cacheInd, hostname, ip, expiry, NONE, LOCAL_PTR_AUTH, cfig.serial2);
  7196.                                 rr++;
  7197.                             }
  7198.                         }
  7199.                         break;
  7200.                 }
  7201.             }
  7202.         }
  7203.  
  7204.         sprintf(logBuff, "%u RRs imported from Secondary Server", rr);
  7205.         logDNSMess(logBuff, 2);
  7206.     }
  7207.     else
  7208.     {
  7209.         errno = WSAGetLastError();
  7210.         sprintf(logBuff, "Server %s, Error %u", IP2String(tempbuff, req.addr.sin_addr.s_addr), errno);
  7211.         logDNSMess(logBuff, 1);
  7212.     }
  7213.     closesocket(req.sock);
  7214. }
  7215.  
  7216. void addDHCPRange(char *iniStrPtr)
  7217. {
  7218.     DWORD rs = 0;
  7219.     DWORD re = 0;
  7220.     char name[512];
  7221.     char value[512];
  7222.     mySplit(name, value, iniStrPtr, '-');
  7223.  
  7224.     if (name[0] && value[0] && isIP(name) && isIP(value))
  7225.     {
  7226.         rs = htonl(my_inet_addr(name));
  7227.         re = htonl(my_inet_addr(value));
  7228.  
  7229.         if (rs && rs != INADDR_NONE && re && re != INADDR_NONE && rs <= re)
  7230.         {
  7231.             data13 *range;
  7232.             BYTE m = 0;
  7233.             BYTE rangeOK = 1;
  7234.             for (; m < MAX_RANGES && cfig.dhcpRanges[m].rangeStart; m++)
  7235.             {
  7236.                 range = &cfig.dhcpRanges[m];
  7237.                 if ((rs >= range->rangeStart && rs <= range->rangeEnd)
  7238.                         || (re >= range->rangeStart && re <= range->rangeEnd)
  7239.                         || (range->rangeStart >= rs && range->rangeStart <= re)
  7240.                         || (range->rangeEnd >= rs && range->rangeEnd <= re))
  7241.                 {
  7242.                     sprintf(logBuff, "Warning: DHCP Range %s overlaps with another range, ignored", iniStrPtr);
  7243.                     logMess(logBuff, 1);
  7244.                     rangeOK = 0;
  7245.                     break;
  7246.                 }
  7247.             }
  7248.  
  7249.             if (m < MAX_RANGES && rangeOK)
  7250.             {
  7251.                 cfig.dhcpSize += (re - rs + 1);
  7252.                 range = &cfig.dhcpRanges[m];
  7253.                 range->rangeStart = rs;
  7254.                 range->rangeEnd = re;
  7255.                 range->expiry = (time_t*)calloc((re - rs + 1), sizeof(time_t));
  7256.                 range->dhcpEntry = (data7**)calloc((re - rs + 1), sizeof(data7*));
  7257.  
  7258.                 if (!range->expiry || !range->dhcpEntry)
  7259.                 {
  7260.                     if (range->expiry)
  7261.                         free(range->expiry);
  7262.  
  7263.                     if (range->dhcpEntry)
  7264.                         free(range->dhcpEntry);
  7265.  
  7266.                     sprintf(logBuff, "DHCP Ranges Load, Memory Allocation Error");
  7267.                     logMess(logBuff, 1);
  7268.                     return ;
  7269.                 }
  7270.             }
  7271.         }
  7272.         else
  7273.         {
  7274.             sprintf(logBuff, "Section [RANGE_SET] Invalid DHCP range %s in ini file, ignored", iniStrPtr);
  7275.             logMess(logBuff, 1);
  7276.         }
  7277.     }
  7278.     else
  7279.     {
  7280.         sprintf(logBuff, "Section [RANGE_SET] Invalid DHCP range %s in ini file, ignored", iniStrPtr);
  7281.         logMess(logBuff, 1);
  7282.     }
  7283. }
  7284.  
  7285. void addVendClass(BYTE rangeSetInd, char *vendClass, BYTE vendClassSize)
  7286. {
  7287.     // Strip surrounding quotation marks
  7288.     if (vendClassSize>2)
  7289.     {
  7290.         if (vendClass[0]=='"')
  7291.         {
  7292.             char* secondQuotationMark = strchr(vendClass+1,'"');
  7293.             memcpy(vendClass,vendClass+1,(secondQuotationMark - vendClass - 1));
  7294.             vendClass[(secondQuotationMark - vendClass)]='\0';
  7295.             vendClassSize-=2;
  7296.         }
  7297.     }
  7298.  
  7299.     data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
  7300.  
  7301.     BYTE i = 0;
  7302.  
  7303.     for (; i <= 32 && rangeSet->vendClassSize[i]; i++);
  7304.  
  7305.     if (i >= 32 || !vendClassSize)
  7306.         return;
  7307.  
  7308.     rangeSet->vendClass[i] = (BYTE*)calloc(vendClassSize, 1);
  7309.  
  7310.     if(!rangeSet->vendClass[i])
  7311.     {
  7312.         sprintf(logBuff, "Vendor Class Load, Memory Allocation Error");
  7313.         logMess(logBuff, 1);
  7314.     }
  7315.     else
  7316.     {
  7317.         cfig.hasFilter = true;
  7318.         rangeSet->vendClassSize[i] = vendClassSize;
  7319.         memcpy(rangeSet->vendClass[i], vendClass, vendClassSize);
  7320.         //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);
  7321.     }
  7322. }
  7323.  
  7324. void addUserClass(BYTE rangeSetInd, char *userClass, BYTE userClassSize)
  7325. {
  7326.     
  7327.     // Strip surrounding quotation marks
  7328.     if (userClassSize>2)
  7329.     {
  7330.         if (userClass[0]=='"')
  7331.         {
  7332.             char* secondQuotationMark = strchr(userClass+1,'"');
  7333.             memcpy(userClass,userClass+1,(secondQuotationMark - userClass - 1));
  7334.             userClass[(secondQuotationMark - userClass)]='\0';
  7335.             userClassSize-=2;
  7336.         }
  7337.     }
  7338.  
  7339.     data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
  7340.  
  7341.     BYTE i = 0;
  7342.  
  7343.     for (; i <= 32 && rangeSet->userClassSize[i]; i++);
  7344.  
  7345.     if (i >= 32 || !userClassSize)
  7346.         return;
  7347.  
  7348.     rangeSet->userClass[i] = (BYTE*)calloc(userClassSize, 1);
  7349.  
  7350.     if(!rangeSet->userClass[i])
  7351.     {
  7352.         sprintf(logBuff, "Vendor Class Load, Memory Allocation Error");
  7353.         logMess(logBuff, 1);
  7354.     }
  7355.     else
  7356.     {
  7357.         cfig.hasFilter = true;
  7358.         rangeSet->userClassSize[i] = userClassSize;
  7359.         memcpy(rangeSet->userClass[i], userClass, userClassSize);
  7360.         //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);
  7361.     }
  7362. }
  7363.  
  7364. void addMacRange(BYTE rangeSetInd, char *macRange)
  7365. {
  7366.     if (macRange[0])
  7367.     {
  7368.         data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
  7369.  
  7370.         BYTE i = 0;
  7371.  
  7372.         for (; i <= 32 && rangeSet->macSize[i]; i++);
  7373.  
  7374.         if (i >= 32)
  7375.             return;
  7376.  
  7377.         char name[256];
  7378.         char value[256];
  7379.  
  7380.         mySplit(name, value, macRange, '-');
  7381.  
  7382.         if(!name[0] || !value[0])
  7383.         {
  7384.             sprintf(logBuff, "Section [RANGE_SET], invalid Filter_Mac_Range %s, ignored", macRange);
  7385.             logMess(logBuff, 1);
  7386.         }
  7387.         else
  7388.         {
  7389.             BYTE macSize1 = 16;
  7390.             BYTE macSize2 = 16;
  7391.             BYTE *macStart = (BYTE*)calloc(1, macSize1);
  7392.             BYTE *macEnd = (BYTE*)calloc(1, macSize2);
  7393.  
  7394.             if(!macStart || !macEnd)
  7395.             {
  7396.                 sprintf(logBuff, "DHCP Range Load, Memory Allocation Error");
  7397.                 logMess(logBuff, 1);
  7398.             }
  7399.             else if (getHexValue(macStart, name, &macSize1) || getHexValue(macEnd, value, &macSize2))
  7400.             {
  7401.                 sprintf(logBuff, "Section [RANGE_SET], Invalid character in Filter_Mac_Range %s", macRange);
  7402.                 logMess(logBuff, 1);
  7403.                 free(macStart);
  7404.                 free(macEnd);
  7405.             }
  7406.             else if (memcmp(macStart, macEnd, 16) > 0)
  7407.             {
  7408.                 sprintf(logBuff, "Section [RANGE_SET], Invalid Filter_Mac_Range %s, (higher bound specified on left), ignored", macRange);
  7409.                 logMess(logBuff, 1);
  7410.                 free(macStart);
  7411.                 free(macEnd);
  7412.             }
  7413.             else if (macSize1 != macSize2)
  7414.             {
  7415.                 sprintf(logBuff, "Section [RANGE_SET], Invalid Filter_Mac_Range %s, (start/end size mismatched), ignored", macRange);
  7416.                 logMess(logBuff, 1);
  7417.                 free(macStart);
  7418.                 free(macEnd);
  7419.             }
  7420.             else
  7421.             {
  7422.                 cfig.hasFilter = true;
  7423.                 rangeSet->macSize[i] = macSize1;
  7424.                 rangeSet->macStart[i] = macStart;
  7425.                 rangeSet->macEnd[i] = macEnd;
  7426.                 //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);
  7427.             }
  7428.         }
  7429.     }
  7430. }
  7431.  
  7432. void init(void *lparam)
  7433. {
  7434.     time_t t = time(NULL);
  7435.     char iniStr[16384];
  7436.     char name[512];
  7437.     char value[512];
  7438.  
  7439.     memset(&cfig, 0, sizeof(cfig));
  7440.     memset(&network, 0, sizeof(network));
  7441.  
  7442.     GetModuleFileName(NULL, extbuff, _MAX_PATH);
  7443.     char *fileExt = strrchr(extbuff, '.');
  7444.     *fileExt = 0;
  7445.     sprintf(leaFile, "%s.state", extbuff);
  7446.     sprintf(iniFile, "%s.ini", extbuff);
  7447.     fileExt = strrchr(extbuff, '\\');
  7448.     *fileExt = 0;
  7449.     fileExt++;
  7450.     sprintf(logFile, "%s\\logs\\%s%%Y%%m%%d.log", extbuff, fileExt);
  7451.  
  7452.     //printf("log=%s\n", logFile);
  7453.  
  7454.     if (verbatim)
  7455.     {
  7456.         cfig.dnsLogLevel = 2;
  7457.         cfig.dhcpLogLevel = 2;
  7458.         printf("%s\n\n", sVersion);
  7459.     }
  7460.     else if (getSection("LOGGING", iniStr, 1, iniFile))
  7461.     {
  7462.         cfig.dnsLogLevel = 1;
  7463.         cfig.dhcpLogLevel = 2;
  7464.         char *iniStrPtr = myGetToken(iniStr, 0);
  7465.         tempbuff[0] = 0;
  7466.  
  7467.         for (; iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  7468.         {
  7469.             mySplit(name, value, iniStrPtr, '=');
  7470.  
  7471.             if (name[0] && value[0])
  7472.             {
  7473.                 if (!strcasecmp(name, "DNSLogLevel"))
  7474.                 {
  7475.                     if (!strcasecmp(value, "None"))
  7476.                         cfig.dnsLogLevel = 0;
  7477.                     else if (!strcasecmp(value, "Errors"))
  7478.                         cfig.dnsLogLevel = 1;
  7479.                     else if (!strcasecmp(value, "All"))
  7480.                         cfig.dnsLogLevel = 2;
  7481.                     else
  7482.                         sprintf(tempbuff, "Section [LOGGING], Invalid DNSLogLevel: %s", value);
  7483.                 }
  7484.                 else if (!strcasecmp(name, "DHCPLogLevel"))
  7485.                 {
  7486.                     if (!strcasecmp(value, "None"))
  7487.                         cfig.dhcpLogLevel = 0;
  7488.                     else if (!strcasecmp(value, "Errors"))
  7489.                         cfig.dhcpLogLevel = 1;
  7490.                     else if (!strcasecmp(value, "All"))
  7491.                         cfig.dhcpLogLevel = 2;
  7492.                     else
  7493.                         sprintf(tempbuff, "Section [LOGGING], Invalid DHCPLogLevel: %s", value);
  7494.                 }
  7495.                 else
  7496.                     sprintf(tempbuff, "Section [LOGGING], Invalid Entry %s ignored", iniStrPtr);
  7497.             }
  7498.             else
  7499.                 sprintf(tempbuff, "Section [LOGGING], Invalid Entry %s ignored", iniStrPtr);
  7500.         }
  7501.     }
  7502.  
  7503.     if (/*!verbatim &&*/ (cfig.dnsLogLevel || cfig.dhcpLogLevel) && logFile[0])
  7504.     {
  7505.         tm *ttm = localtime(&t);
  7506.         loggingDay = ttm->tm_yday;
  7507.         strftime(extbuff, sizeof(extbuff), logFile, ttm);
  7508.  
  7509.         printf("opening log file %s\n",extbuff);
  7510.         cfig.logfile = fopen(extbuff, "at");
  7511.  
  7512.         if (cfig.logfile)
  7513.         {
  7514.             sprintf(logBuff, "%s Starting..", sVersion);
  7515.             logMess(logBuff, 1);
  7516.  
  7517.             if (tempbuff[0])
  7518.                 logMess(tempbuff, 0);
  7519.         } else
  7520.         {
  7521.             
  7522.         printf("failed to open log file %s\n",extbuff);
  7523.         }
  7524.     }
  7525.  
  7526.     WORD wVersionRequested = MAKEWORD(1, 1);
  7527.     WSAStartup(wVersionRequested, &cfig.wsaData);
  7528.  
  7529.     if (cfig.wsaData.wVersion != wVersionRequested)
  7530.     {
  7531.         sprintf(logBuff, "WSAStartup Error");
  7532.         logMess(logBuff, 1);
  7533.     }
  7534.  
  7535.     if (getSection("SERVICES", iniStr, 1, iniFile))
  7536.     {
  7537.         dhcpService = false;
  7538.         dnsService = false;
  7539.         char *iniStrPtr = myGetToken(iniStr, 0);
  7540.  
  7541.         for (int i = 0; i < 2 && iniStrPtr[0]; i++, iniStrPtr = myGetToken(iniStrPtr, 1))
  7542.             if (!strcasecmp(iniStrPtr, "DNS"))
  7543.                 dnsService = true;
  7544.             else if (!strcasecmp(iniStrPtr, "DHCP"))
  7545.                 dhcpService = true;
  7546.  
  7547.         if (!dhcpService && !dnsService)
  7548.         {
  7549.             dhcpService = true;
  7550.             dnsService = true;
  7551.         }
  7552.     }
  7553.  
  7554.     if (dnsService)
  7555.     {
  7556.         if (verbatim)
  7557.             printf("Starting DNS...\n");
  7558.         else
  7559.         {
  7560.             sprintf(logBuff, "Starting DNS Service");
  7561.             logDNSMess(logBuff, 1);
  7562.         }
  7563.     }
  7564.  
  7565.     if (dhcpService)
  7566.     {
  7567.         if (verbatim)
  7568.             printf("Starting DHCP...\n");
  7569.         else
  7570.         {
  7571.             sprintf(logBuff, "Starting DHCP Service");
  7572.             logDNSMess(logBuff, 1);
  7573.         }
  7574.     }
  7575.  
  7576.     cfig.lease = 360000;
  7577.     cfig.ttl = 360000;
  7578.     cfig.refresh = 3600;
  7579.     cfig.retry = 100;
  7580.     cfig.expire = 360000;
  7581.     cfig.minimum = 100;
  7582.  
  7583.     if (getSection("TIMINGS", iniStr, 1, iniFile))
  7584.     {
  7585.         char *iniStrPtr = myGetToken(iniStr, 0);
  7586.         for (; iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  7587.         {
  7588.             mySplit(name, value, iniStrPtr, '=');
  7589.             if (name[0] && value[0])
  7590.             {
  7591.                 if (atol(value) || !strcasecmp(value,"0"))
  7592.                 {
  7593.                     if (!strcasecmp(name, "Lease_Time"))
  7594.                     {
  7595.                         cfig.lease = atol(value);
  7596.  
  7597.                         if (!cfig.lease)
  7598.                             cfig.lease = ULONG_MAX;
  7599.  
  7600.                         cfig.refresh = cfig.lease / 10;
  7601.  
  7602.                         if (cfig.refresh > 36000)
  7603.                             cfig.refresh = 36000;
  7604.  
  7605.                         cfig.retry = cfig.refresh / 10;
  7606.  
  7607.                         if (ULONG_MAX/24 > cfig.lease)
  7608.                             cfig.expire = 24 * cfig.lease;
  7609.                         else
  7610.                             cfig.expire = ULONG_MAX;
  7611.  
  7612.                         cfig.minimum = cfig.retry;
  7613.                     } 
  7614.                     else if (!strcasecmp(name, "Time_to_Live")) 
  7615.                     {
  7616.                         sprintf(logBuff, "Time_to_Live %d", atol(value));
  7617.                         logMess(logBuff, 1);
  7618.                         cfig.ttl = atol(value);
  7619.  
  7620.                         if (!cfig.ttl)
  7621.                             cfig.ttl = ULONG_MAX;
  7622.                     }    
  7623.                     else if (!strcasecmp(name, "Refresh"))
  7624.                         cfig.refresh = atol(value);
  7625.                     else if (!strcasecmp(name, "Retry"))
  7626.                         cfig.retry = atol(value);
  7627.                     else if (!strcasecmp(name, "Expire"))
  7628.                         cfig.expire = atol(value);
  7629.                     else if (!strcasecmp(name, "Minimum"))
  7630.                         cfig.minimum = atol(value);
  7631.                     else if (!strcasecmp(name, "MinCacheTime"))
  7632.                         cfig.minCache = atol(value);
  7633.                     else if (!strcasecmp(name, "MaxCacheTime"))
  7634.                         cfig.maxCache = atol(value);
  7635.                     else
  7636.                     {
  7637.                         sprintf(logBuff, "Section [TIMINGS], Invalid Entry: %s ignored", name);
  7638.                         logDNSMess(logBuff, 1);
  7639.                     }
  7640.                 }
  7641.                 else
  7642.                 {
  7643.                     sprintf(logBuff, "Section [TIMINGS], Invalid value: %s ignored", value);
  7644.                     logDNSMess(logBuff, 1);
  7645.                 }
  7646.             }
  7647.             else
  7648.             {
  7649.                 sprintf(logBuff, "Section [TIMINGS], Missing value, entry %s ignored", iniStrPtr);
  7650.                 logDNSMess(logBuff, 1);
  7651.             }
  7652.         }
  7653.     }
  7654.  
  7655.     if (!cfig.refresh)
  7656.     {
  7657.         cfig.refresh = ULONG_MAX;
  7658.  
  7659.         if (!cfig.retry)
  7660.             cfig.retry = 100;
  7661.     }
  7662.     else if (!cfig.retry)
  7663.         cfig.retry = cfig.refresh / 10;
  7664.  
  7665.     if (!cfig.expire)
  7666.         cfig.expire = ULONG_MAX;
  7667.  
  7668.     if (!cfig.minimum)
  7669.         cfig.minimum = cfig.retry;
  7670.  
  7671.     if (getSection("DOMAIN-NAME", iniStr, 1, iniFile))
  7672.     {
  7673.         char *iniStrPtr = myGetToken(iniStr, 0);
  7674.         mySplit(name, value, iniStrPtr, '=');
  7675.         if (name[0] && value[0])
  7676.         {
  7677.             data15 mask;
  7678.             data15 network;
  7679.             char left[64];
  7680.  
  7681.             cfig.authority[0] = 0;
  7682.             myLower(value);
  7683.             mask.ip = 0;
  7684.             network.ip = 0;
  7685.  
  7686.             for (BYTE octateNum = 0; octateNum < 3; octateNum++)
  7687.             {
  7688.                 mySplit(left, value, value, '.');
  7689.                 if (left[0] == '0' || (atoi(left) && atoi(left) < 256))
  7690.                 {
  7691.                     for (int j = 2; j >= 0; j--)
  7692.                     {
  7693.                         network.octate[j + 1] = network.octate[j];
  7694.                         mask.octate[j + 1] = mask.octate[j];
  7695.                     }
  7696.  
  7697.                     mask.octate[0] = 255;
  7698.                     network.octate[0] = atoi(left);
  7699.                     strcat(cfig.authority, left);
  7700.                     strcat(cfig.authority, ".");
  7701.                 }
  7702.                 else
  7703.                     break;
  7704.  
  7705.                 if (!strcasecmp(value, arpa + 1))
  7706.                     break;
  7707.             }
  7708.  
  7709.             if (!strcasecmp(value, arpa + 1))
  7710.             {
  7711.                 strcat(cfig.authority, arpa + 1);
  7712.                 cfig.aLen = strlen(cfig.authority);
  7713.                 calcRangeLimits(network.ip, mask.ip, &cfig.rangeStart, &cfig.rangeEnd);
  7714.                 cfig.authorized = 1;
  7715.             }
  7716.             else
  7717.             {
  7718.                 sprintf(logBuff, "Warning: Invalid Domain Name (Part %s), ignored", cfig.authority);
  7719.                 cfig.aLen = 0;
  7720.                 cfig.authority[0] = 0;
  7721.                 logDNSMess(logBuff, 1);
  7722.             }
  7723.         }
  7724.  
  7725.         if (chkQu(name))
  7726.         {
  7727.             strcpy(cfig.zone, name);
  7728.             strcpy(cfig.zoneSmall, name);
  7729.             myLower(cfig.zoneSmall);
  7730.             cfig.zLen = strlen(cfig.zone);
  7731.         }
  7732.         else
  7733.         {
  7734.             cfig.aLen = 0;
  7735.             cfig.authority[0] = 0;
  7736.             sprintf(logBuff, "Warning: Invalid Domain Name %s, ignored", iniStrPtr);
  7737.             logDNSMess(logBuff, 1);
  7738.         }
  7739.     }
  7740.  
  7741.     getServ();
  7742.     getDServ();
  7743.  
  7744.     if (getSection("ZONE-REPLICATION", iniStr, 1, iniFile))
  7745.     {
  7746.         char *iniStrPtr = myGetToken(iniStr, 0);
  7747.         for (int i = 2; i < MAX_SERVERS && iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  7748.         {
  7749.             if (dnsService && !cfig.authorized)
  7750.             {
  7751.                 sprintf(logBuff, "Section [REPLICATION-SERVERS], Server is not authorized, entry %s ignored", iniStrPtr);
  7752.                 logMess(logBuff, 1);
  7753.                 continue;
  7754.             }
  7755.  
  7756.             mySplit(name, value, iniStrPtr, '=');
  7757.  
  7758.             if (name[0] && value[0])
  7759.             {
  7760.                 if (chkQu(name) && !isIP(name) && isIP(value))
  7761.                 {
  7762.                     if (!strcasecmp(name, "Primary"))
  7763.                         cfig.zoneServers[0] = my_inet_addr(value);
  7764.                     else if (!strcasecmp(name, "Secondary"))
  7765.                         cfig.zoneServers[1] = my_inet_addr(value);
  7766.                     else if (dnsService && !strcasecmp(name, "AXFRClient"))
  7767.                     {
  7768.                         cfig.zoneServers[i] = my_inet_addr(value);
  7769.                         i++;
  7770.                     }
  7771.                     else
  7772.                     {
  7773.                         sprintf(logBuff, "Section [REPLICATION-SERVERS] Invalid Entry: %s ignored", iniStrPtr);
  7774.                         logMess(logBuff, 1);
  7775.                     }
  7776.                 }
  7777.                 else
  7778.                 {
  7779.                     sprintf(logBuff, "Section [REPLICATION-SERVERS] Invalid Entry: %s ignored", iniStrPtr);
  7780.                     logMess(logBuff, 1);
  7781.                 }
  7782.             }
  7783.             else
  7784.             {
  7785.                 sprintf(logBuff, "Section [REPLICATION-SERVERS], Missing value, entry %s ignored", iniStrPtr);
  7786.                 logMess(logBuff, 1);
  7787.             }
  7788.         }
  7789.     }
  7790.  
  7791.     if (!cfig.zoneServers[0] && cfig.zoneServers[1])
  7792.     {
  7793.         sprintf(logBuff, "Section [REPLICATION-SERVERS] Missing Primary Server");
  7794.         logMess(logBuff, 1);
  7795.     }
  7796.     else if (cfig.zoneServers[0] && !cfig.zoneServers[1])
  7797.     {
  7798.         sprintf(logBuff, "Section [REPLICATION-SERVERS] Missing Secondary Server");
  7799.         logMess(logBuff, 1);
  7800.     }
  7801.     else if (cfig.zoneServers[0] && cfig.zoneServers[1])
  7802.     {
  7803.         if (findServer(network.staticServers, cfig.zoneServers[0]) && findServer(network.staticServers, cfig.zoneServers[1]))
  7804.         {
  7805.             sprintf(logBuff, "Section [REPLICATION-SERVERS] Primary & Secondary should be Different Boxes");
  7806.             logMess(logBuff, 1);
  7807.         }
  7808.         else if (findServer(network.staticServers, cfig.zoneServers[0]))
  7809.             cfig.replication = 1;
  7810.         else if (findServer(network.staticServers, cfig.zoneServers[1]))
  7811.             cfig.replication = 2;
  7812.         else
  7813.         {
  7814.             sprintf(logBuff, "Section [REPLICATION-SERVERS] No Server IP not found on this Machine");
  7815.             logMess(logBuff, 1);
  7816.         }
  7817.     }
  7818.  
  7819.     if (dhcpService)
  7820.     {
  7821.         if (getSection("DHCP-OPTIONS", iniStr, 1, iniFile))
  7822.         {
  7823.             data20 optionData;
  7824.             loadOptions(iniStr, "DHCP-OPTIONS", &optionData);
  7825.             cfig.options = optionData.options;
  7826.             cfig.mask = optionData.mask;
  7827.         }
  7828.  
  7829.         for (BYTE i = 1; i <= MAX_RANGES ; i++)
  7830.         {
  7831.             if (getSection("DHCP-RANGE", iniStr, i, iniFile))
  7832.             {
  7833.                 BYTE m = 0;
  7834.                 for (; m < MAX_RANGES && cfig.dhcpRanges[m].rangeStart; m++);
  7835.  
  7836.                 data20 optionData;
  7837.                 optionData.rangeSetInd = i - 1;
  7838.                 loadOptions(iniStr, "DHCP-RANGE", &optionData);
  7839.                 cfig.rangeSet[optionData.rangeSetInd].active = true;
  7840.  
  7841.                 for (; m < MAX_RANGES && cfig.dhcpRanges[m].rangeStart; m++)
  7842.                 {
  7843.                     //printf("Range Start=%s rangeSetInd=%i\n", IP2String(tempbuff, htonl(cfig.dhcpRanges[m].rangeStart)), optionData.rangeSetInd);
  7844.                     cfig.dhcpRanges[m].rangeSetInd = optionData.rangeSetInd;
  7845.                     cfig.dhcpRanges[m].options = optionData.options;
  7846.                     cfig.dhcpRanges[m].mask = optionData.mask;
  7847.                 }
  7848.             }
  7849.             else
  7850.                 break;
  7851.         }
  7852.  
  7853.         //printf("%s\n", IP2String(tempbuff, cfig.mask));
  7854.  
  7855.         if (!cfig.mask)
  7856.             cfig.mask = my_inet_addr("255.255.255.0");
  7857.  
  7858.         for (char rangeInd = 0; rangeInd < MAX_RANGES && cfig.dhcpRanges[rangeInd].rangeStart; rangeInd++)
  7859.         {
  7860.             if (!cfig.dhcpRanges[rangeInd].mask)
  7861.                 cfig.dhcpRanges[rangeInd].mask = cfig.mask;
  7862.  
  7863.             for (DWORD iip = cfig.dhcpRanges[rangeInd].rangeStart; iip <= cfig.dhcpRanges[rangeInd].rangeEnd; iip++)
  7864.             {
  7865.                 DWORD ip = htonl(iip);
  7866.  
  7867.                 if ((cfig.dhcpRanges[rangeInd].mask | (~ip)) == ULONG_MAX || (cfig.dhcpRanges[rangeInd].mask | ip) == ULONG_MAX)
  7868.                     cfig.dhcpRanges[rangeInd].expiry[iip - cfig.dhcpRanges[rangeInd].rangeStart] = LONG_MAX;
  7869.             }
  7870.         }
  7871.  
  7872.         for (BYTE m = 0; m < MAX_SERVERS && network.allServers[m]; m++)
  7873.             setLeaseExpiry(network.allServers[m], LONG_MAX);
  7874.  
  7875.         for (BYTE m = 0; m < MAX_SERVERS && network.dns[m]; m++)
  7876.             setLeaseExpiry(network.dns[m], LONG_MAX);
  7877.  
  7878.         if (getSection("DHCP-OPTIONS", iniStr, 1, iniFile))
  7879.             lockOptions(iniStr);
  7880.  
  7881.         for (BYTE i = 1; i <= 32 ;i++)
  7882.         {
  7883.             if (getSection("DHCP-RANGE", iniStr, i, iniFile))
  7884.                 lockOptions(iniStr);
  7885.         }
  7886.  
  7887.         FILE *f = fopen(iniFile, "rt");
  7888.  
  7889.         if (f)
  7890.         {
  7891.             char sectionName[512];
  7892.  
  7893.             while (fgets(sectionName, 511, f))
  7894.             {
  7895.                 if (*sectionName == '[')
  7896.                 {
  7897.                     char *secend = strchr(sectionName, ']');
  7898.  
  7899.                     if (secend)
  7900.                     {
  7901.                         *secend = 0;
  7902.                         sectionName[0] = 32;
  7903.                         myTrim(sectionName, sectionName);
  7904.                     }
  7905.                     else
  7906.                         continue;
  7907.                 }
  7908.                 else
  7909.                     continue;
  7910.  
  7911.  
  7912.                 BYTE hexValue[255];
  7913.                 BYTE hexValueSize = sizeof(hexValue);
  7914.                 data20 optionData;
  7915.  
  7916.                 if (!getHexValue(hexValue, sectionName, &hexValueSize))
  7917.                 {
  7918.                     data7 *dhcpEntry = dhcpCache[toUUE(tempbuff, hexValue, hexValueSize)];
  7919.  
  7920.                     if (!dhcpEntry)
  7921.                     {
  7922.                         getSection(sectionName, iniStr, 1, iniFile);
  7923.                         loadOptions(iniStr, sectionName, &optionData);
  7924.                         lockOptions(iniStr);
  7925.  
  7926.                         if (optionData.ip)
  7927.                         {
  7928.                             dhcpMap::iterator p = dhcpCache.begin();
  7929.  
  7930.                             for (; p != dhcpCache.end(); p++)
  7931.                             {
  7932.                                 if (p->second && p->second->ip == optionData.ip)
  7933.                                     break;
  7934.                             }
  7935.  
  7936.                             if (p == dhcpCache.end())
  7937.                             {
  7938.                                 dhcpEntry = (data7*)calloc(1, sizeof(data7));
  7939.  
  7940.                                 if (!dhcpEntry)
  7941.                                 {
  7942.                                     sprintf(logBuff, "Client Options Load, Memory Allocation Error");
  7943.                                     logMess(logBuff, 1);
  7944.                                     return;
  7945.                                 }
  7946.  
  7947.                                 dhcpEntry->mapname = cloneString(toUUE(tempbuff, hexValue, hexValueSize));
  7948.  
  7949.                                 if (!dhcpEntry->mapname)
  7950.                                 {
  7951.                                     sprintf(logBuff, "Client Data Load, Memory Allocation Error");
  7952.                                     logMess(logBuff, 1);
  7953.                                     return;
  7954.                                 }
  7955.  
  7956.                                 DWORD tmask = htonl(optionData.mask);
  7957.                                 while (tmask)
  7958.                                 {
  7959.                                     (dhcpEntry->bitmask)++;
  7960.                                     tmask = tmask << 1;
  7961.                                 }
  7962.  
  7963.                                 dhcpEntry->ip = optionData.ip;
  7964.                                 dhcpEntry->options = optionData.options;
  7965.                                 dhcpEntry->rangeInd = getRangeInd(optionData.ip);
  7966.                                 dhcpEntry->fixed = 1;
  7967.                                 setLeaseExpiry(optionData.ip, LONG_MAX);
  7968.                                 dhcpCache[dhcpEntry->mapname] = dhcpEntry;
  7969.                                 //printf("%s=%s=%s\n", sectionName, dhcpEntry->mapname, IP2String(tempbuff, optionData.ip));
  7970.                             }
  7971.                             else
  7972.                             {
  7973.                                 sprintf(logBuff, "Static DHCP Host [%s] Duplicate IP Address %s, Entry ignored", sectionName, IP2String(tempbuff, optionData.ip));
  7974.                                 logMess(logBuff, 1);
  7975.                             }
  7976.                         }
  7977.                         else
  7978.                         {
  7979.                             sprintf(logBuff, "IP Address is missing in Static DHCP Host [%s], Entry ignored", sectionName);
  7980.                             logMess(logBuff, 1);
  7981.                         }
  7982.                     }
  7983.                     else
  7984.                     {
  7985.                         sprintf(logBuff, "Duplicate Static DHCP Host [%s] ignored", sectionName);
  7986.                         logMess(logBuff, 1);
  7987.                     }
  7988.                 }
  7989.                 else if (strchr(sectionName, ':'))
  7990.                 {
  7991.                     sprintf(logBuff, "Invalid Static DHCP Host MAC Addr [%s] ignored", sectionName);
  7992.                     logMess(logBuff, 1);
  7993.                 }
  7994.             }
  7995.  
  7996.             fclose(f);
  7997.         }
  7998.  
  7999.         f = fopen(leaFile, "rb");
  8000.  
  8001.         if (f)
  8002.         {
  8003.             data8 dhcpData;
  8004.  
  8005.             while (fread(&dhcpData, sizeof(data8), 1, f))
  8006.             {
  8007.                 char rangeInd = -1;
  8008.                 int ind = -1;
  8009.  
  8010.                 if (!findServer(network.staticServers, dhcpData.ip) && !findServer(network.dns, dhcpData.ip))
  8011.                 {
  8012.                     data7 *dhcpEntry = dhcpCache[toUUE(tempbuff, dhcpData.bp_chaddr, dhcpData.bp_hlen)];
  8013.  
  8014.                     if (dhcpEntry)
  8015.                     {
  8016.                         if (dhcpEntry->ip != dhcpData.ip)
  8017.                             continue;
  8018.                     }
  8019.                     else
  8020.                     {
  8021.                         dhcpMap::iterator p = dhcpCache.begin();
  8022.  
  8023.                         for (; p != dhcpCache.end(); p++)
  8024.                         {
  8025.                             if (p->second && p->second->ip == dhcpData.ip)
  8026.                                 break;
  8027.                         }
  8028.  
  8029.                         if (p != dhcpCache.end())
  8030.                         {
  8031.                             if (p->second->fixed || p->second->expiry > dhcpData.expiry)
  8032.                                 continue;
  8033.                             else
  8034.                                 dhcpCache.erase(p);
  8035.                         }
  8036.                     }
  8037.  
  8038.                     rangeInd = getRangeInd(dhcpData.ip);
  8039.  
  8040.                     if(rangeInd >= 0)
  8041.                     {
  8042.                         ind = getIndex(rangeInd, dhcpData.ip);
  8043.  
  8044.                         if (ind >= 0 && !dhcpEntry)
  8045.                         {
  8046.                             dhcpEntry = (data7*)calloc(1, sizeof(data7));
  8047.  
  8048.                             if (!dhcpEntry)
  8049.                             {
  8050.                                 sprintf(logBuff, "Loading Existing Leases, Memory Allocation Error");
  8051.                                 logDHCPMess(logBuff, 1);
  8052.                                 return;
  8053.                             }
  8054.  
  8055.                             dhcpEntry->mapname = cloneString(toUUE(tempbuff, dhcpData.bp_chaddr, dhcpData.bp_hlen));
  8056.  
  8057.                             if (!dhcpEntry->mapname)
  8058.                             {
  8059.                                 sprintf(logBuff, "Loading Existing Leases, Memory Allocation Error");
  8060.                                 free(dhcpEntry);
  8061.                                 logDHCPMess(logBuff, 1);
  8062.                                 return ;
  8063.                             }
  8064.  
  8065.                             //dhcpEntry->dataType = DHCP;
  8066.                             dhcpCache[dhcpEntry->mapname] = dhcpEntry;
  8067.                         }
  8068.                     }
  8069.  
  8070.                     if (dhcpEntry)
  8071.                     {
  8072.                         dhcpEntry->ip = dhcpData.ip;
  8073.                         dhcpEntry->rangeInd = rangeInd;
  8074.  
  8075.                         if (!dhcpEntry->fixed)
  8076.                             dhcpEntry->source = dhcpData.source;
  8077.  
  8078.                         if (dhcpData.expiry > t)
  8079.                         {
  8080.                             setLeaseExpiry(dhcpEntry, dhcpData.expiry - t, dhcpData.local);
  8081.  
  8082.                             addToCache(cacheInd, dhcpData.hostname, dhcpEntry->ip, dhcpData.expiry, LOCAL_A, NONE, cfig.serial1);
  8083.  
  8084.                             if (makeLocal(dhcpEntry->ip))
  8085.                                 addToCache(cacheInd, dhcpData.hostname, dhcpEntry->ip, dhcpData.expiry, NONE, LOCAL_PTR_AUTH, cfig.serial2);
  8086.                             else
  8087.                                 addToCache(cacheInd, dhcpData.hostname, dhcpEntry->ip, dhcpData.expiry, NONE, LOCAL_PTR_NAUTH, cfig.serial2);
  8088.                         }
  8089.                         else
  8090.                             setLeaseExpiry(dhcpEntry, 0, false);
  8091.                     }
  8092.                 }
  8093.             }
  8094.  
  8095.             fclose(f);
  8096.  
  8097.             f = fopen(leaFile, "wb");
  8098.             cfig.dhcpIndex = 0;
  8099.  
  8100.             if (f)
  8101.             {
  8102.                 dhcpMap::iterator p = dhcpCache.begin();
  8103.  
  8104.                 for (; p != dhcpCache.end(); p++)
  8105.                 {
  8106.                     if (p->second && p->second->expiry)
  8107.                     {
  8108.                         memset(&dhcpData, 0, sizeof(data8));
  8109.                         dhcpData.bp_hlen = fromUUE(dhcpData.bp_chaddr, p->second->mapname);
  8110.                         dhcpData.ip = p->second->ip;
  8111.                         dhcpData.expiry = p->second->expiry;
  8112.                         dhcpData.local = p->second->local;
  8113.  
  8114.                         if (!p->second->fixed)
  8115.                             dhcpData.source = p->second->source;
  8116.  
  8117.                         data7 *cache = findEntry(cacheInd, IP2String(tempbuff, htonl(p->second->ip)));
  8118.  
  8119.                         if (cache && cache->hostname)
  8120.                             strcpy(dhcpData.hostname, cache->hostname);
  8121.  
  8122.                         cfig.dhcpIndex++;
  8123.                         dhcpData.dhcpInd = cfig.dhcpIndex;
  8124.                         p->second->dhcpInd = cfig.dhcpIndex;
  8125.  
  8126.                         fwrite(&dhcpData, sizeof(data8), 1, f);
  8127.                     }
  8128.                 }
  8129.                 fclose(f);
  8130.             }
  8131.         }
  8132.  
  8133.         fEvent = CreateEvent(
  8134.             NULL,                  // default security descriptor
  8135.             FALSE,                 // ManualReset
  8136.             TRUE,                  // Signalled
  8137.             TEXT("AchalDualServerFileEvent"));  // object name
  8138.  
  8139.         SetEvent(fEvent);
  8140.  
  8141.         for (int i = 0; i < MAX_RANGES && cfig.dhcpRanges[i].rangeStart;i++)
  8142.         {
  8143.             char *logPtr = logBuff;
  8144.             logPtr += sprintf(logPtr, "DHCP Range: ");
  8145.             logPtr += sprintf(logPtr, "%s", IP2String(tempbuff, htonl(cfig.dhcpRanges[i].rangeStart)));
  8146.             logPtr += sprintf(logPtr, "-%s", IP2String(tempbuff, htonl(cfig.dhcpRanges[i].rangeEnd)));
  8147.             logPtr += sprintf(logPtr, "/%s", IP2String(tempbuff, cfig.dhcpRanges[i].mask));
  8148.             logDHCPMess(logBuff, 1);
  8149.         }
  8150.  
  8151.         if (cfig.lease >= LONG_MAX)
  8152.             sprintf(logBuff, "Max Lease: Infinity");
  8153.         else
  8154.             sprintf(logBuff, "Max Lease: %u (sec)", cfig.lease);
  8155.  
  8156.         logDHCPMess(logBuff, 1);
  8157.     }
  8158.  
  8159.     if (dnsService)
  8160.     {
  8161.         addToCache(0, "localhost", my_inet_addr("127.0.0.1"), LONG_MAX, LOCALHOST_A, LOCALHOST_PTR, LONG_MAX);
  8162.         addToCache(1, "localhost", my_inet_addr("127.0.0.1"), LONG_MAX, LOCALHOST_A, LOCALHOST_PTR, LONG_MAX);
  8163.  
  8164.         for (int i = 0; cfig.replication != 2 && i < MAX_SERVERS && network.allServers[i]; i++)
  8165.             if (cfig.authorized && makeLocal(network.allServers[i]))
  8166.             {
  8167.                 addToCache(0, cfig.servername, network.allServers[i], LONG_MAX, SERVER_A, SERVER_PTR_AUTH, LONG_MAX);
  8168.                 addToCache(1, cfig.servername, network.allServers[i], LONG_MAX, SERVER_A, SERVER_PTR_AUTH, LONG_MAX);
  8169.             }
  8170.             else
  8171.             {
  8172.                 addToCache(0, cfig.servername, network.allServers[i], LONG_MAX, SERVER_A, SERVER_PTR_NAUTH, LONG_MAX);
  8173.                 addToCache(1, cfig.servername, network.allServers[i], LONG_MAX, SERVER_A, SERVER_PTR_NAUTH, LONG_MAX);
  8174.             }
  8175.  
  8176.         if (getSection("DNS-ALLOWED-HOSTS", iniStr, 1, iniFile))
  8177.         {
  8178.             char *iniStrPtr = myGetToken(iniStr, 0);
  8179.             for (int i = 0; i < 32 && iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  8180.             {
  8181.                 DWORD rs = 0;
  8182.                 DWORD re = 0;
  8183.                 mySplit(name, value, iniStrPtr, '-');
  8184.  
  8185.                 if (value[0] && isIP(value))
  8186.                 {
  8187.                     rs = htonl(my_inet_addr(name));
  8188.                     re = htonl(my_inet_addr(value));
  8189.                 }
  8190.                 else
  8191.                 {
  8192.                     rs = htonl(my_inet_addr(name));
  8193.                     re = rs;
  8194.                 }
  8195.  
  8196.                 //printf("%u=%u\n", rs, re);
  8197.  
  8198.                 if (rs && rs != INADDR_NONE && re && re != INADDR_NONE && rs <= re)
  8199.                 {
  8200.                     cfig.dnsRanges[i].rangeStart = rs;
  8201.                     cfig.dnsRanges[i].rangeEnd = re;
  8202.                     i++;
  8203.                 }
  8204.                 else
  8205.                 {
  8206.                     sprintf(logBuff, "Section [DNS-ALLOWED-HOSTS] Invalid entry %s in ini file, ignored", iniStrPtr);
  8207.                     logDNSMess(logBuff, 1);
  8208.                 }
  8209.             }
  8210.         }
  8211.  
  8212.         if (cfig.replication != 2 && getSection("HOSTS", iniStr, 1, iniFile))
  8213.         {
  8214.             char *iniStrPtr = myGetToken(iniStr, 0);
  8215.             for (; iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  8216.             {
  8217.                 mySplit(name, value, iniStrPtr, '=');
  8218.                 if (name[0] && value[0])
  8219.                 {
  8220.                     if (chkQu(name) && !isIP(name) && isIP(value))
  8221.                     {
  8222.                         DWORD inetAddr = my_inet_addr(value);
  8223.  
  8224.                          if (!inetAddr)
  8225.                         {
  8226.                             sprintf(logBuff, "Section [HOSTS] Invalid Entry: %s ignored", iniStrPtr);
  8227.                             logDNSMess(logBuff, 1);
  8228.                         }
  8229.                         else if (cfig.authorized && makeLocal(name) && makeLocal(inetAddr))
  8230.                         {
  8231.                             addToCache(cacheInd, name, inetAddr, LONG_MAX, STATIC_A_AUTH, STATIC_PTR_AUTH, cfig.serial1);
  8232.                             setLeaseExpiry(inetAddr, 0);
  8233.                         }
  8234.                         else if (cfig.authorized && makeLocal(name))
  8235.                         {
  8236.                             addToCache(cacheInd, name, inetAddr, LONG_MAX, STATIC_A_AUTH, STATIC_PTR_NAUTH, cfig.serial1);
  8237.                             setLeaseExpiry(inetAddr, 0);
  8238.                         }
  8239.                         else if (cfig.authorized && makeLocal(inetAddr))
  8240.                         {
  8241.                             addToCache(cacheInd, name, inetAddr, LONG_MAX, STATIC_A_NAUTH, STATIC_PTR_AUTH, cfig.serial1);
  8242.                             setLeaseExpiry(inetAddr, 0);
  8243.                         }
  8244.                         else
  8245.                         {
  8246.                             makeLocal(name);
  8247.                             addToCache(cacheInd, name, inetAddr, LONG_MAX, STATIC_A_NAUTH, STATIC_PTR_NAUTH, cfig.serial1);
  8248.                             setLeaseExpiry(inetAddr, 0);
  8249.                         }
  8250.                     }
  8251.                     else
  8252.                     {
  8253.                         sprintf(logBuff, "Section [HOSTS] Invalid Entry: %s ignored", iniStrPtr);
  8254.                         logDNSMess(logBuff, 1);
  8255.                     }
  8256.                 }
  8257.                 else
  8258.                 {
  8259.                     sprintf(logBuff, "Section [HOSTS], Missing value, entry %s ignored", iniStrPtr);
  8260.                     logDNSMess(logBuff, 1);
  8261.                 }
  8262.             }
  8263.         }
  8264.  
  8265.         if (cfig.replication != 2 && getSection("ALIASES", iniStr, 1, iniFile))
  8266.         {
  8267.             char *iniStrPtr = myGetToken(iniStr, 0);
  8268.             for (int i = 0; iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  8269.             {
  8270.                 mySplit(name, value, iniStrPtr, '=');
  8271.                 if (name[0] && value[0])
  8272.                 {
  8273.                     if (chkQu(name) && chkQu(value))
  8274.                     {
  8275.                         if (makeLocal(name))
  8276.                         {
  8277.                             data7 *cache = findEntry(cacheInd, name);
  8278.  
  8279.                             if (!cache)
  8280.                             {
  8281.                                 cache = (data7*)calloc(1, sizeof(data7));
  8282.                                 if (cache)
  8283.                                 {
  8284.                                     if (!makeLocal(value))
  8285.                                         cache->dataType = EXT_CNAME;
  8286.                                     else
  8287.                                         cache->dataType = LOCAL_CNAME;
  8288.  
  8289.                                     mySplit(name, value, iniStrPtr, '=');
  8290.                                     makeLocal(name);
  8291.                                     cache->mapname = cloneString(name);
  8292.                                     cache->hostname = cloneString(value);
  8293.  
  8294.                                     if (!cache->mapname || !cache->hostname)
  8295.                                     {
  8296.                                         sprintf(logBuff, "Section [ALIASES] entry %s memory error", iniStrPtr);
  8297.                                         logDNSMess(logBuff, 1);
  8298.                                     }
  8299.                                     else
  8300.                                     {
  8301.                                         cache->expiry = LONG_MAX;
  8302.                                         cache->serial = cfig.serial1;
  8303.                                         addEntry(cacheInd, cache);
  8304.                                         i++;
  8305.                                     }
  8306.                                 }
  8307.                                 else
  8308.                                 {
  8309.                                     sprintf(logBuff, "Section [ALIASES] entry %s memory error", iniStrPtr);
  8310.                                     logDNSMess(logBuff, 1);
  8311.                                 }
  8312.                             }
  8313.                             else
  8314.                             {
  8315.                                 sprintf(logBuff, "Section [ALIASES] duplicate entry %s ignored", iniStrPtr);
  8316.                                 logDNSMess(logBuff, 1);
  8317.                             }
  8318.                         }
  8319.                         else
  8320.                         {
  8321.                             sprintf(logBuff, "Section [ALIASES] alias %s should be bare/local name, entry ignored", name);
  8322.                             logDNSMess(logBuff, 1);
  8323.                         }
  8324.                     }
  8325.                     else
  8326.                     {
  8327.                         sprintf(logBuff, "Section [ALIASES] Invalid Entry: %s ignored", iniStrPtr);
  8328.                         logDNSMess(logBuff, 1);
  8329.                     }
  8330.                 }
  8331.                 else
  8332.                 {
  8333.                     sprintf(logBuff, "Section [ALIASES], Missing value, entry %s ignored", iniStrPtr);
  8334.                     logDNSMess(logBuff, 1);
  8335.                 }
  8336.             }
  8337.         }
  8338.  
  8339.         if (cfig.replication != 2 && getSection("MAIL-SERVERS", iniStr, 1, iniFile))
  8340.         {
  8341.             char *iniStrPtr = myGetToken(iniStr, 0);
  8342.  
  8343.             for (cfig.mxCount[cacheInd] = 0; cfig.mxCount[cacheInd] < MAX_SERVERS && iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  8344.             {
  8345.                 mySplit(name, value, iniStrPtr, '=');
  8346.                 if (name[0] && value[0])
  8347.                 {
  8348.                     if (chkQu(name) && atoi(value))
  8349.                     {
  8350.                         cfig.mxServers[0][cfig.mxCount[cacheInd]].pref = atoi(value);
  8351.                         cfig.mxServers[1][cfig.mxCount[cacheInd]].pref = atoi(value);
  8352.                         if (!strchr(name, '.'))
  8353.                         {
  8354.                             strcat(name, ".");
  8355.                             strcat(name, cfig.zone);
  8356.                         }
  8357.                         strcpy(cfig.mxServers[0][cfig.mxCount[cacheInd]].hostname, name);
  8358.                         strcpy(cfig.mxServers[1][cfig.mxCount[cacheInd]].hostname, name);
  8359.                         cfig.mxCount[cacheInd]++;
  8360.                     }
  8361.                     else
  8362.                     {
  8363.                         sprintf(logBuff, "Section [MAIL-SERVERS] Invalid Entry: %s ignored", iniStrPtr);
  8364.                         logDNSMess(logBuff, 1);
  8365.                     }
  8366.                 }
  8367.                 else
  8368.                 {
  8369.                     sprintf(logBuff, "Section [MAIL-SERVERS], Missing value, entry %s ignored", iniStrPtr);
  8370.                     logDNSMess(logBuff, 1);
  8371.                 }
  8372.             }
  8373.             cfig.mxCount[1] = cfig.mxCount[0];
  8374.         }
  8375.  
  8376.         if (getSection("CHILD-ZONES", iniStr, 1, iniFile))
  8377.         {
  8378.             char *iniStrPtr = myGetToken(iniStr, 0);
  8379.  
  8380.             for (int i = 0; i < 32 && iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  8381.             {
  8382.                 mySplit(name, value, iniStrPtr, '=');
  8383.                 if (name[0] && value[0])
  8384.                 {
  8385. /*
  8386.                     if (cfig.authorized)
  8387.                     {
  8388.                         char *dp = strstr(name, arpa);
  8389.  
  8390.                         if (dp)
  8391.                         {
  8392.                             dp = strchr(name, '.');
  8393.                             if (!dp || strcasecmp(dp + 1, cfig.authority))
  8394.                             {
  8395.                                 sprintf(logBuff, "Section [CHILD-ZONES], Zone %s is not child of %s, Entry ignored", name, cfig.authority);
  8396.                                 logDNSMess(logBuff, 1);
  8397.                                 continue;
  8398.                             }
  8399.                         }
  8400.                         else
  8401.                         {
  8402.                             dp = strchr(name, '.');
  8403.                             if (!dp || strcasecmp(dp + 1, cfig.zone))
  8404.                             {
  8405.                                 sprintf(logBuff, "Section [CHILD-ZONES], Zone %s is not child of %s, Entry ignored", name, cfig.zone);
  8406.                                 logDNSMess(logBuff, 1);
  8407.                                 continue;
  8408.                             }
  8409.                         }
  8410.                     }
  8411. */
  8412.                     int j = 0;
  8413.                     for (; j < 32 && cfig.dnsRoutes[j].zone[0]; j++)
  8414.                     {
  8415.                         if (!strcasecmp(cfig.dnsRoutes[j].zone, name))
  8416.                         {
  8417.                             sprintf(logBuff, "Section [CHILD-ZONES], Duplicate Entry for Child Zone %s ignored", name);
  8418.                             logDNSMess(logBuff, 1);
  8419.                             break;
  8420.                         }
  8421.                     }
  8422.  
  8423.                     if (j < 32 && !cfig.dnsRoutes[j].zone[0])
  8424.                     {
  8425.                         if (name[0] && chkQu(name) && value[0])
  8426.                         {
  8427.                             char *value1 = strchr(value, ',');
  8428.                             if (value1)
  8429.                             {
  8430.                                 *value1 = 0;
  8431.                                 value1++;
  8432.  
  8433.                                 DWORD ip = my_inet_addr(myTrim(value, value));
  8434.                                 DWORD ip1 = my_inet_addr(myTrim(value1, value1));
  8435.  
  8436.                                 if (isIP(value) && ip && isIP(value1) && ip1)
  8437.                                 {
  8438.                                     strcpy(cfig.dnsRoutes[i].zone, name);
  8439.                                     cfig.dnsRoutes[i].zLen = strlen(cfig.dnsRoutes[i].zone);
  8440.                                     cfig.dnsRoutes[i].dns[0] = ip;
  8441.                                     cfig.dnsRoutes[i].dns[1] = ip1;
  8442.                                     i++;
  8443.                                 }
  8444.                                 else
  8445.                                 {
  8446.                                     sprintf(logBuff, "Section [CHILD-ZONES] Invalid Entry: %s ignored", iniStrPtr);
  8447.                                     logDNSMess(logBuff, 1);
  8448.                                 }
  8449.                             }
  8450.                             else
  8451.                             {
  8452.                                 DWORD ip = my_inet_addr(value);
  8453.                                 if (isIP(value) && ip)
  8454.                                 {
  8455.                                     strcpy(cfig.dnsRoutes[i].zone, name);
  8456.                                     cfig.dnsRoutes[i].zLen = strlen(cfig.dnsRoutes[i].zone);
  8457.                                     cfig.dnsRoutes[i].dns[0] = ip;
  8458.                                     i++;
  8459.                                 }
  8460.                                 else
  8461.                                 {
  8462.                                     sprintf(logBuff, "Section [CHILD-ZONES] Invalid Entry: %s ignored", iniStrPtr);
  8463.                                     logDNSMess(logBuff, 1);
  8464.                                 }
  8465.                             }
  8466.                         }
  8467.                         else
  8468.                         {
  8469.                             sprintf(logBuff, "Section [CHILD-ZONES] Invalid Entry: %s ignored", iniStrPtr);
  8470.                             logDNSMess(logBuff, 1);
  8471.                         }
  8472.                     }
  8473.                 }
  8474.                 else
  8475.                 {
  8476.                     sprintf(logBuff, "Section [CHILD-ZONES], Missing value, entry %s ignored", iniStrPtr);
  8477.                     logDNSMess(logBuff, 1);
  8478.                 }
  8479.             }
  8480.         }
  8481.  
  8482.         if (getSection("WILD-HOSTS", iniStr, 1, iniFile))
  8483.         {
  8484.             char *iniStrPtr = myGetToken(iniStr, 0);
  8485.             for (int i = 0; i < 32 && iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  8486.             {
  8487.                 mySplit(name, value, iniStrPtr, '=');
  8488.                 if (name[0] && value[0])
  8489.                 {
  8490.                     if (chkQu(name) && isIP(value))
  8491.                     {
  8492.                         DWORD ip = my_inet_addr(value);
  8493.                         strcpy(cfig.wildHosts[i].wildcard, name);
  8494.                         myLower(cfig.wildHosts[i].wildcard);
  8495.                         cfig.wildHosts[i].ip = ip;
  8496.                         i++;
  8497.                     }
  8498.                     else
  8499.                     {
  8500.                         sprintf(logBuff, "Section [WILD-HOSTS] Invalid Entry: %s ignored", iniStrPtr);
  8501.                         logDNSMess(logBuff, 1);
  8502.                     }
  8503.                 }
  8504.                 else
  8505.                 {
  8506.                     sprintf(logBuff, "Section [WILD-HOSTS], Missing value, entry %s ignored", iniStrPtr);
  8507.                     logDNSMess(logBuff, 1);
  8508.                 }
  8509.             }
  8510.         }
  8511.  
  8512.         if (getSection("NXDOMAIN", iniStr, 1, iniFile))
  8513.         {
  8514.             char *iniStrPtr = myGetToken(iniStr, 0);    //-- read a line in 
  8515.             for (int i = 0; i < 32 && iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  8516.             {
  8517.                 mySplit(name, value, iniStrPtr, '=');        //-- parse it
  8518.  
  8519.                 if (name[0]) {
  8520.                     // If DEFAULT_IP is named and there is an ip value in value
  8521.                     if (!strcmp(name, "DEFAULT_IP") && value[0] && isIP(value))
  8522.                     {
  8523.                             sprintf(logBuff, "Section [NXDOMAIN] setting default ip ");
  8524.                             logDNSMess(logBuff, 1);
  8525.                         cfig.defaultIP = my_inet_addr(value);
  8526.                     }
  8527.                     // If this is just a name and its an ip
  8528.                     else if (!value[0] && isIP(name))
  8529.                     {                    
  8530.                         BYTE i = 0;
  8531.  
  8532.                         for (; i <= 32 && cfig.nxdBlacklist[i]; i++);
  8533.  
  8534.                         if (i < 32)
  8535.                         {
  8536.                             sprintf(logBuff, "Section [NXDOMAIN] adding blacklist ip at %d ",i);
  8537.                             logDNSMess(logBuff, 1);
  8538.                             cfig.nxdBlacklist[i]=my_inet_addr(name);
  8539.                         }
  8540.                         else
  8541.                         {
  8542.                             sprintf(logBuff, "Section [NXDOMAIN] Too many blacklist entries: %s ignored", iniStrPtr);
  8543.                             logDNSMess(logBuff, 1);
  8544.                         }
  8545.  
  8546.  
  8547.                     }
  8548.                     else
  8549.                     {
  8550.                         sprintf(logBuff, "Section [NXDOMAIN] Invalid Entry: %s ignored", iniStrPtr);
  8551.                         logDNSMess(logBuff, 1);
  8552.                     }
  8553.                 }
  8554.                 else
  8555.                 {
  8556.                     sprintf(logBuff, "Section [NXDOMAIN], Missing value, entry %s ignored", iniStrPtr);
  8557.                     logDNSMess(logBuff, 1);
  8558.                 }
  8559.             }
  8560.         }
  8561.  
  8562.         for (int i = 0; i < 32 && cfig.dnsRoutes[i].dns[0]; i++)
  8563.         {
  8564.             char temp[256];
  8565.  
  8566.             if (!cfig.dnsRoutes[i].dns[1])
  8567.                 sprintf(logBuff, "Child DNS Server: %s for Zone %s", IP2String(tempbuff, cfig.dnsRoutes[i].dns[0]), cfig.dnsRoutes[i].zone);
  8568.             else
  8569.                 sprintf(logBuff, "Child DNS Servers: %s, %s for Zone %s", IP2String(temp, cfig.dnsRoutes[i].dns[0]), IP2String(tempbuff, cfig.dnsRoutes[i].dns[1]), cfig.dnsRoutes[i].zone);
  8570.  
  8571.             logDNSMess(logBuff, 1);
  8572.         }
  8573.  
  8574.         for (int i = 0; i < MAX_SERVERS && network.dns[i]; i++)
  8575.         {
  8576.             sprintf(logBuff, "Forwarding DNS Server: %s", IP2String(tempbuff, network.dns[i]));
  8577.             logDNSMess(logBuff, 1);
  8578.         }
  8579.  
  8580.         char temp[128];
  8581.  
  8582.         for (int i = 0; i <= MAX_RANGES && cfig.dnsRanges[i].rangeStart; i++)
  8583.         {
  8584.             char *logPtr = logBuff;
  8585.             logPtr += sprintf(logPtr, "%s", "DNS Service Permitted Hosts: ");
  8586.             logPtr += sprintf(logPtr, "%s-", IP2String(tempbuff, htonl(cfig.dnsRanges[i].rangeStart)));
  8587.             logPtr += sprintf(logPtr, "%s", IP2String(tempbuff, htonl(cfig.dnsRanges[i].rangeEnd)));
  8588.             logDNSMess(logBuff, 1);
  8589.         }
  8590.  
  8591.         if (cfig.ttl >= LONG_MAX)
  8592.             sprintf(logBuff, "Default Host Expiry: Infinity");
  8593.         else
  8594.             sprintf(logBuff, "Default Host Expiry: %u (sec)", cfig.ttl);
  8595.  
  8596.         logDNSMess(logBuff, 1);
  8597.  
  8598.         if (cfig.replication)
  8599.         {
  8600.             sprintf(logBuff, "Refresh: %u (sec)", cfig.refresh);
  8601.             logDNSMess(logBuff, 1);
  8602.             sprintf(logBuff, "Retry: %u (sec)", cfig.retry);
  8603.             logDNSMess(logBuff, 1);
  8604.  
  8605.             if (cfig.expire == ULONG_MAX)
  8606.                 sprintf(logBuff, "Expire: Infinity");
  8607.             else
  8608.                 sprintf(logBuff, "Expire: %u (sec)", cfig.expire);
  8609.  
  8610.             logDNSMess(logBuff, 1);
  8611.             sprintf(logBuff, "Min: %u (sec)", cfig.minimum);
  8612.             logDNSMess(logBuff, 1);
  8613.         }
  8614.     }
  8615.  
  8616.     if (cfig.replication == 1)
  8617.         sprintf(logBuff, "Server Name: %s (Primary)", cfig.servername);
  8618.     else if (cfig.replication == 2)
  8619.         sprintf(logBuff, "Server Name: %s (Secondary)", cfig.servername);
  8620.     else
  8621.         sprintf(logBuff, "Server Name: %s", cfig.servername);
  8622.  
  8623.     logDNSMess(logBuff, 1);
  8624.  
  8625.     if (dnsService)
  8626.     {
  8627.         if (cfig.authorized)
  8628.             sprintf(logBuff, "Authority for Zone: %s (%s)", cfig.zone, cfig.authority);
  8629.         else
  8630.             sprintf(logBuff, "Domain Name: %s", cfig.zone);
  8631.     }
  8632.     else
  8633.         sprintf(logBuff, "Domain Name: %s", cfig.zone);
  8634.  
  8635.     logDNSMess(logBuff, 1);
  8636.  
  8637.     if (!verbatim)
  8638.     {
  8639.         if (dnsService)
  8640.         {
  8641.             if (cfig.dnsLogLevel > 1)
  8642.                 sprintf(logBuff, "DNS Logging: All");
  8643.             else if (cfig.dnsLogLevel)
  8644.                 sprintf(logBuff, "DNS Logging: Errors");
  8645.             else
  8646.                 sprintf(logBuff, "DNS Logging: None");
  8647.  
  8648.             logMess(logBuff, 1);
  8649.         }
  8650.  
  8651.         if (dhcpService)
  8652.         {
  8653.             if (cfig.dhcpLogLevel > 1)
  8654.                 sprintf(logBuff, "DHCP Logging: All");
  8655.             else if (cfig.dhcpLogLevel)
  8656.                 sprintf(logBuff, "DHCP Logging: Errors");
  8657.             else
  8658.                 sprintf(logBuff, "DHCP Logging: None");
  8659.  
  8660.             logMess(logBuff, 1);
  8661.         }
  8662.     }
  8663.  
  8664.     if (dnsService)
  8665.     {
  8666.         cfig.serial1 = t;
  8667.         cfig.serial2 = t;
  8668.         cfig.expireTime = LONG_MAX;
  8669.  
  8670.         if (dhcpService)
  8671.         {
  8672.             if (cfig.replication == 1)
  8673.                 getSecondary();
  8674.             else if (cfig.replication == 2)
  8675.                 _beginthread(checkZone, 0, (void*)0);
  8676.         }
  8677.         else if (cfig.replication == 2)
  8678.         {
  8679.             _beginthread(checkZone, 0, (void*)&cfig);
  8680.         }
  8681.     }
  8682.  
  8683.     if (getSection("PORT-OFFSET", iniStr, 1, iniFile))
  8684.     {
  8685.         char *iniStrPtr = myGetToken(iniStr, 0);
  8686.         portOffset = atoi(iniStrPtr);
  8687.         if (portOffset)
  8688.         {
  8689.             sprintf(logBuff, "Using port offset %d", portOffset);
  8690.             logMess(logBuff, 1);
  8691.         }
  8692.     }
  8693.  
  8694.     sprintf(logBuff, "Detecting Static Interfaces..");
  8695.     logMess(logBuff, 1);
  8696.  
  8697.     do
  8698.     {
  8699.         memset(&network, 0, sizeof(network));
  8700.         getServ();
  8701.         getDServ();
  8702.         sprintf(cfig.servername_fqn, "%s.%s", cfig.servername, cfig.zone);
  8703.         strcpy(cfig.ns, cfig.servername_fqn);
  8704.         cfig.zLen = strlen(cfig.zone);
  8705.         bool ifSpecified = false;
  8706.  
  8707.         if (getSection("LISTEN-ON", iniStr, 1, iniFile))
  8708.         {
  8709.             char *iniStrPtr = myGetToken(iniStr, 0);
  8710.             for (int i = 0; i < MAX_SERVERS && iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  8711.             {
  8712.                 ifSpecified = true;
  8713.                 DWORD addr = my_inet_addr(iniStrPtr);
  8714.  
  8715.                 if (isIP(iniStrPtr) && addr)
  8716.                 {
  8717.                     for (BYTE m = 0; ; m++)
  8718.                     {
  8719.                         if (m >= MAX_SERVERS || !network.staticServers[m])
  8720.                         {
  8721.                             if (findServer(network.allServers, addr))
  8722.                             {
  8723.                                 sprintf(logBuff, "Warning: Section [LISTEN-ON], Interface %s is not Static, ignored", iniStrPtr);
  8724.                                 logMess(logBuff, 1);
  8725.                             }
  8726.                             else
  8727.                             {
  8728.                                 sprintf(logBuff, "Warning: Section [LISTEN-ON], Interface %s not available, ignored", iniStrPtr);
  8729.                                 logMess(logBuff, 1);
  8730.                             }
  8731.                             break;
  8732.                         }
  8733.                         else if (network.staticServers[m] == addr)
  8734.                         {
  8735.                             for (BYTE n = 0; n < MAX_SERVERS; n++)
  8736.                             {
  8737.                                 if (network.listenServers[n] == addr)
  8738.                                     break;
  8739.                                 else if (!network.listenServers[n])
  8740.                                 {
  8741.                                     network.listenServers[n] = network.staticServers[m];
  8742.                                     network.listenMasks[n] = network.staticMasks[m];
  8743.                                     break;
  8744.                                 }
  8745.                             }
  8746.                             break;
  8747.                         }
  8748.                     }
  8749.                 }
  8750.                 else
  8751.                 {
  8752.                     sprintf(logBuff, "Warning: Section [LISTEN-ON], Invalid Interface Address %s, ignored", iniStrPtr);
  8753.                     logMess(logBuff, 1);
  8754.                 }
  8755.             }
  8756.         }
  8757.  
  8758.         if (!ifSpecified)
  8759.         {
  8760.             BYTE k = 0;
  8761.  
  8762.             for (BYTE m = 0; m < MAX_SERVERS && network.allServers[m]; m++)
  8763.             {
  8764.                 for (BYTE n = 0; n < MAX_SERVERS; n++)
  8765.                 {
  8766.                     if (network.allServers[m] == network.staticServers[n])
  8767.                     {
  8768.                         network.listenServers[k] = network.staticServers[n];
  8769.                         network.listenMasks[k] = network.staticMasks[n];
  8770.                         k++;
  8771.                         break;
  8772.                     }
  8773.                     else if (!network.staticServers[n])
  8774.                     {
  8775.                         sprintf(logBuff, "Warning: Interface %s is not Static, not used", IP2String(tempbuff, network.allServers[m]));
  8776.                         logMess(logBuff, 2);
  8777.                         break;
  8778.                     }
  8779.                 }
  8780.             }
  8781.         }
  8782.  
  8783.         if (dhcpService)
  8784.         {
  8785.             int i = 0;
  8786.  
  8787.             for (int j = 0; j < MAX_SERVERS && network.listenServers[j]; j++)
  8788.             {
  8789.                 BOOL bOptVal = TRUE;
  8790.                 int bOptLen = sizeof(BOOL);
  8791.  
  8792.                 network.dhcpConn[i].sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  8793.  
  8794.                 if (network.dhcpConn[i].sock == INVALID_SOCKET)
  8795.                 {
  8796.                     sprintf(logBuff, "Failed to Create DHCP Socket");
  8797.                     logMess(logBuff, 1);
  8798.                     continue;
  8799.                 }
  8800.  
  8801.                 network.dhcpConn[i].addr.sin_family = AF_INET;
  8802.                 network.dhcpConn[i].addr.sin_addr.s_addr = network.listenServers[j];
  8803.                 network.dhcpConn[i].addr.sin_port = htons(IPPORT_DHCPS + portOffset);
  8804.  
  8805.                 network.dhcpConn[i].broadCastVal = TRUE;
  8806.                 network.dhcpConn[i].broadCastSize = sizeof(network.dhcpConn[i].broadCastVal);
  8807.                 setsockopt(network.dhcpConn[i].sock, SOL_SOCKET, SO_BROADCAST, (char*)&network.dhcpConn[i].broadCastVal, network.dhcpConn[i].broadCastSize);
  8808.                 setsockopt(network.dhcpConn[i].sock, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptVal, bOptLen);
  8809.  
  8810.                 //network.dhcpConn[i].donotRouteVal = TRUE;
  8811.                 //network.dhcpConn[i].donotRouteSize = sizeof(network.dhcpConn[i].donotRouteVal);
  8812.                 //setsockopt(network.dhcpConn[i].sock, SOL_SOCKET, SO_DONTROUTE, (char*)&network.dhcpConn[i].donotRouteVal, network.dhcpConn[i].donotRouteSize);
  8813.  
  8814.                 int nRet = bind(network.dhcpConn[i].sock, (sockaddr*)&network.dhcpConn[i].addr, sizeof(struct sockaddr_in));
  8815.  
  8816.                 if (nRet == SOCKET_ERROR)
  8817.                 {
  8818.                     closesocket(network.dhcpConn[i].sock);
  8819.                     sprintf(logBuff, "Warning: %s Port %d already in use",
  8820.                             IP2String(tempbuff, network.listenServers[j]),
  8821.                             (IPPORT_DHCPS + portOffset));
  8822.                     logMess(logBuff, 1);
  8823.                     continue;
  8824.                 }
  8825.  
  8826.                 if (network.maxFD < network.dhcpConn[i].sock)
  8827.                     network.maxFD = network.dhcpConn[i].sock;
  8828.  
  8829.                 network.dhcpConn[i].server = network.listenServers[j];
  8830.                 network.dhcpConn[i].mask = network.listenMasks[j];
  8831.  
  8832.                 i++;
  8833.             }
  8834.  
  8835.             if (cfig.replication)
  8836.             {
  8837.                 //printf("Here\n");
  8838.  
  8839.                 network.dhcpReplConn.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  8840.                 if (network.dhcpReplConn.sock == INVALID_SOCKET)
  8841.                 {
  8842.                     sprintf(logBuff, "Failed to Create DHCP Replication Socket");
  8843.                     logMess(logBuff, 1);
  8844.                 }
  8845.                 else
  8846.                 {
  8847.                     //printf("Socket %u\n", network.dhcpReplConn.sock);
  8848.                     network.dhcpReplConn.addr.sin_family = AF_INET;
  8849.  
  8850.                     if (cfig.replication == 1)
  8851.                         network.dhcpReplConn.addr.sin_addr.s_addr = cfig.zoneServers[0];
  8852.                     else
  8853.                         network.dhcpReplConn.addr.sin_addr.s_addr = cfig.zoneServers[1];
  8854.  
  8855.                     network.dhcpReplConn.addr.sin_port = 0;
  8856.  
  8857.                     int nRet = bind(network.dhcpReplConn.sock, (sockaddr*)&network.dhcpReplConn.addr, sizeof(struct sockaddr_in));
  8858.  
  8859.                     if (nRet == SOCKET_ERROR)
  8860.                     {
  8861.                         sprintf(logBuff, "DHCP Replication Server, Bind Failed");
  8862.                         logMess(logBuff, 1);
  8863.                     }
  8864.                     else if (network.maxFD < network.dhcpReplConn.sock)
  8865.                         network.maxFD = network.dhcpReplConn.sock;
  8866.                     /*
  8867.                     else
  8868.                     network.dhcpReplConn.server = network.dhcpReplConn.addr.sin_addr.s_addr;
  8869.                     */
  8870.                 }
  8871.             }
  8872.         }
  8873.  
  8874.         if (dnsService)
  8875.         {
  8876.             int i = 0;
  8877.  
  8878.             for (int j = 0; j < MAX_SERVERS && network.listenServers[j]; j++)
  8879.             {
  8880.                 BOOL bOptVal = TRUE;
  8881.                 int bOptLen = sizeof(BOOL);
  8882.  
  8883.                 network.dnsUdpConn[i].sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  8884.  
  8885.                 if (network.dnsUdpConn[i].sock == INVALID_SOCKET)
  8886.                 {
  8887.                     sprintf(logBuff, "Failed to Create Socket");
  8888.                     logDNSMess(logBuff, 1);
  8889.                     continue;
  8890.                 }
  8891.  
  8892.                 //printf("Socket %u\n", network.dnsUdpConn[i].sock);
  8893.  
  8894.                 network.dnsUdpConn[i].addr.sin_family = AF_INET;
  8895.                 network.dnsUdpConn[i].addr.sin_addr.s_addr = network.listenServers[j];
  8896.                 network.dnsUdpConn[i].addr.sin_port = htons(IPPORT_DNS + portOffset);
  8897.                 setsockopt(network.dnsUdpConn[i].sock, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptVal, bOptLen);
  8898.  
  8899.                 int nRet = bind(network.dnsUdpConn[i].sock,
  8900.                                 (sockaddr*)&network.dnsUdpConn[i].addr,
  8901.                                 sizeof(struct sockaddr_in)
  8902.                                );
  8903.  
  8904.                 if (nRet == SOCKET_ERROR)
  8905.                 {
  8906.                     closesocket(network.dnsUdpConn[i].sock);
  8907.                     sprintf(logBuff, "Warning: %s UDP Port %d already in use",
  8908.                             IP2String(tempbuff, network.listenServers[j]),
  8909.                             (IPPORT_DNS + portOffset));
  8910.                     logDNSMess(logBuff, 1);
  8911.                     continue;
  8912.                 }
  8913.  
  8914.                 if (network.maxFD < network.dnsUdpConn[i].sock)
  8915.                     network.maxFD = network.dnsUdpConn[i].sock;
  8916.  
  8917.                 network.dnsUdpConn[i].server = network.listenServers[j];
  8918.  
  8919.                 if (!cfig.nsIP)
  8920.                     cfig.nsIP = network.listenServers[j];
  8921.  
  8922.                 i++;
  8923.             }
  8924.  
  8925.             network.forwConn.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  8926.             if (network.forwConn.sock == INVALID_SOCKET)
  8927.             {
  8928.                 sprintf(logBuff, "Failed to Create Socket");
  8929.                 logDNSMess(logBuff, 1);
  8930.             }
  8931.             else
  8932.             {
  8933.                 network.forwConn.addr.sin_family = AF_INET;
  8934.                 //bind(network.forwConn.sock, (sockaddr*)&network.forwConn.addr, sizeof(struct sockaddr_in));
  8935.  
  8936.                 if (network.maxFD < network.forwConn.sock)
  8937.                     network.maxFD = network.forwConn.sock;
  8938.             }
  8939.  
  8940.             i = 0;
  8941.  
  8942.             for (int j = 0; j < MAX_SERVERS && network.listenServers[j]; j++)
  8943.             {
  8944.                 network.dnsTcpConn[i].sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP);
  8945.  
  8946.                 if (network.dnsTcpConn[i].sock == INVALID_SOCKET)
  8947.                 {
  8948.                     sprintf(logBuff, "Failed to Create Socket");
  8949.                     logDNSMess(logBuff, 1);
  8950.                 }
  8951.                 else
  8952.                 {
  8953.                     BOOL bOptVal = TRUE;
  8954.                     int bOptLen = sizeof(BOOL);
  8955.  
  8956.                     //printf("Socket %u\n", network.dnsTcpConn[i].sock);
  8957.                     network.dnsTcpConn[i].addr.sin_family = AF_INET;
  8958.                     network.dnsTcpConn[i].addr.sin_addr.s_addr = network.listenServers[j];
  8959.                     network.dnsTcpConn[i].addr.sin_port = htons(IPPORT_DNS + portOffset);
  8960.                     setsockopt(network.dnsTcpConn[i].sock, SOL_SOCKET, SO_REUSEADDR, (char *)&bOptVal, bOptLen);
  8961.  
  8962.                     int nRet = bind(network.dnsTcpConn[i].sock,
  8963.                                     (sockaddr*)&network.dnsTcpConn[i].addr,
  8964.                                     sizeof(struct sockaddr_in));
  8965.  
  8966.                     if (nRet == SOCKET_ERROR)
  8967.                     {
  8968.                         closesocket(network.dnsTcpConn[i].sock);
  8969.                         sprintf(logBuff, "Warning: %s TCP Port %d already in use",
  8970.                                 IP2String(tempbuff, network.listenServers[j]),
  8971.                                 (IPPORT_DNS + portOffset));
  8972.                         logDNSMess(logBuff, 1);
  8973.                     }
  8974.                     else
  8975.                     {
  8976.                         nRet = listen(network.dnsTcpConn[i].sock, SOMAXCONN);
  8977.  
  8978.                         if (nRet == SOCKET_ERROR)
  8979.                         {
  8980.                             closesocket(network.dnsTcpConn[i].sock);
  8981.                             sprintf(logBuff, "TCP Port 53 Error on Listen");
  8982.                             logDNSMess(logBuff, 1);
  8983.                         }
  8984.                         else
  8985.                         {
  8986.                             network.dnsTcpConn[i].server = network.listenServers[j];
  8987.  
  8988.                             if (network.maxFD < network.dnsTcpConn[i].sock)
  8989.                                 network.maxFD = network.dnsTcpConn[i].sock;
  8990.  
  8991.                             i++;
  8992.                         }
  8993.                     }
  8994.                 }
  8995.             }
  8996.         }
  8997.  
  8998.         if ((dhcpService && !network.dhcpConn[0].server) || (dnsService && !(network.dnsUdpConn[0].server && network.dnsTcpConn[0].server)))
  8999.         {
  9000.             sprintf(logBuff, "No Static Interface ready, Waiting...");
  9001.             logMess(logBuff, 1);
  9002.             continue;
  9003.         }
  9004.  
  9005.         if (dhcpService)
  9006.         {
  9007.             network.httpConn.port = 6789;
  9008.             network.httpConn.server = network.dhcpConn[0].server;
  9009.  
  9010.             if (getSection("HTTP-INTERFACE", iniStr, 1, iniFile))
  9011.             {
  9012.                 char *iniStrPtr = myGetToken(iniStr, 0);
  9013.  
  9014.                 if(iniStrPtr[0])
  9015.                 {
  9016.                     mySplit(name, value, iniStrPtr, ':');
  9017.  
  9018.                     if (name[0] && isIP(name) && my_inet_addr(name))
  9019.                         network.httpConn.server = my_inet_addr(name);
  9020.                     else
  9021.                     {
  9022.                         sprintf(logBuff, "Warning: Section [HTTP-INTERFACE], Invalid IP Address %s, ignored", name);
  9023.                         logDHCPMess(logBuff, 1);
  9024.                     }
  9025.  
  9026.                     if (value[0])
  9027.                     {
  9028.                         if (atoi(value))
  9029.                             network.httpConn.port = atoi(value);
  9030.                         else
  9031.                         {
  9032.                             sprintf(logBuff, "Warning: Section [HTTP-INTERFACE], Invalid port %s, ignored", value);
  9033.                             logDHCPMess(logBuff, 1);
  9034.                         }
  9035.                     }
  9036.                 }
  9037.             }
  9038.  
  9039.             network.httpConn.sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  9040.  
  9041.             if (network.httpConn.sock == INVALID_SOCKET)
  9042.             {
  9043.                 network.httpConn.server = 0;
  9044.                 sprintf(logBuff, "Failed to Create Socket");
  9045.                 logDHCPMess(logBuff, 1);
  9046.             }
  9047.             else
  9048.             {
  9049.                 //printf("Socket %u\n", network.httpConn.sock);
  9050.  
  9051.                 network.httpConn.addr.sin_family = AF_INET;
  9052.                 network.httpConn.addr.sin_addr.s_addr = network.httpConn.server;
  9053.                 network.httpConn.addr.sin_port = htons(network.httpConn.port);
  9054.  
  9055.                 int nRet = bind(network.httpConn.sock,
  9056.                                 (sockaddr*)&network.httpConn.addr,
  9057.                                 sizeof(struct sockaddr_in));
  9058.  
  9059.                 if (nRet == SOCKET_ERROR)
  9060.                 {
  9061.                     sprintf(logBuff, "Http Interface %s TCP Port %u not available", IP2String(tempbuff, network.httpConn.server), network.httpConn.port);
  9062.                     logDHCPMess(logBuff, 1);
  9063.                     network.httpConn.server = 0;
  9064.                     closesocket(network.httpConn.sock);
  9065.                 }
  9066.                 else
  9067.                 {
  9068.                     nRet = listen(network.httpConn.sock, SOMAXCONN);
  9069.  
  9070.                     if (nRet == SOCKET_ERROR)
  9071.                     {
  9072.                         sprintf(logBuff, "%s TCP Port %u Error on Listen", IP2String(tempbuff, network.httpConn.server), network.httpConn.port);
  9073.                         logDHCPMess(logBuff, 1);
  9074.                         closesocket(network.httpConn.sock);
  9075.                         network.httpConn.server = 0;
  9076.                     }
  9077.                     else if (network.httpConn.sock > network.maxFD)
  9078.                         network.maxFD = network.httpConn.sock;
  9079.                 }
  9080.             }
  9081.  
  9082.         }
  9083.  
  9084.         network.maxFD++;
  9085.  
  9086.         char htmFile[_MAX_PATH];
  9087.         GetModuleFileName(NULL, htmFile, _MAX_PATH);
  9088.         fileExt = strrchr(htmFile, '.');
  9089.         strcpy(fileExt, ".htm");
  9090.  
  9091.         if (dhcpService && network.httpConn.server)
  9092.         {
  9093.             sprintf(logBuff, "Lease Status URL: http://%s:%u", IP2String(tempbuff, network.httpConn.server), network.httpConn.port);
  9094.             logDHCPMess(logBuff, 1);
  9095.             FILE *f = fopen(htmFile, "wt");
  9096.             if (f)
  9097.             {
  9098.                 fprintf(f, "<script>this.location=\"http://%s:%u\";</script>", IP2String(tempbuff, network.httpConn.server), network.httpConn.port);
  9099.                 fclose(f);
  9100.             }
  9101.         }
  9102.         else
  9103.         {
  9104.             FILE *f = fopen(htmFile, "wt");
  9105.  
  9106.             if (f)
  9107.             {
  9108.                 fprintf(f, "<html><body><h2>DHCP/HTTP Service is not running</h2></body></html>");
  9109.                 fclose(f);
  9110.             }
  9111.         }
  9112.  
  9113.         for (int i = 0; i < MAX_SERVERS && network.staticServers[i]; i++)
  9114.         {
  9115.             for (BYTE j = 0; j < MAX_SERVERS; j++)
  9116.             {
  9117.                 if (network.dhcpConn[j].server == network.staticServers[i] || network.dnsUdpConn[j].server == network.staticServers[i])
  9118.                 {
  9119.                     sprintf(logBuff, "Listening On: %s", IP2String(tempbuff, network.staticServers[i]));
  9120.                     logMess(logBuff, 1);
  9121.                     break;
  9122.                 }
  9123.             }
  9124.         }
  9125.  
  9126. //        if (verbatim)
  9127. //            printf("\nAccepting requests..\n");
  9128.  
  9129.     } while (detectChange());
  9130.  
  9131.     _endthread();
  9132.     return;
  9133. }
  9134.  
  9135. bool detectChange()
  9136. {
  9137.     OVERLAPPED overlap;
  9138.     DWORD ret;
  9139.     HANDLE hand = NULL;
  9140.     overlap.hEvent = WSACreateEvent();
  9141.  
  9142.     ret = NotifyAddrChange(&hand, &overlap);
  9143.  
  9144.     if (ret != NO_ERROR)
  9145.     {
  9146.         if (WSAGetLastError() != WSA_IO_PENDING)
  9147.         {
  9148.             printf("NotifyAddrChange error...%d\n", WSAGetLastError());
  9149.             return true;
  9150.         }
  9151.     }
  9152.  
  9153.     network.ready = true;
  9154.  
  9155.     if ( WaitForSingleObject(overlap.hEvent, INFINITE) == WAIT_OBJECT_0 )
  9156.     {
  9157.         //logMess("Here", 1);
  9158.  
  9159.         WSACloseEvent(overlap.hEvent);
  9160.  
  9161.         network.ready = false;
  9162.  
  9163.         while (network.busy)
  9164.             Sleep(10);
  9165.  
  9166.         sprintf(logBuff, "Network changed, re-detecting Static Interfaces..");
  9167.         logMess(logBuff, 1);
  9168.         closeConn();
  9169.         memset(&network, 0, sizeof(network));
  9170.     }
  9171.  
  9172.     return true;
  9173. }
  9174.  
  9175. void getServ()
  9176. {
  9177.     for (int i = 0; i < MAX_SERVERS; i++)
  9178.     {
  9179.         network.allServers[i] = 0;
  9180.         network.staticServers[i] = 0;
  9181.         network.staticMasks[i] = 0;
  9182.     }
  9183.  
  9184.     SOCKET sd = WSASocket(PF_INET, SOCK_DGRAM, 0, 0, 0, 0);
  9185.     if (sd == INVALID_SOCKET)
  9186.         return;
  9187.  
  9188.     INTERFACE_INFO InterfaceList[MAX_SERVERS];
  9189.     unsigned long nBytesReturned;
  9190.     if (WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList,
  9191.                  sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR)
  9192.         return ;
  9193.  
  9194.     int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
  9195.     for (int i = 0; i < nNumInterfaces; ++i)
  9196.     {
  9197.         sockaddr_in *pAddress = (sockaddr_in*)&(InterfaceList[i].iiAddress);
  9198.         u_long nFlags = InterfaceList[i].iiFlags;
  9199.         //        if (!((nFlags & IFF_POINTTOPOINT)))
  9200.         if (!((nFlags & IFF_POINTTOPOINT) || (nFlags & IFF_LOOPBACK)))
  9201.         {
  9202.             //printf("%s\n", IP2String(tempbuff, pAddress->sin_addr.S_un.S_addr));
  9203.             addServer(network.allServers, pAddress->sin_addr.s_addr);
  9204.         }
  9205.     }
  9206.  
  9207.     closesocket(sd);
  9208.  
  9209.     PIP_ADAPTER_INFO pAdapterInfo;
  9210.     PIP_ADAPTER_INFO pAdapter;
  9211.  
  9212.     pAdapterInfo = (IP_ADAPTER_INFO*) calloc(1, sizeof(IP_ADAPTER_INFO));
  9213.     DWORD ulOutBufLen = sizeof(IP_ADAPTER_INFO);
  9214.  
  9215.     if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)
  9216.     {
  9217.         free(pAdapterInfo);
  9218.         pAdapterInfo = (IP_ADAPTER_INFO*)calloc(1, ulOutBufLen);
  9219.     }
  9220.  
  9221.     if ((GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR)
  9222.     {
  9223.         pAdapter = pAdapterInfo;
  9224.         while (pAdapter)
  9225.         {
  9226.             //if (!pAdapter->DhcpEnabled)
  9227.             {
  9228.                 IP_ADDR_STRING *sList = &pAdapter->IpAddressList;
  9229.                 while (sList)
  9230.                 {
  9231.                     DWORD iaddr = my_inet_addr(sList->IpAddress.String);
  9232.  
  9233.                     if (iaddr)
  9234.                     {
  9235.                         for (BYTE k = 0; k < MAX_SERVERS; k++)
  9236.                         {
  9237.                             if (network.staticServers[k] == iaddr)
  9238.                                 break;
  9239.                             else if (!network.staticServers[k])
  9240.                             {
  9241.                                 network.staticServers[k] = iaddr;
  9242.                                 network.staticMasks[k] = my_inet_addr(sList->IpMask.String);
  9243.                                 break;
  9244.                             }
  9245.                         }
  9246.                     }
  9247.                     sList = sList->Next;
  9248.                 }
  9249.  
  9250. //                IP_ADDR_STRING *rList = &pAdapter->GatewayList;
  9251. //                while (rList)
  9252. //                {
  9253. //                    DWORD trouter = my_inet_addr(rList->IpAddress.String);
  9254. //                    addServer(cfig.routers, trouter);
  9255. //                    rList = rList->Next;
  9256. //                }
  9257.             }
  9258.             pAdapter = pAdapter->Next;
  9259.         }
  9260.         free(pAdapterInfo);
  9261.     }
  9262. }
  9263.  
  9264. void getDServ()
  9265. {
  9266.     char iniStr[9192];
  9267.     DWORD dservers[MAX_SERVERS];
  9268.  
  9269.     for (int i = 0; i < MAX_SERVERS; i++)
  9270.     {
  9271.         network.dns[i] = 0;
  9272.         dservers[i] = 0;
  9273.     }
  9274.  
  9275.     if (getSection("DNS-SERVERS", iniStr, 1, iniFile))
  9276.     {
  9277.         char *iniStrPtr = myGetToken(iniStr, 0);
  9278.         for (int i = 0; i < MAX_SERVERS && iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
  9279.         {
  9280.             if (isIP(iniStrPtr))
  9281.             {
  9282.                 DWORD addr = my_inet_addr(iniStrPtr);
  9283.                 if (addServer(dservers, addr))
  9284.                     i++;
  9285.             }
  9286.             else
  9287.             {
  9288.                 sprintf(logBuff, "Section [DNS-SERVERS] Invalid Entry: %s ignored", iniStrPtr);
  9289.                 logMess(logBuff, 1);
  9290.             }
  9291.         }
  9292.     }
  9293.  
  9294.     FIXED_INFO *FixedInfo;
  9295.     ULONG ulOutBufLen;
  9296.     IP_ADDR_STRING *pIPAddr;
  9297.  
  9298.     FixedInfo = (FIXED_INFO*) GlobalAlloc(GPTR, sizeof(FIXED_INFO));
  9299.     ulOutBufLen = sizeof(FIXED_INFO);
  9300.  
  9301.     if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &ulOutBufLen))
  9302.     {
  9303.         GlobalFree(FixedInfo);
  9304.         FixedInfo = (FIXED_INFO*)GlobalAlloc(GPTR, ulOutBufLen);
  9305.     }
  9306.  
  9307.     if (!GetNetworkParams(FixedInfo, &ulOutBufLen))
  9308.     {
  9309.         if (!cfig.servername[0])
  9310.             strcpy(cfig.servername, FixedInfo->HostName);
  9311.  
  9312.         //printf("d=%s", FixedInfo->DomainName);
  9313.  
  9314.         if (!cfig.zone[0])
  9315.         {
  9316.             strcpy(cfig.zone, FixedInfo->DomainName);
  9317.             cfig.zLen = strlen(cfig.zone);
  9318.         }
  9319.  
  9320.         if (!cfig.zone[0])
  9321.         {
  9322.             strcpy(cfig.zone, "workgroup");
  9323.             cfig.zLen = strlen(cfig.zone);
  9324.         }
  9325.  
  9326.         if (!dservers[0])
  9327.         {
  9328.             pIPAddr = &FixedInfo->DnsServerList;
  9329.             while (pIPAddr)
  9330.             {
  9331.                 DWORD addr = my_inet_addr(pIPAddr->IpAddress.String);
  9332.  
  9333.                 addServer(dservers, addr);
  9334.                 pIPAddr = pIPAddr->Next;
  9335.             }
  9336.         }
  9337.         GlobalFree(FixedInfo);
  9338.     }
  9339.  
  9340.     for (int i = 0; i < MAX_SERVERS && dservers[i]; i++)
  9341.     {
  9342.         if (dnsService)
  9343.         {
  9344.             if (findServer(network.allServers, dservers[i]))
  9345.                 continue;
  9346.  
  9347.             addServer(network.dns, dservers[i]);
  9348.         }
  9349.         else
  9350.             addServer(network.dns, dservers[i]);
  9351.     }
  9352.     return;
  9353. }
  9354.  
  9355. void updateStateFile(void *lpParam)
  9356. {
  9357.     data8 *dhcpData = (data8*)lpParam;
  9358.  
  9359.     WaitForSingleObject(fEvent, INFINITE);
  9360.  
  9361.     if (dhcpData->dhcpInd)
  9362.     {
  9363.         FILE *f = fopen(leaFile, "rb+");
  9364.         if (f)
  9365.         {
  9366.             if (fseek(f, (dhcpData->dhcpInd - 1)*sizeof(data8), SEEK_SET) >= 0)
  9367.                 fwrite(dhcpData, sizeof(data8), 1, f);
  9368.  
  9369.             fclose(f);
  9370.         }
  9371.     }
  9372.     else
  9373.     {
  9374.         dhcpData->dhcpInd = cfig.dhcpIndex;
  9375.  
  9376.         FILE *f = fopen(leaFile, "ab");
  9377.         if (f)
  9378.         {
  9379.             fwrite(dhcpData, sizeof(data8), 1, f);
  9380.             fclose(f);
  9381.         }
  9382.     }
  9383.  
  9384.     free(dhcpData);
  9385.     SetEvent(fEvent);
  9386.     _endthread();
  9387.     return;
  9388. }
  9389.  
  9390. WORD gdmess(data9 *req, BYTE sockInd)
  9391. {
  9392.     memset(req, 0, sizeof(data9));
  9393.     req->sockInd = sockInd;
  9394.     req->sockLen = sizeof(req->addr);
  9395.     errno = 0;
  9396.  
  9397.     req->bytes = recvfrom(network.dhcpConn[req->sockInd].sock,
  9398.                           req->raw,
  9399.                           sizeof(req->raw),
  9400.                           0,
  9401.                           (sockaddr*)&req->addr,
  9402.                           &req->sockLen);
  9403.  
  9404.     //printf("start bytes=%u\n", req->bytes);
  9405.  
  9406.     errno = WSAGetLastError();
  9407.  
  9408.     //printf("errno=%u\n", errno);
  9409.  
  9410.     if (errno || req->bytes <= 0 || req->dhcpp.header.bp_op != BOOTP_REQUEST)
  9411.         return 0;
  9412.  
  9413.     data3 *op;
  9414.     BYTE *raw = req->dhcpp.vend_data;
  9415.     BYTE *rawEnd = raw + (req->bytes - sizeof(dhcp_header));
  9416.  
  9417.     for (; raw < rawEnd && *raw != DHCP_OPTION_END;)
  9418.     {
  9419.         op = (data3*)raw;
  9420.         //printf("OpCode=%u,MessType=%u\n", op->opt_code, op->value[0]);
  9421.  
  9422.         switch (op->opt_code)
  9423.         {
  9424.             case DHCP_OPTION_PAD:
  9425.                 raw++;
  9426.                 continue;
  9427.  
  9428.             case DHCP_OPTION_PARAMREQLIST:
  9429.                 for (int ix = 0; ix < op->size; ix++) {
  9430.                     req->paramreqlist[op->value[ix]] = 1;    
  9431.                 }
  9432.                 break;
  9433.  
  9434.             case DHCP_OPTION_MESSAGETYPE:
  9435.                 req->req_type = op->value[0];
  9436.                 break;
  9437.  
  9438.             case DHCP_OPTION_SERVERID:
  9439.                 req->server = fIP(op->value);
  9440.                 break;
  9441.  
  9442.             case DHCP_OPTION_IPADDRLEASE:
  9443.                 req->lease = fULong(op->value);
  9444.                 break;
  9445.  
  9446.             case DHCP_OPTION_MAXDHCPMSGSIZE:
  9447.                 req->messsize = fUShort(op->value);
  9448.                 break;
  9449.  
  9450.             case DHCP_OPTION_REQUESTEDIPADDR:
  9451.                 req->reqIP = fIP(op->value);
  9452.                 break;
  9453.  
  9454.             case DHCP_OPTION_HOSTNAME:
  9455.                 if (op->size && strcasecmp((char*)op->value, "(none)") && strcasecmp((char*)op->value, cfig.servername))
  9456.                 {
  9457.                     memcpy(req->hostname, op->value, op->size);
  9458.                     req->hostname[op->size] = 0;
  9459.  
  9460.                     if (char *ptr = strchr(req->hostname, '.'))
  9461.                         *ptr = 0;
  9462.                 }
  9463.                 break;
  9464.  
  9465.             case DHCP_OPTION_VENDORCLASSID:
  9466.                 memcpy(req->vendClass, op->value, op->size);
  9467.                 req->vendClassSize = op->size;
  9468.                 vciData v;
  9469.                 memcpy(v.vci, req->vendClass, (op->size)+1);
  9470.                 vci[req->reqIP] = v;
  9471.                 break;
  9472.  
  9473.             case DHCP_OPTION_USERCLASS:
  9474.                 memcpy(req->userClass, op->value, op->size);
  9475.                 req->userClassSize = op->size;
  9476.                 break;
  9477.  
  9478.             case DHCP_OPTION_RELAYAGENTINFO:
  9479.                 memcpy(&req->agentOption, op, op->size + 2);
  9480.                 break;
  9481.  
  9482.             case DHCP_OPTION_CLIENTID:
  9483.                 memcpy(&req->clientId, op, op->size + 2);
  9484.                 break;
  9485.  
  9486.             case DHCP_OPTION_SERIAL:
  9487.                 req->serial = fULong(op->value);
  9488.                 break;
  9489.         }
  9490.         raw += 2;
  9491.         raw += op->size;
  9492.     }
  9493.  
  9494.     req->vp = req->dhcpp.vend_data;
  9495.     memset(req->vp, 0, sizeof(dhcp_packet) - sizeof(dhcp_header));
  9496.     //printf("end bytes=%u\n", req->bytes);
  9497.     return 1;
  9498. }
  9499.  
  9500. void logMess(char *logBuff, BYTE dhcpLogLevel)
  9501. {
  9502. //    WaitForSingleObject(lEvent, INFINITE);
  9503.     //if (verbatim)
  9504.         printf("%s\n", logBuff);
  9505.     /*else*/ if (cfig.logfile && (dhcpLogLevel <= cfig.dnsLogLevel || dhcpLogLevel <= cfig.dhcpLogLevel))
  9506.     {
  9507.         time_t t = time(NULL);
  9508.         tm *ttm = localtime(&t);
  9509.  
  9510.         if (ttm->tm_yday != loggingDay)
  9511.         {
  9512.             loggingDay = ttm->tm_yday;
  9513.             strftime(extbuff, sizeof(extbuff), logFile, ttm);
  9514.             fprintf(cfig.logfile, "Logging Continued on file %s\n", extbuff);
  9515.             fclose(cfig.logfile);
  9516.             cfig.logfile = fopen(extbuff, "at");
  9517.  
  9518.             if (cfig.logfile)
  9519.                 fprintf(cfig.logfile, "%s\n\n", sVersion);
  9520.             else
  9521.                 return;
  9522.         }
  9523.  
  9524.         strftime(extbuff, sizeof(extbuff), "%d-%b-%y %X", ttm);
  9525.         fprintf(cfig.logfile, "[%s] %s\n", extbuff, logBuff);
  9526.         fflush(cfig.logfile);
  9527.     }
  9528. //    SetEvent(lEvent);
  9529. }
  9530.  
  9531. void logDHCPMess(char *logBuff, BYTE dhcpLogLevel)
  9532. {
  9533. //    WaitForSingleObject(lEvent, INFINITE);
  9534.     //if (verbatim)
  9535.         printf("%s\n", logBuff);
  9536.     /*else*/ if (cfig.logfile && dhcpLogLevel <= cfig.dhcpLogLevel)
  9537.     {
  9538.         time_t t = time(NULL);
  9539.         tm *ttm = localtime(&t);
  9540.  
  9541.         if (ttm->tm_yday != loggingDay)
  9542.         {
  9543.             loggingDay = ttm->tm_yday;
  9544.             strftime(extbuff, sizeof(extbuff), logFile, ttm);
  9545.             fprintf(cfig.logfile, "Logging Continued on file %s\n", extbuff);
  9546.             fclose(cfig.logfile);
  9547.             cfig.logfile = fopen(extbuff, "at");
  9548.  
  9549.             if (cfig.logfile)
  9550.                 fprintf(cfig.logfile, "%s\n\n", sVersion);
  9551.             else
  9552.                 return;
  9553.         }
  9554.  
  9555.         strftime(extbuff, sizeof(extbuff), "%d-%b-%y %X", ttm);
  9556.         fprintf(cfig.logfile, "[%s] %s\n", extbuff, logBuff);
  9557.         fflush(cfig.logfile);
  9558.     }
  9559. //    SetEvent(lEvent);
  9560. }
  9561.  
  9562. void logDNSMess(char *logBuff, BYTE dnsLogLevel)
  9563. {
  9564. //    WaitForSingleObject(lEvent, INFINITE);
  9565.     //if (verbatim)
  9566.         printf("%s\n", logBuff);
  9567.     /*else*/ if (cfig.logfile && dnsLogLevel <= cfig.dnsLogLevel)
  9568.     {
  9569.         time_t t = time(NULL);
  9570.         tm *ttm = localtime(&t);
  9571.  
  9572.         if (ttm->tm_yday != loggingDay)
  9573.         {
  9574.             loggingDay = ttm->tm_yday;
  9575.             strftime(extbuff, sizeof(extbuff), logFile, ttm);
  9576.             fprintf(cfig.logfile, "Logging Continued on file %s\n", extbuff);
  9577.             fclose(cfig.logfile);
  9578.             cfig.logfile = fopen(extbuff, "at");
  9579.  
  9580.             if (cfig.logfile)
  9581.                 fprintf(cfig.logfile, "%s\n\n", sVersion);
  9582.             else
  9583.                 return;
  9584.         }
  9585.  
  9586.         strftime(extbuff, sizeof(extbuff), "%d-%b-%y %X", ttm);
  9587.         fprintf(cfig.logfile, "[%s] %s\n", extbuff, logBuff);
  9588.         fflush(cfig.logfile);
  9589.     }
  9590. //    SetEvent(lEvent);
  9591. }
  9592.  
  9593. void logDNSMess(data5 *req, char *logBuff, BYTE dnsLogLevel)
  9594. {
  9595. //    WaitForSingleObject(lEvent, INFINITE);
  9596.     //if (verbatim)
  9597.         printf("%s\n", logBuff);
  9598.     /*else*/ if (cfig.logfile && dnsLogLevel <= cfig.dnsLogLevel)
  9599.     {
  9600.         time_t t = time(NULL);
  9601.         tm *ttm = localtime(&t);
  9602.  
  9603.         if (ttm->tm_yday != loggingDay)
  9604.         {
  9605.             loggingDay = ttm->tm_yday;
  9606.             strftime(extbuff, sizeof(extbuff), logFile, ttm);
  9607.             fprintf(cfig.logfile, "Logging Continued on file %s\n", extbuff);
  9608.             fclose(cfig.logfile);
  9609.             cfig.logfile = fopen(extbuff, "at");
  9610.  
  9611.             if (cfig.logfile)
  9612.                 fprintf(cfig.logfile, "%s\n\n", sVersion);
  9613.             else
  9614.                 return;
  9615.         }
  9616.  
  9617.  
  9618.         strftime(extbuff, sizeof(extbuff), "%d-%b-%y %X", ttm);
  9619.         fprintf(cfig.logfile, "[%s] Client %s, %s\n", extbuff, inet_ntoa(req->addr.sin_addr), logBuff);
  9620.         fflush(cfig.logfile);
  9621.     }
  9622. //    SetEvent(lEvent);
  9623. }
  9624.  
  9625. void logTCPMess(data5 *req, char *logBuff, BYTE dnsLogLevel)
  9626. {
  9627. //    WaitForSingleObject(lEvent, INFINITE);
  9628.  
  9629.     //if (verbatim)
  9630.         printf("%s\n", logBuff);
  9631.     /*else*/ if (cfig.logfile && dnsLogLevel <= cfig.dnsLogLevel)
  9632.     {
  9633.         time_t t = time(NULL);
  9634.         tm *ttm = localtime(&t);
  9635.  
  9636.         if (ttm->tm_yday != loggingDay)
  9637.         {
  9638.             loggingDay = ttm->tm_yday;
  9639.             strftime(extbuff, sizeof(extbuff), logFile, ttm);
  9640.             fprintf(cfig.logfile, "Logging Continued on file %s\n", extbuff);
  9641.             fclose(cfig.logfile);
  9642.             cfig.logfile = fopen(extbuff, "at");
  9643.  
  9644.             if (cfig.logfile)
  9645.                 fprintf(cfig.logfile, "%s\n\n", sVersion);
  9646.             else
  9647.                 return;
  9648.         }
  9649.  
  9650.         strftime(extbuff, sizeof(extbuff), "%d-%b-%y %X", ttm);
  9651.         fprintf(cfig.logfile, "[%s] TCP Client %s, %s\n", extbuff, inet_ntoa(req->addr.sin_addr), logBuff);
  9652.         fflush(cfig.logfile);
  9653.     }
  9654. //    SetEvent(lEvent);
  9655. }
  9656.  
  9657.