dualserver.cpp
上传用户:raihanchen
上传日期:2022-08-07
资源大小:129k
文件大小:227k
- /**************************************************************************
- * Copyright (C) 2005 by Achal Dhir *
- * achaldhir@gmail.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
- // dualserver.cpp //
- #include <string>
- #include <map>
- using namespace std;
- #include <sys/types.h>
- #include <sys/ioctl.h>
- #include <limits.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <net/if.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <unistd.h>
- #include <signal.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <memory.h>
- #include <sys/stat.h>
- #include <stdlib.h>
- #include <syslog.h>
- #include "dualserver.h"
- //Global Variables
- data2 cfig;
- BYTE cacheInd = 0;
- BYTE newInd = 0;
- bool kRunning = true;
- hostMap dnsCache[2];
- expiryMap dnsAge[2];
- dhcpMap dhcpCache;
- expiryMap dhcpAge;
- char tempbuff[256] = "";
- char logBuff[256] = "";
- char extbuff[256];
- WORD loggingDay;
- bool verbatim = false;
- char iniFile[256] = "";
- char leaFile[256] = "";
- char logFile[256] = "";
- char currentLogFile[256] = "";
- char arpa[] = ".in-addr.arpa";
- bool dhcpService = true;
- bool dnsService = true;
- timeval tv;
- fd_set readfds;
- fd_set writefds;
- pthread_mutex_t mutStateFile = PTHREAD_MUTEX_INITIALIZER;
- //pthread_mutex_t mutLogFile = PTHREAD_MUTEX_INITIALIZER;
- //constants
- const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- const char send200[] = "HTTP/1.1 200 OKrnDate: %srnLast-Modified: %srnContent-Type: text/htmlrnConnection: ClosernContent-Length: rnrn";
- //const char send200[] = "HTTP/1.1 200 OKrnDate: %srnLast-Modified: %srnContent-Type: text/htmlrnConnection: ClosernTransfer-Encoding: chunkedrn";
- const char sVersion[] = "Dual DHCP DNS Server Version 6.42 Linux Build 6421";
- const data4 opData[] =
- {
- {"IP_Addr", 0, 0},
- {"DHCP_Range", 0, 255},
- //{"Authorized", 0, 1},
- {"SubNet_Mask", DHCP_OPTION_NETMASK, 0},
- {"Time_Offset", DHCP_OPTION_TIMEOFFSET, 4},
- {"Router", DHCP_OPTION_ROUTER, 0},
- {"Time_Server", DHCP_OPTION_TIMESERVER, 0},
- {"Name_Server", DHCP_OPTION_NAMESERVER, 0},
- {"DNS_Server", DHCP_OPTION_DNS, 0},
- {"Log_Server", DHCP_OPTION_LOGSERVER, 0},
- {"Cookie_Server", DHCP_OPTION_COOKIESERVER, 0},
- {"LPR_Server", DHCP_OPTION_LPRSERVER, 0},
- {"Impress_Server", DHCP_OPTION_IMPRESSSERVER, 0},
- {"RLP_Server", DHCP_OPTION_RESLOCSERVER, 0},
- {"Hostname", DHCP_OPTION_HOSTNAME, 255},
- {"Boot_File_Size", DHCP_OPTION_BOOTFILESIZE, 2},
- //{"Domain_Name", DHCP_OPTION_DOMAINNAME, 255},
- {"Swap_Server", DHCP_OPTION_SWAPSERVER, 0},
- {"Root_Path", DHCP_OPTION_ROOTPATH, 255},
- {"Extension_Path", DHCP_OPTION_EXTSPATH, 255},
- {"Forward_On/Off", DHCP_OPTION_IPFORWARD, 1},
- {"SrcRte_On/Off", DHCP_OPTION_NONLOCALSR, 1},
- {"Policy_Filter_IP", DHCP_OPTION_POLICYFILTER, 0},
- {"Policy_Filter_Mask", DHCP_OPTION_POLICYFILTER, 0},
- {"Default_IP_TTL", DHCP_OPTION_IPTTL, 1},
- {"MTU_Timeout", DHCP_OPTION_PATHMTUAGING, 4},
- {"MTU_Plateau", DHCP_OPTION_PATHMTUPLATEAU, 2},
- {"MTU_Interface", DHCP_OPTION_INTERFACEMTU, 2},
- {"MTU_Subnet", DHCP_OPTION_SUBNETSLOCAL, 1},
- {"Broadcast_Address", DHCP_OPTION_BCASTADDRESS, 0},
- {"Mask_Discovery", DHCP_OPTION_MASKDISCOVERY, 1},
- {"Mask_Supplier", DHCP_OPTION_MASKSUPPLIER, 1},
- {"Router_Discovery", DHCP_OPTION_ROUTERDISCOVERY, 1},
- {"Router_Request", DHCP_OPTION_ROUTERSOLIC, 0},
- {"Static_Route_IP", DHCP_OPTION_STATICROUTE, 0},
- {"Static_Route_Mask", DHCP_OPTION_STATICROUTE, 0},
- {"Trailers", DHCP_OPTION_TRAILERENCAPS, 1},
- {"ARP_Timeout", DHCP_OPTION_ARPTIMEOUT, 4},
- {"Ethernet_Encp", DHCP_OPTION_ETHERNETENCAPS, 1},
- {"Default_TCP_TTL", DHCP_OPTION_TCPTTL, 1},
- {"Keepalive_Time", DHCP_OPTION_TCPKEEPALIVEINT, 4},
- {"Keepalive_Data", DHCP_OPTION_TCPKEEPALIVEGRBG, 1},
- {"NIS_Domain", DHCP_OPTION_NISDOMAIN, 255},
- {"NIS_Servers", DHCP_OPTION_NISSERVERS, 0},
- {"NTP_Servers", DHCP_OPTION_NTPSERVERS, 0},
- {"NETBIOS_Name_Srv", DHCP_OPTION_NETBIOSNAMESERV, 0},
- {"NETBIOS_Dist_Srv", DHCP_OPTION_NETBIOSDGDIST, 0},
- {"NETBIOS_Node_Type", DHCP_OPTION_NETBIOSNODETYPE, 1},
- {"NETBIOS_Scope", DHCP_OPTION_NETBIOSSCOPE, 255},
- {"X_Window_Font", DHCP_OPTION_X11FONTS, 0},
- {"X_Window_Manager", DHCP_OPTION_X11DISPLAYMNGR, 0},
- {"Lease_Time", DHCP_OPTION_IPADDRLEASE, 4},
- {"Renewal_Time", DHCP_OPTION_RENEWALTIME, 4},
- {"Rebinding_Time", DHCP_OPTION_REBINDINGTIME, 4},
- {"Netware/IP_Domain", 62, 255},
- {"Netware/IP_Option", 63, 0},
- {"NIS+_Domain_Name", DHCP_OPTION_NISPLUSDOMAIN, 255},
- {"NIS+_Server_Addr", DHCP_OPTION_NISPLUSSERVERS, 0},
- {"TFTP_Server_Name", DHCP_OPTION_TFTPSERVER, 255},
- {"Boot_File", DHCP_OPTION_BOOTFILE, 255},
- {"Home_Agent_Addrs", DHCP_OPTION_MOBILEIPHOME, 0},
- {"SMTP_Server", DHCP_OPTION_SMTPSERVER, 0},
- {"POP3_Server", DHCP_OPTION_POP3SERVER, 0},
- {"NNTP_Server", DHCP_OPTION_NNTPSERVER, 0},
- {"WWW_Server", DHCP_OPTION_WWWSERVER, 0},
- {"Finger_Server", DHCP_OPTION_FINGERSERVER, 0},
- {"IRC_Server", DHCP_OPTION_IRCSERVER, 0},
- {"StreetTalk_Server", DHCP_OPTION_STSERVER, 0},
- {"STDA_Server", DHCP_OPTION_STDASERVER, 0},
- {"iSNS", 83, 14},
- {"NDS_Servers", DHCP_OPTION_NDSSERVERS, 0},
- {"NDS_Tree_Name", DHCP_OPTION_NDSTREENAME, 255},
- {"NDS_Context", 87, 255},
- {"LDAP_URL", DHCP_OPTION_LDAP, 255},
- {"Auto_Configure", DHCP_OPTION_AUTO_CONFIG, 1},
- {"Name_Service_Search", DHCP_OPTION_NAMESERVICESEARCH, 2},
- {"Subnet_Selection", DHCP_OPTION_SUBNETSELECTION, 0},
- {"DNS_Domain_Search", DHCP_OPTION_DOMAINSEARCH, 255},
- {"TFTP_Phone_Server", DHCP_OPTION_TFPTSERVERIPADDRESS, 0},
- //{"TFTP_Server", DHCP_OPTION_TFPTSERVERIPADDRESS, 0},
- {"Call_Server", DHCP_OPTION_CALLSERVERIPADDRESS, 0},
- {"Discrimination_String", DHCP_OPTION_DISCRIMINATIONSTRING, 255},
- {"RemoteStatisticsServer", DHCP_OPTION_REMOTESTATISTICSSERVER, 0},
- {"Phone_Http_Proxy", DHCP_OPTION_HTTPPROXYFORPHONE_SPEC, 0},
- {"IP_Phone", 176, 255},
- {"Next_Server", DHCP_OPTION_NEXTSERVER, 0}
- };
- int main(int argc, char **argv)
- {
- signal(SIGINT, catch_int);
- signal(SIGABRT, catch_int);
- signal(SIGTERM, catch_int);
- signal(SIGQUIT, catch_int);
- signal(SIGTSTP, catch_int);
- signal(SIGHUP, catch_int);
- //printf("%in", argc);
- logBuff[0] = 0;
- char *ds = strrchr(argv[0], '/');
- if (ds)
- ds++;
- else
- ds = argv[0];
- sprintf(tempbuff, "ps -e | grep -v grep | grep -v "rc.%s" | grep "%s$" | head -1 | awk '{ print $1 }'", ds, ds);
- FILE *p = popen(tempbuff,"r");
- if (p)
- {
- while (fgets(tempbuff, sizeof(tempbuff), p))
- {
- if (atoi(tempbuff) != getpid())
- {
- sprintf(logBuff, "Error: %s is already running, Pid = %s", ds, tempbuff);
- break;
- }
- }
- pclose(p);
- }
- for (int i = 1; i < argc; i++)
- {
- if (!strcasecmp(argv[i], "-v"))
- verbatim = true;
- else if (!strcmp(argv[i], "-i") && argc > i + 1 && argv[i + 1][0] != '-' )
- {
- myTrim(iniFile, argv[i + 1]);
- i++;
- }
- else if (!strcmp(argv[i], "-s") && argc > i + 1 && argv[i + 1][0] != '-' )
- {
- myTrim(leaFile, argv[i + 1]);
- i++;
- }
- else if (!strcmp(argv[i], "-l") && argc > i + 1 && argv[i + 1][0] != '-' )
- {
- myTrim(logFile, argv[i + 1]);
- i++;
- }
- else if (!strncasecmp(argv[i], "-i", 2))
- myTrim(iniFile, argv[i] + 2);
- else if (!strncasecmp(argv[i], "-s", 2))
- myTrim(leaFile, argv[i] + 2);
- else if (!strncasecmp(argv[i], "-l", 2))
- myTrim(logFile, argv[i] + 2);
- else
- sprintf(logBuff, "Error: Invalid Argument %s", argv[i]);
- }
- if (!leaFile[0])
- strcpy(leaFile, "/etc/dualserver.state");
- if (!iniFile[0])
- strcpy(iniFile, "/etc/dualserver.ini");
- if (verbatim)
- {
- if (logBuff[0])
- {
- printf("%sn", logBuff);
- exit(EXIT_FAILURE);
- }
- if (getuid())
- {
- printf("Error: Only root should run this programn");
- exit(EXIT_FAILURE);
- }
- //printf("%in",sizeof(data7));
- data1 dhcpr;
- data5 dnsr;
- init();
- while (kRunning)
- {
- FD_ZERO(&readfds);
- tv.tv_sec = 20;
- tv.tv_usec = 0;
- if (dhcpService)
- {
- if (cfig.httpConn.server)
- FD_SET(cfig.httpConn.sock, &readfds);
- for (int i = 0; i < MAX_SERVERS && cfig.dhcpConn[i].server; i++)
- FD_SET(cfig.dhcpConn[i].sock, &readfds);
- FD_SET(cfig.dhcpListener.sock, &readfds);
- if (cfig.replication)
- FD_SET(cfig.dhcpReplConn.sock, &readfds);
- }
- if (dnsService)
- {
- for (int i = 0; i < MAX_SERVERS && cfig.dnsUdpConn[i].server; i++)
- FD_SET(cfig.dnsUdpConn[i].sock, &readfds);
- FD_SET(cfig.forwConn.sock, &readfds);
- for (int i = 0; i < MAX_SERVERS && cfig.dnsTcpConn[i].server; i++)
- FD_SET(cfig.dnsTcpConn[i].sock, &readfds);
- }
- //printf("%in",select(cfig.maxFD, &readfds, NULL, NULL, &tv));
- if (select(cfig.maxFD, &readfds, NULL, NULL, &tv))
- {
- if (dhcpService)
- {
- if (cfig.httpConn.server && FD_ISSET(cfig.httpConn.sock, &readfds))
- {
- data19 *req = (data19*)calloc(1, sizeof(data19));
- if (req)
- {
- req->sockLen = sizeof(req->addr);
- errno = 0;
- req->sock = accept(cfig.httpConn.sock, (sockaddr*)&req->addr, &req->sockLen);
- if (req->sock == INVALID_SOCKET)
- {
- sprintf(logBuff, "Accept Failed, Error=%sn", strerror(errno));
- logDHCPMess(logBuff, 1);
- free(req);
- }
- else
- procHTTP(req);
- }
- else
- {
- sprintf(logBuff, "Memory Error");
- logDHCPMess(logBuff, 0);
- }
- }
- if (cfig.replication && FD_ISSET(cfig.dhcpReplConn.sock, &readfds))
- {
- //printf("Repln");
- dhcpr.sockLen = sizeof(dhcpr.addr);
- dhcpr.bytes = recvfrom(cfig.dhcpReplConn.sock,
- dhcpr.raw,
- sizeof(dhcpr.raw),
- 0,
- (sockaddr*)&dhcpr.addr,
- &dhcpr.sockLen);
- }
- for (int i = 0; i < MAX_SERVERS && cfig.dhcpConn[i].server; i++)
- {
- if (FD_ISSET(cfig.dhcpConn[i].sock, &readfds) && gdmess(&dhcpr, i) && sdmess(&dhcpr))
- alad(&dhcpr);
- }
- if (FD_ISSET(cfig.dhcpListener.sock, &readfds) && gdmess(&dhcpr, 255) && sdmess(&dhcpr))
- alad(&dhcpr);
- }
- if (dnsService)
- {
- for (int i = 0; i < MAX_SERVERS && cfig.dnsUdpConn[i].server; i++)
- {
- if (FD_ISSET(cfig.dnsUdpConn[i].sock, &readfds) && gdnmess(&dnsr, i))
- {
- if (dnsr.dnsp->header.rcode == RCODE_NOTIMPL || dnsr.dnsp->header.rcode == RCODE_REFUSED)
- {
- sdnmess(&dnsr);
- }
- else if (scanloc(&dnsr))
- {
- if (htons(dnsr.dnsp->header.ancount))
- {
- if (dnsr.qtype == DNS_TYPE_SOA)
- printf("SOA Sent for zone %sn", dnsr.query);
- else if (dnsr.qtype == DNS_TYPE_NS)
- printf("NS Sent for zone %sn", dnsr.query);
- else if (dnsr.cache.dataType == CACHED)
- printf("%s resolved from Cache to %sn", dnsr.query, getResult(&dnsr));
- else
- printf("%s resolved Locally to %sn", dnsr.query, getResult(&dnsr));
- }
- else if (dnsr.dnsp->header.rcode == RCODE_NAMEERROR || dnsr.dnsp->header.rcode == RCODE_NOERROR)
- {
- dnsr.dnsp->header.rcode = RCODE_NAMEERROR;
- printf("%s not foundn", dnsr.query);
- }
- sdnmess(&dnsr);
- }
- else if (!fdnmess(&dnsr))
- {
- sdnmess(&dnsr);
- }
- }
- }
- for (int i = 0; i < MAX_SERVERS && cfig.dnsTcpConn[i].server; i++)
- {
- if (FD_ISSET(cfig.dnsTcpConn[i].sock, &readfds))
- {
- dnsr.sockInd = i;
- dnsr.sockLen = sizeof(dnsr.addr);
- errno = 0;
- dnsr.sock = accept(cfig.dnsTcpConn[i].sock, (sockaddr*)&dnsr.addr, &dnsr.sockLen);
- if (dnsr.sock == INVALID_SOCKET)
- printf("Accept Failed, Error=%sn", strerror(errno));
- else
- procTCP(&dnsr);
- }
- }
- if (FD_ISSET(cfig.forwConn.sock, &readfds))
- {
- if (frdnmess(&dnsr))
- {
- sdnmess(&dnsr);
- if (dnsr.cache.dnsIndex < MAX_SERVERS)
- {
- if (dnsr.dnsp->header.ancount)
- {
- if (getResult(&dnsr))
- printf("%s resolved from Forwarding server as %sn", dnsr.query, tempbuff);
- else
- printf("%s resolved from Forwarding servern", dnsr.query);
- }
- else
- printf("%s not found by Forwarding Servern", dnsr.query);
- }
- else
- {
- if (dnsr.dnsp->header.ancount)
- {
- if (getResult(&dnsr))
- printf("%s resolved from Child Server as %sn", dnsr.query, tempbuff);
- else
- printf("%s resolved from Child Servern", dnsr.query);
- }
- else
- printf("%s not found by Child Servern", dnsr.query);
- }
- }
- }
- }
- }
- cacheInd = newInd;
- checkSize(cacheInd);
- }
- //printf("Heren");
- }
- else
- {
- if(logBuff[0])
- {
- syslog(LOG_MAKEPRI(LOG_LOCAL1, LOG_CRIT), logBuff);
- exit(EXIT_FAILURE);
- }
- if(getuid())
- {
- syslog(LOG_MAKEPRI(LOG_LOCAL1, LOG_CRIT), "Only root should run this program");
- exit(EXIT_FAILURE);
- }
- /* Our process ID and Session ID */
- pid_t pid, sid;
- /* Fork off the parent process */
- pid = fork();
- if (pid < 0)
- {
- exit(EXIT_FAILURE);
- }
- /* If we got a good PID, then
- we can exit the parent process. */
- if (pid > 0)
- {
- exit(EXIT_SUCCESS);
- }
- /* Change the file mode mask */
- umask(0);
- /* Open any logs here */
- /* Create a new SID for the child process */
- sid = setsid();
- if (sid < 0)
- {
- /* Log the failure */
- exit(EXIT_FAILURE);
- }
- /* Change the current working directory */
- if ((chdir("/")) < 0)
- {
- /* Log the failure */
- exit(EXIT_FAILURE);
- }
- /* Close out the standard file descriptors */
- close(STDIN_FILENO);
- close(STDOUT_FILENO);
- close(STDERR_FILENO);
- /* Daemon-specific initialization goes here */
- data1 dhcpr;
- data5 dnsr;
- data19 httpr;
- init();
- /* The Big Loop */
- while (kRunning)
- {
- FD_ZERO(&readfds);
- tv.tv_sec = 20;
- tv.tv_usec = 0;
- if (dhcpService)
- {
- if (cfig.httpConn.server)
- FD_SET(cfig.httpConn.sock, &readfds);
- for (int i = 0; i < MAX_SERVERS && cfig.dhcpConn[i].server; i++)
- FD_SET(cfig.dhcpConn[i].sock, &readfds);
- FD_SET(cfig.dhcpListener.sock, &readfds);
- if (cfig.replication)
- FD_SET(cfig.dhcpReplConn.sock, &readfds);
- }
- if (dnsService)
- {
- for (int i = 0; i < MAX_SERVERS && cfig.dnsUdpConn[i].server; i++)
- FD_SET(cfig.dnsUdpConn[i].sock, &readfds);
- FD_SET(cfig.forwConn.sock, &readfds);
- for (int i = 0; i < MAX_SERVERS && cfig.dnsTcpConn[i].server; i++)
- FD_SET(cfig.dnsTcpConn[i].sock, &readfds);
- }
- //printf("%in",select(USHRT_MAX, &readfds, NULL, NULL, &tv));
- if (select(cfig.maxFD, &readfds, NULL, NULL, &tv))
- {
- if (dhcpService)
- {
- if (cfig.httpConn.server && FD_ISSET(cfig.httpConn.sock, &readfds))
- {
- data19 *req = (data19*)calloc(1, sizeof(data19));
- if (req)
- {
- req->sockLen = sizeof(req->addr);
- errno = 0;
- req->sock = accept(cfig.httpConn.sock, (sockaddr*)&req->addr, &req->sockLen);
- if (req->sock == INVALID_SOCKET)
- {
- sprintf(logBuff, "Accept Failed, Error=%sn", strerror(errno));
- logDHCPMess(logBuff, 1);
- free(req);
- }
- else
- procHTTP(req);
- }
- else
- {
- sprintf(logBuff, "Memory Error");
- logDHCPMess(logBuff, 0);
- }
- }
- if (cfig.replication && FD_ISSET(cfig.dhcpReplConn.sock, &readfds))
- {
- //printf("Repln");
- dhcpr.sockLen = sizeof(dhcpr.addr);
- dhcpr.bytes = recvfrom(cfig.dhcpReplConn.sock,
- dhcpr.raw,
- sizeof(dhcpr.raw),
- 0,
- (sockaddr*)&dhcpr.addr,
- &dhcpr.sockLen);
- }
- for (int i = 0; i < MAX_SERVERS && cfig.dhcpConn[i].server; i++)
- {
- if (FD_ISSET(cfig.dhcpConn[i].sock, &readfds) && gdmess(&dhcpr, i) && sdmess(&dhcpr))
- alad(&dhcpr);
- }
- if (FD_ISSET(cfig.dhcpListener.sock, &readfds) && gdmess(&dhcpr, 255) && sdmess(&dhcpr))
- alad(&dhcpr);
- }
- if (dnsService)
- {
- for (int i = 0; i < MAX_SERVERS && cfig.dnsUdpConn[i].server; i++)
- {
- if (FD_ISSET(cfig.dnsUdpConn[i].sock, &readfds) && gdnmess(&dnsr, i))
- {
- if (dnsr.dnsp->header.rcode == RCODE_NOTIMPL || dnsr.dnsp->header.rcode == RCODE_REFUSED)
- {
- sdnmess(&dnsr);
- }
- else if (scanloc(&dnsr))
- {
- if (htons(dnsr.dnsp->header.ancount))
- {
- if (cfig.dnsLogLevel == 2)
- {
- if (dnsr.qtype == DNS_TYPE_SOA)
- sprintf(logBuff, "SOA Sent for zone %s", dnsr.query);
- else if (dnsr.qtype == DNS_TYPE_NS)
- sprintf(logBuff, "NS Sent for zone %s", dnsr.query);
- else if (dnsr.cache.dataType == CACHED)
- sprintf(logBuff, "%s resolved from Cache to %s", dnsr.query, getResult(&dnsr));
- else
- sprintf(logBuff, "%s resolved Locally to %s", dnsr.query, getResult(&dnsr));
- logDNSMess(&dnsr, logBuff, 2);
- }
- }
- else if (dnsr.dnsp->header.rcode == RCODE_NAMEERROR || dnsr.dnsp->header.rcode == RCODE_NOERROR)
- {
- dnsr.dnsp->header.rcode = RCODE_NAMEERROR;
- if (cfig.dnsLogLevel == 2)
- {
- sprintf(logBuff, "%s not found", dnsr.query);
- logDNSMess(&dnsr, logBuff, 2);
- }
- }
- sdnmess(&dnsr);
- }
- else if (!fdnmess(&dnsr))
- {
- sdnmess(&dnsr);
- }
- }
- }
- for (int i = 0; i < MAX_SERVERS && cfig.dnsTcpConn[i].server; i++)
- {
- if (FD_ISSET(cfig.dnsTcpConn[i].sock, &readfds))
- {
- dnsr.sockInd = i;
- dnsr.sockLen = sizeof(dnsr.addr);
- errno = 0;
- dnsr.sock = accept(cfig.dnsTcpConn[i].sock, (sockaddr*)&dnsr.addr, &dnsr.sockLen);
- if (dnsr.sock == INVALID_SOCKET)
- {
- if (cfig.dhcpLogLevel)
- {
- sprintf(logBuff, "Accept Failed, Error=%sn", strerror(errno));
- logDNSMess(logBuff, 1);
- }
- }
- else
- procTCP(&dnsr);
- }
- }
- if (FD_ISSET(cfig.forwConn.sock, &readfds))
- {
- if (frdnmess(&dnsr))
- {
- sdnmess(&dnsr);
- if (cfig.dnsLogLevel == 2)
- {
- if (dnsr.cache.dnsIndex < MAX_SERVERS)
- {
- if (dnsr.dnsp->header.ancount)
- {
- if (getResult(&dnsr))
- sprintf(logBuff, "%s resolved from Forwarding server as %s", dnsr.query, tempbuff);
- else
- sprintf(logBuff, "%s resolved from Forwarding server", dnsr.query);
- }
- else
- sprintf(logBuff, "%s not found by Forwarding Server", dnsr.query);
- }
- else
- {
- if (dnsr.dnsp->header.ancount)
- {
- if (getResult(&dnsr))
- sprintf(logBuff, "%s resolved from Child Server as %s", dnsr.query, tempbuff);
- else
- sprintf(logBuff, "%s resolved from Child Server", dnsr.query);
- }
- else
- sprintf(logBuff, "%s not found by Child Server", dnsr.query);
- }
- logDNSMess(&dnsr, logBuff, 2);
- }
- }
- }
- }
- }
- cacheInd = newInd;
- checkSize(cacheInd);
- }
- }
- closeConn();
- }
- void closeConn()
- {
- kRunning = false;
- sprintf(logBuff, "Closing Network Connections...");
- logMess(logBuff, 1);
- if (dhcpService)
- {
- for (int i = 0; i < MAX_SERVERS && cfig.dhcpConn[i].server; i++)
- close(cfig.dhcpConn[i].sock);
- close(cfig.dhcpListener.sock);
- if (cfig.replication)
- close(cfig.dhcpReplConn.sock);
- }
- if (dnsService)
- {
- for (int i = 0; i < MAX_SERVERS && cfig.dnsUdpConn[i].server; i++)
- close(cfig.dnsUdpConn[i].sock);
- for (int i = 0; i < MAX_SERVERS && cfig.dnsTcpConn[i].server; i++)
- close(cfig.dnsTcpConn[i].sock);
- close(cfig.forwConn.sock);
- }
- sprintf(logBuff, "Dual Server Stopped !n");
- logMess(logBuff, 1);
- if (cfig.logfile)
- fclose(cfig.logfile);
- exit(EXIT_SUCCESS);
- }
- void catch_int(int sig_num)
- {
- closeConn();
- }
- bool chkQu(char *query)
- {
- if (strlen(query) >= 255)
- return 0;
- while (true)
- {
- char *dp = strchr(query, '.');
- if (dp)
- {
- WORD size = (DWORD)dp - (DWORD)query;
- if (size >= 64)
- return 0;
- query += (size + 1);
- }
- else if (strlen(query) >= 64)
- return 0;
- else
- return 1;
- }
- }
- WORD fQu(char *query, dnsPacket *mess, char *raw)
- {
- BYTE *xname = (BYTE*)query;
- BYTE *xraw = (BYTE*)raw;
- WORD retvalue = 0;
- bool goneout = false;
- while (true)
- {
- BYTE size = *xraw;
- xraw++;
- if (!size)
- {
- break;
- }
- else if (size <= 63)
- {
- if (!goneout)
- retvalue += (size + 1);
- memcpy(xname, xraw, size);
- xname += size;
- xraw += size;
- if (!*xraw)
- break;
- *xname = '.';
- xname++;
- }
- else
- {
- if (!goneout)
- retvalue += 2;
- goneout = true;
- size %= 128;
- size %= 64;
- size *= 256;
- size += *xraw;
- xraw = (BYTE*)mess + size;
- }
- }
- *xname = 0;
- if (!goneout)
- retvalue++;
- return retvalue;
- }
- WORD qLen(char *query)
- {
- WORD fullsize = 1;
- while (true)
- {
- char *i = strchr(query, '.');
- if (i != NULL)
- {
- int size = (DWORD)i - (DWORD)query;
- query += (size + 1);
- fullsize += (size + 1);
- }
- else
- {
- int size = strlen(query);
- if (size)
- fullsize += (size + 1);
- break;
- }
- }
- //printf("%in",fullsize);
- return fullsize;
- }
- WORD pQu(char *raw, char *query)
- {
- WORD fullsize = 1;
- while (true)
- {
- char *i = strchr(query, '.');
- if (i != NULL)
- {
- int size = (DWORD)i - (DWORD)query;
- *raw = size;
- raw++;
- memcpy(raw, query, size);
- raw += size;
- query += (size + 1);
- fullsize += (size + 1);
- }
- else
- {
- int size = strlen(query);
- if (size)
- {
- *raw = size;
- raw++;
- strcpy(raw, query);
- fullsize += (size + 1);
- }
- break;
- }
- }
- //printf("%in",fullsize);
- return fullsize;
- }
- WORD fUShort(void *raw)
- {
- return ntohs(*(WORD*)raw);
- }
- DWORD fULong(void *raw)
- {
- return ntohl(*(DWORD*)raw);
- }
- DWORD fIP(void *raw)
- {
- return (*(DWORD*)raw);
- }
- BYTE pUShort(void *raw, WORD data)
- {
- *((WORD*)raw) = htons(data);
- return 2;
- }
- BYTE pULong(void *raw, DWORD data)
- {
- *((DWORD*)raw) = htonl(data);
- return 4;
- }
- BYTE pIP(void *raw, DWORD data)
- {
- *((DWORD*)raw) = data;
- return 4;
- }
- void addRRNone(data5 *req)
- {
- if (cfig.dns[0])
- req->dnsp->header.ra = 1;
- else
- req->dnsp->header.ra = 0;
- req->dnsp->header.at = 0;
- req->dnsp->header.aa = 0;
- req->dnsp->header.qr = 1;
- req->dnsp->header.ancount = 0;
- req->dnsp->header.nscount = 0;
- req->dnsp->header.adcount = 0;
- }
- void addRRExt(data5 *req)
- {
- //printf("%u=%un", req->cache.dataType, CACHED);
- WORD xid = req->dnsp->header.xid;
- if (strcasecmp(req->cname, req->query))
- {
- dnsPacket *packet;
- if (req->cache.dataType == CACHED && req->cache.response)
- packet = (dnsPacket*)req->cache.response;
- else
- {
- memcpy(req->temp, req->dnsp, req->bytes);
- packet = (dnsPacket*)req->temp;
- }
- req->dnsp->header.aa = 0;
- req->dnsp->header.at = 0;
- req->dnsp->header.qdcount = htons(1);
- req->dnsp->header.ancount = htons(1);
- //manuplate the response
- req->data = &req->dnsp->data;
- req->data += pQu(req->data, req->query);
- req->data += pUShort(req->data, DNS_TYPE_A);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pQu(req->data, req->query);
- req->data += pUShort(req->data, DNS_TYPE_CNAME);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, qLen(req->cname));
- req->data += pQu(req->data, req->cname);
- char *dp = &packet->data;
- for (int i = 1; i <= ntohs(packet->header.qdcount); i++)
- {
- dp += fQu(req->cname, packet, dp);
- dp += 4;
- }
- WORD dl = 0;
- for (int i = 1; i <= ntohs(packet->header.ancount); i++)
- {
- dp += fQu(req->cname, packet, dp);
- req->data += pQu(req->data, req->cname);
- memcpy(req->data, dp, 8);
- req->data += 8;
- int type = fUShort(dp);
- dp += 2; //type
- dp += 2; //class
- dp += 4; //ttl
- WORD zLen = fUShort(dp);
- dp += 2; //datalength
- switch (type)
- {
- case DNS_TYPE_A:
- req->data += pUShort(req->data, zLen);
- req->data += pULong(req->data, fULong(dp));
- break;
- case DNS_TYPE_CNAME:
- fQu(req->cname, packet, dp);
- dl = pQu(req->data + 2, req->cname);
- req->data += pUShort(req->data, dl);
- req->data += dl;
- break;
- }
- dp += zLen;
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- }
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- else if (req->cache.dataType == CACHED && req->cache.response)
- {
- memcpy(req->dnsp, req->cache.response, req->cache.bytes);
- req->dnsp->header.xid = xid;
- req->bytes = req->cache.bytes;
- }
- }
- void addRRA(data5 *req)
- {
- if (strcasecmp(req->query, req->cname))
- {
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- req->data += pQu(req->data, req->query);
- req->data += pUShort(req->data, DNS_TYPE_CNAME);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, qLen(req->cname));
- req->data += pQu(req->data, req->cname);
- }
- for (;req->iterBegin != dnsCache[cacheInd].end(); req->iterBegin++)
- {
- data7 *cache = req->iterBegin->second;
- if (strcasecmp(cache->mapname, req->mapname))
- break;
- if (cache->ip)
- {
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- req->data += pQu(req->data, req->cname);
- req->data += pUShort(req->data, DNS_TYPE_A);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- if (cache->dataType == LOCAL_A)
- {
- if (cache->expiry == LONG_MAX)
- req->data += pULong(req->data, ULONG_MAX);
- else if ((DWORD)(cache->expiry - time(NULL)) >= cfig.lease)
- req->data += pULong(req->data, cfig.lease - 1);
- else
- req->data += pULong(req->data, (cache->expiry - time(NULL)));
- }
- else
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, 4);
- req->data += pIP(req->data, cache->ip);
- }
- }
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRPtr(data5 *req)
- {
- for (;req->iterBegin != dnsCache[cacheInd].end(); req->iterBegin++)
- {
- data7 *cache = req->iterBegin->second;
- if (strcasecmp(cache->mapname, req->mapname))
- break;
- req->data += pQu(req->data, req->query);
- req->data += pUShort(req->data, DNS_TYPE_PTR);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- if (cache->dataType == LOCAL_PTR_AUTH || cache->dataType == LOCAL_PTR_NAUTH)
- {
- if (cache->expiry == LONG_MAX)
- req->data += pULong(req->data, ULONG_MAX);
- else if ((DWORD)(cache->expiry - time(NULL)) >= cfig.lease)
- req->data += pULong(req->data, cfig.lease - 1);
- else
- req->data += pULong(req->data, (cache->expiry - time(NULL)));
- }
- else
- req->data += pULong(req->data, cfig.lease);
- if (!strchr(cache->hostname, '.'))
- sprintf(req->cname, "%s.%s", cache->hostname, cfig.zone);
- else
- strcpy(req->cname, cache->hostname);
- req->data += pUShort(req->data, qLen(req->cname));
- req->data += pQu(req->data, req->cname);
- }
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRServerA(data5 *req)
- {
- if (strcasecmp(req->query, req->cname))
- {
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- req->data += pQu(req->data, req->query);
- req->data += pUShort(req->data, DNS_TYPE_CNAME);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, qLen(req->cname));
- req->data += pQu(req->data, req->cname);
- }
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- req->data += pQu(req->data, req->cname);
- req->data += pUShort(req->data, DNS_TYPE_A);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, 4);
- req->data += pIP(req->data, cfig.dnsUdpConn[req->sockInd].server);
- for (;req->iterBegin != dnsCache[cacheInd].end(); req->iterBegin++)
- {
- data7 *cache = req->iterBegin->second;
- if (strcasecmp(cache->mapname, req->mapname))
- break;
- if (cache->ip && cache->ip != cfig.dnsUdpConn[req->sockInd].server)
- {
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- req->data += pQu(req->data, req->cname);
- req->data += pUShort(req->data, DNS_TYPE_A);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, 4);
- req->data += pIP(req->data, cache->ip);
- }
- }
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRWildA(data5 *req, DWORD ip)
- {
- req->dnsp->header.ancount = htons(1);
- req->data += pQu(req->data, req->query);
- req->data += pUShort(req->data, DNS_TYPE_A);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, 4);
- req->data += pIP(req->data, ip);
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRLocalhostA(data5 *req)
- {
- if (strcasecmp(req->query, req->mapname))
- {
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- req->data += pQu(req->data, req->query);
- req->data += pUShort(req->data, DNS_TYPE_CNAME);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, qLen(req->mapname));
- req->data += pQu(req->data, req->mapname);
- }
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- req->data += pQu(req->data, req->mapname);
- req->data += pUShort(req->data, DNS_TYPE_A);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, 4);
- req->data += pIP(req->data, req->cache.ip);
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRLocalhostPtr(data5 *req)
- {
- req->data += pQu(req->data, req->query);
- req->data += pUShort(req->data, DNS_TYPE_PTR);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->dnsp->header.ancount = htons(1);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, qLen(req->cache.hostname));
- req->data += pQu(req->data, req->cache.hostname);
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRMX(data5 *req)
- {
- req->dnsp->header.ancount = 0;
- if (cfig.mxCount[cacheInd])
- {
- for (int m = 0; m < cfig.mxCount[cacheInd]; m++)
- {
- //req->data += pQu(req->data, req->query);
- req->data += pQu(req->data, cfig.zone);
- req->data += pUShort(req->data, DNS_TYPE_MX);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, strlen(cfig.mxServers[cacheInd][m].hostname) + 4);
- req->data += pUShort(req->data, cfig.mxServers[cacheInd][m].pref);
- req->data += pQu(req->data, cfig.mxServers[cacheInd][m].hostname);
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- }
- }
- else
- req->dnsp->header.rcode = RCODE_NAMEERROR;
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRNSA(data5 *req)
- {
- //printf("%s=%un", cfig.ns, cfig.expireTime);
- if (cfig.authorized && cfig.expireTime > time(NULL))
- {
- req->dnsp->header.at = 1;
- req->dnsp->header.aa = 1;
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- req->data += pQu(req->data, cfig.zone);
- req->data += pUShort(req->data, DNS_TYPE_NS);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.expire);
- req->data += pUShort(req->data, qLen(cfig.ns));
- req->data += pQu(req->data, cfig.ns);
- req->data += pQu(req->data, cfig.servername_fqn);
- req->data += pUShort(req->data, DNS_TYPE_A);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.expire);
- req->data += pUShort(req->data, 4);
- req->data += pIP(req->data, cfig.nsIP);
- }
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRNSPtr(data5 *req)
- {
- if (cfig.authorized && cfig.expireTime > time(NULL))
- {
- req->dnsp->header.at = 1;
- req->dnsp->header.aa = 1;
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- req->data += pQu(req->data, cfig.authority);
- req->data += pUShort(req->data, DNS_TYPE_NS);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.expire);
- req->data += pUShort(req->data, qLen(cfig.ns));
- req->data += pQu(req->data, cfig.ns);
- req->data += pQu(req->data, cfig.ns);
- req->data += pUShort(req->data, DNS_TYPE_A);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.expire);
- req->data += pUShort(req->data, 4);
- req->data += pIP(req->data, cfig.nsIP);
- }
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRSOA(data5 *req, DWORD serial)
- {
- if (cfig.authorized)
- {
- req->dnsp->header.at = 1;
- req->dnsp->header.aa = 1;
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- req->data += pQu(req->data, req->query);
- req->data += pUShort(req->data, DNS_TYPE_SOA);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- char *data = req->data;
- req->data += 2;
- req->data += pQu(req->data, cfig.ns);
- sprintf(req->cname, "hostmaster.%s", cfig.zone);
- req->data += pQu(req->data, req->cname);
- req->data += pULong(req->data, serial);
- req->data += pULong(req->data, cfig.refresh);
- req->data += pULong(req->data, cfig.retry);
- req->data += pULong(req->data, cfig.expire);
- req->data += pULong(req->data, cfig.minimum);
- pUShort(data, ((DWORD)req->data - (DWORD)data) - 2);
- }
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addAuth(data5 *req)
- {
- if (cfig.authorized && cfig.expireTime > time(NULL))
- {
- req->dnsp->header.at = 1;
- req->dnsp->header.aa = 1;
- req->dnsp->header.nscount = htons(1);
- if (req->qtype == DNS_TYPE_PTR)
- req->data += pQu(req->data, cfig.authority);
- else
- req->data += pQu(req->data, cfig.zone);
- req->data += pUShort(req->data, DNS_TYPE_NS);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- if (cfig.expire >= LONG_MAX)
- req->data += pULong(req->data, ULONG_MAX);
- else
- req->data += pULong(req->data, cfig.expire);
- req->data += pUShort(req->data, qLen(cfig.ns));
- req->data += pQu(req->data, cfig.ns);
- addRRAd(req);
- }
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRAd(data5 *req)
- {
- if (cfig.authorized && cfig.expireTime > time(NULL))
- {
- req->dnsp->header.adcount = htons(1);
- req->data += pQu(req->data, cfig.ns);
- req->data += pUShort(req->data, DNS_TYPE_A);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, 4);
- req->data += pIP(req->data, cfig.nsIP);
- }
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRAOne(data5 *req)
- {
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- if (!strchr(req->iterBegin->second->mapname, '.'))
- sprintf(req->cname, "%s.%s", req->iterBegin->second->mapname, cfig.zone);
- else
- strcpy(req->cname, req->iterBegin->second->mapname);
- req->data += pQu(req->data, req->cname);
- req->data += pUShort(req->data, DNS_TYPE_A);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- if (req->iterBegin->second->dataType == LOCAL_A)
- {
- if (req->iterBegin->second->expiry == LONG_MAX)
- req->data += pULong(req->data, ULONG_MAX - 1);
- else if ((DWORD)(req->iterBegin->second->expiry - time(NULL)) >= cfig.lease)
- req->data += pULong(req->data, cfig.lease - 1);
- else
- req->data += pULong(req->data, (req->iterBegin->second->expiry - time(NULL)));
- }
- else
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, 4);
- req->data += pIP(req->data, req->iterBegin->second->ip);
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRPtrOne(data5 *req)
- {
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- strcpy(req->cname, req->iterBegin->second->mapname);
- strcat(req->cname, arpa);
- req->data += pQu(req->data, req->cname);
- req->data += pUShort(req->data, DNS_TYPE_PTR);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- if (req->iterBegin->second->dataType == LOCAL_PTR_AUTH || req->iterBegin->second->dataType == LOCAL_PTR_NAUTH)
- {
- if (req->iterBegin->second->expiry == LONG_MAX)
- req->data += pULong(req->data, ULONG_MAX - 1);
- else if ((DWORD)(req->iterBegin->second->expiry - time(NULL)) >= cfig.lease)
- req->data += pULong(req->data, cfig.lease - 1);
- else
- req->data += pULong(req->data, (req->iterBegin->second->expiry - time(NULL)));
- }
- else
- req->data += pULong(req->data, cfig.lease);
- if (!strchr(req->iterBegin->second->hostname, '.'))
- sprintf(req->cname, "%s.%s", req->iterBegin->second->hostname, cfig.zone);
- else
- strcpy(req->cname, req->iterBegin->second->hostname);
- req->data += pUShort(req->data, qLen(req->cname));
- req->data += pQu(req->data, req->cname);
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRSTAOne(data5 *req)
- {
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- if (!strchr(req->iterBegin->second->mapname, '.'))
- sprintf(req->cname, "%s.%s", req->iterBegin->second->mapname, cfig.zone);
- else
- strcpy(req->cname, req->iterBegin->second->mapname);
- req->data += pQu(req->data, req->cname);
- req->data += pUShort(req->data, DNS_TYPE_A);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, 4);
- req->data += pIP(req->data, req->iterBegin->second->ip);
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRCNOne(data5 *req)
- {
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- if (!strchr(req->iterBegin->second->mapname, '.'))
- sprintf(req->cname, "%s.%s", req->iterBegin->second->mapname, cfig.zone);
- else
- strcpy(req->cname, req->iterBegin->second->mapname);
- req->data += pQu(req->data, req->cname);
- req->data += pUShort(req->data, DNS_TYPE_CNAME);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- if (!strchr(req->iterBegin->second->hostname, '.'))
- sprintf(req->cname, "%s.%s", req->iterBegin->second->hostname, cfig.zone);
- else
- strcpy(req->cname, req->iterBegin->second->hostname);
- req->data += pUShort(req->data, qLen(req->cname));
- req->data += pQu(req->data, req->cname);
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void addRRMXOne(data5 *req, BYTE m)
- {
- //req->data += pQu(req->data, req->query);
- req->data += pQu(req->data, cfig.zone);
- req->data += pUShort(req->data, DNS_TYPE_MX);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->data += pULong(req->data, cfig.lease);
- req->data += pUShort(req->data, strlen(cfig.mxServers[cacheInd][m].hostname) + 4);
- req->data += pUShort(req->data, cfig.mxServers[cacheInd][m].pref);
- req->data += pQu(req->data, cfig.mxServers[cacheInd][m].hostname);
- req->dnsp->header.ancount = htons(htons(req->dnsp->header.ancount) + 1);
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- void procHTTP(data19 *req)
- {
- req->ling.l_onoff = 1; //0 = off (l_linger ignored), nonzero = on
- req->ling.l_linger = 30; //0 = discard data, nonzero = wait for data sent
- setsockopt(req->sock, SOL_SOCKET, SO_LINGER, &req->ling, sizeof(req->ling));
- errno = 0;
- req->bytes = recv(req->sock, tempbuff, sizeof(tempbuff), 0);
- //errno = WSAGetLastError();
- if (errno)
- {
- sprintf(logBuff, "Error %s Receiving HTTP Message from Client %s", strerror(errno), IP2String(tempbuff, req->addr.sin_addr.s_addr));
- logDHCPMess(logBuff, 1);
- closesocket(req->sock);
- free(req);
- return;
- }
- else if (cfig.dhcpLogLevel >= 2)
- {
- sprintf(logBuff, "HTTP Request Received from Client %s", IP2String(tempbuff, req->addr.sin_addr.s_addr));
- logDHCPMess(logBuff, 2);
- }
- time_t t = time(NULL);
- BYTE bp_chaddr[16];
- const char line200[] = "<td>%s</td>";
- dhcpMap::iterator p;
- int ind = 0;
- DWORD iip = 0;
- data7 *dhcpEntry = NULL;
- data7 *cache = NULL;
- DWORD memSize = 2048 + (135 * dhcpCache.size()) + ((cfig.dhcpSize - dhcpCache.size()) * 26);
- req->buffer = (char*)calloc(1, memSize);
- if (!req->buffer)
- {
- sprintf(logBuff, "Memory Error");
- logDHCPMess(logBuff, 0);
- closesocket(req->sock);
- free(req);
- return;
- }
- char *fp = req->buffer;
- char *maxData = req->buffer + (memSize - 512);
- tm *ttm = gmtime(&t);
- strftime(tempbuff, sizeof(tempbuff), "%a, %d %b %Y %H:%M:%S GMT", ttm);
- fp += sprintf(fp, send200, tempbuff, tempbuff);
- char *contentStart = fp;
- 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");
- fp += sprintf(fp, "<body bgcolor="#cccccc">n<h2>%s</h2>n", sVersion);
- fp += sprintf(fp, "<table border="1" width="600" bgcolor="#b8b8b8">n");
- fp += sprintf(fp, "<tr><th colspan="5"><font size="5"><i>Active Leases</i></font></th></tr>n");
- fp += sprintf(fp, "<tr><th>Mac Address</th><th>IP</th><th>Lease Expiry</th><th>Hostname (first 20 chars)</th></tr>n");
- for (p = dhcpCache.begin(); p != dhcpCache.end() && fp < maxData; p++)
- {
- if ((dhcpEntry = p->second) && dhcpEntry->active && dhcpEntry->expiry >= t)
- {
- fp += sprintf(fp, "<tr>");
- BYTE bp_hlen = fromUUE(bp_chaddr, dhcpEntry->mapname);
- fp += sprintf(fp, line200, hex2String(tempbuff, bp_chaddr, bp_hlen, ':'));
- fp += sprintf(fp, line200, IP2String(tempbuff, dhcpEntry->ip));
- if (dhcpEntry->expiry >= LONG_MAX)
- fp += sprintf(fp, line200, "Infinity");
- else
- {
- tm *ttm = localtime(&dhcpEntry->expiry);
- strftime(tempbuff, sizeof(tempbuff), "%d-%b-%y %X", ttm);
- fp += sprintf(fp, line200, tempbuff);
- }
- cache = findEntry(cacheInd, IP2String(tempbuff, htonl(dhcpEntry->ip)));
- if (cache && cache->hostname)
- {
- if (strlen(cache->hostname) <= 20)
- fp += sprintf(fp, line200, cache->hostname);
- else
- {
- memcpy(tempbuff, cache->hostname, 20);
- tempbuff[20] = 0;
- fp += sprintf(fp, line200, tempbuff);
- }
- }
- else
- fp += sprintf(fp, line200, " ");
- fp += sprintf(fp, "</tr>n");
- }
- }
- fp += sprintf(fp, "</table>n<br>n<table border="1" width="600" bgcolor="#b8b8b8">n");
- fp += sprintf(fp, "<tr><th colspan="5"><font size="5"><i>Free Dynamic Leases</i></font></th></tr>n");
- BYTE colNum = 0;
- for (char rangeInd = 0; rangeInd < 32 && cfig.dhcpRanges[rangeInd].rangeStart && fp < maxData; rangeInd++)
- {
- for (ind = 0, iip = cfig.dhcpRanges[rangeInd].rangeStart; iip <= cfig.dhcpRanges[rangeInd].rangeEnd; iip++, ind++)
- {
- if (cfig.dhcpRanges[rangeInd].expiry[ind] < t)
- {
- if (!colNum)
- {
- fp += sprintf(fp, "<tr>");
- colNum = 1;
- }
- else if (colNum < 5)
- colNum++;
- else
- {
- fp += sprintf(fp, "</tr>n<tr>");
- colNum = 1;
- }
- fp += sprintf(fp, line200, IP2String(tempbuff, htonl(iip)));
- }
- }
- }
- if (colNum)
- fp += sprintf(fp, "</tr>n");
- fp += sprintf(fp, "</table>n<br>n<table border="1" width="600" bgcolor="#b8b8b8">n");
- fp += sprintf(fp, "<tr><th colspan="5"><font size="5"><i>Free Static Leases</i></font></th></tr>n");
- fp += sprintf(fp, "<tr><th>Mac Address</th><th>IP</th><th>Mac Address</th><th>IP</th></tr>n");
- colNum = 0;
- for (p = dhcpCache.begin(); p != dhcpCache.end() && fp < maxData; p++)
- {
- if ((dhcpEntry = p->second) && dhcpEntry->fixed && dhcpEntry->expiry < t)
- {
- if (!colNum)
- {
- fp += sprintf(fp, "<tr>");
- colNum = 1;
- }
- else if (colNum == 1)
- {
- colNum = 2;
- }
- else if (colNum == 2)
- {
- fp += sprintf(fp, "</tr>n<tr>");
- colNum = 1;
- }
- BYTE bp_hlen = fromUUE(bp_chaddr, dhcpEntry->mapname);
- fp += sprintf(fp, line200, hex2String(tempbuff, bp_chaddr, bp_hlen, ':'));
- fp += sprintf(fp, line200, IP2String(tempbuff, dhcpEntry->ip));
- }
- }
- if (colNum)
- fp += sprintf(fp, "</tr>n");
- fp += sprintf(fp, "</table>n</body>n</html>");
- memcpy((contentStart - 12), tempbuff, sprintf(tempbuff, "%u", (fp - contentStart)));
- req->bytes = fp - req->buffer;
- pthread_t threadId;
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- int errcode = pthread_create(&threadId, &attr, sendHTTP, (void*)req);
- pthread_attr_destroy(&attr);
- if(errcode)
- {
- if (cfig.dhcpLogLevel)
- {
- sprintf(logBuff, "Thread Creation Failed");
- logDHCPMess(logBuff, 1);
- }
- send(req->sock, req->buffer, req->bytes, 0);
- closesocket(req->sock);
- free(req->buffer);
- free(req);
- }
- return;
- }
- void *sendHTTP(void *lpParam)
- {
- data19 *req = (data19*)lpParam;
- send(req->sock, req->buffer, req->bytes, 0);
- sleep(20);
- closesocket(req->sock);
- free(req->buffer);
- free(req);
- pthread_exit(NULL);
- }
- void procTCP(void *lpParam)
- {
- //printf("Heren");
- data5 *req = (data5*)lpParam;
- req->ling.l_onoff = 1; //0 = off (l_linger ignored), nonzero = on
- req->ling.l_linger = 10; //0 = discard data, nonzero = wait for data sent
- setsockopt(req->sock, SOL_SOCKET, SO_LINGER, (const char*)&req->ling, sizeof(req->ling));
- errno = 0;
- req->bytes = recvTcpDnsMess(req->sock, req->raw, true);
- //printf("%un",req->bytes);
- if (req->bytes < 2)
- {
- sprintf(logBuff, "Error Getting TCP DNS Message");
- logDNSMess(logBuff, 1);
- closesocket(req->sock);
- return;
- }
- WORD pktSize = fUShort(req->raw);
- req->data = req->raw + 2;
- req->dnsp = (dnsPacket*)(req->data);
- if (req->dnsp->header.opcode != OPCODE_STANDARD_QUERY)
- {
- switch (req->dnsp->header.opcode)
- {
- case OPCODE_INVERSE_QUERY:
- sprintf(logBuff, "Inverse query not supported");
- break;
- case OPCODE_SRVR_STAT_REQ:
- sprintf(logBuff, "Server Status Request not supported");
- break;
- case OPCODE_NOTIFY:
- sprintf(logBuff, "Notify not supported");
- break;
- case OPCODE_DYNAMIC_UPDATE:
- sprintf(logBuff, "Dynamic Update not needed/supported by Dual Server");
- break;
- default:
- sprintf(logBuff, "OpCode %u not supported", req->dnsp->header.opcode);
- }
- logTCPMess(req, logBuff, 1);
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NOTIMPL;
- sTCPmess(req);
- closesocket(req->sock);
- return;
- }
- if (req->dnsp->header.qr != 0 || ntohs(req->dnsp->header.qdcount) != 1 || ntohs(req->dnsp->header.ancount))
- {
- sprintf(logBuff, "DNS Query Format Error");
- logTCPMess(req, logBuff, 1);
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_FORMATERROR;
- sTCPmess(req);
- closesocket(req->sock);
- return;
- }
- req->data = &req->dnsp->data;
- for (int i = 1; i <= ntohs(req->dnsp->header.qdcount); i++)
- {
- req->data += fQu(req->query, req->dnsp, req->data);
- req->qtype = fUShort(req->data);
- req->data += 2;
- req->qclass = fUShort(req->data);
- req->data += 2;
- }
- if (req->qclass != DNS_CLASS_IN)
- {
- sprintf(logBuff, "DNS Class %u not supported", req->qclass);
- logTCPMess(req, logBuff, 1);
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NOTIMPL;
- sTCPmess(req);
- closesocket(req->sock);
- return;
- }
- if (!req->qtype)
- {
- sprintf(logBuff, "missing query type");
- logTCPMess(req, logBuff, 1);
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_FORMATERROR;
- sTCPmess(req);
- closesocket(req->sock);
- return;
- }
- bool allowed = false;
- DWORD ip = req->addr.sin_addr.s_addr;
- for (int i = 0; i < MAX_SERVERS; i++)
- {
- if (ip == cfig.zoneServers[i] || ip == cfig.allServers[i])
- {
- allowed = true;
- break;
- }
- }
- if (!allowed)
- {
- sprintf(logBuff, "DNS TCP Query, Access Denied");
- logTCPMess(req, logBuff, 1);
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_REFUSED;
- sTCPmess(req);
- closesocket(req->sock);
- return;
- }
- strcpy(req->mapname, req->query);
- strcpy(req->cname, req->query);
- bool AXFRError = false;
- if (req->qtype != DNS_TYPE_NS && req->qtype != DNS_TYPE_SOA && req->qtype != DNS_TYPE_AXFR && req->qtype != DNS_TYPE_IXFR)
- {
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NOTIMPL;
- sTCPmess(req);
- sprintf(logBuff, "DNS TCP Query Type %s not supported", strqtype(tempbuff, req->qtype));
- logTCPMess(req, logBuff, 1);
- }
- else if (strcasecmp(req->mapname, cfig.zone) && strcasecmp(req->mapname, cfig.authority))
- {
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NOTIMPL;
- sTCPmess(req);
- sprintf(logBuff, "%s, Forwarding TCP query not supported", req->query);
- logTCPMess(req, logBuff, 1);
- }
- else if (!cfig.authorized)
- {
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NOTAUTH;
- sTCPmess(req);
- sprintf(logBuff, "Server is not authorized for zone %s", req->query);
- logTCPMess(req, logBuff, 1);
- }
- else if (!dhcpService && cfig.expireTime < time(NULL))
- {
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NOTAUTH;
- sTCPmess(req);
- sprintf(logBuff, "Zone %s expired", req->query);
- logTCPMess(req, logBuff, 1);
- }
- else
- {
- switch (req->qtype)
- {
- case DNS_TYPE_SOA:
- if (!strcasecmp(req->query, cfig.zone))
- {
- addRRNone(req);
- req->dnsp->header.aa = 0;
- req->dnsp->header.at = 0;
- addRRSOA(req, cfig.serial1);
- sTCPmess(req);
- sprintf(logBuff, "SOA Sent for zone %s", req->query);
- logTCPMess(req, logBuff, 2);
- }
- else if (!strcasecmp(req->query, cfig.authority))
- {
- addRRNone(req);
- req->dnsp->header.aa = 0;
- req->dnsp->header.at = 0;
- addRRSOA(req, cfig.serial2);
- sTCPmess(req);
- sprintf(logBuff, "SOA Sent for zone %s", req->query);
- logTCPMess(req, logBuff, 2);
- }
- break;
- case DNS_TYPE_NS:
- if (!strcasecmp(req->mapname, cfig.zone))
- {
- addRRNone(req);
- req->dnsp->header.aa = 0;
- req->dnsp->header.at = 0;
- addRRNSA(req);
- addRRAd(req);
- sTCPmess(req);
- sprintf(logBuff, "NS Sent for Zone %s", req->query);
- logTCPMess(req, logBuff, 2);
- }
- else if (!strcasecmp(req->query, cfig.authority))
- {
- addRRNone(req);
- req->dnsp->header.aa = 0;
- req->dnsp->header.at = 0;
- addRRNSPtr(req);
- addRRAd(req);
- sTCPmess(req);
- sprintf(logBuff, "NS Sent for Zone", req->query);
- logTCPMess(req, logBuff, 2);
- }
- break;
- case DNS_TYPE_AXFR:
- case DNS_TYPE_IXFR:
- if (!strcasecmp(req->mapname, cfig.zone))
- {
- DWORD tempserial = cfig.serial1;
- WORD records = 0;
- addRRNone(req);
- req->data = &req->dnsp->data;
- req->dnsp->header.qdcount = 0;
- addRRSOA(req, cfig.serial1);
- if (!sTCPmess(req))
- {
- AXFRError = true;
- break;
- }
- else
- records++;
- addRRNone(req);
- req->data = &req->dnsp->data;
- req->dnsp->header.qdcount = 0;
- addRRNSA(req);
- if (!sTCPmess(req))
- {
- AXFRError = true;
- break;
- }
- else
- records++;
- time_t t = time(NULL);
- req->iterBegin = dnsCache[cacheInd].begin();
- while (!AXFRError && req->iterBegin != dnsCache[cacheInd].end())
- {
- addRRNone(req);
- req->dnsp->header.qdcount = 0;
- req->data = &req->dnsp->data;
- if (req->iterBegin->second->expiry > t)
- {
- switch (req->iterBegin->second->dataType)
- {
- case LOCAL_A:
- addRRAOne(req);
- break;
- case SERVER_A:
- if (cfig.dnsTcpConn[req->sockInd].server == req->iterBegin->second->ip)
- {
- addRRSTAOne(req);
- }
- else
- {
- req->iterBegin++;
- continue;
- }
- break;
- case STATIC_A_AUTH:
- //case STATIC_A_NAUTH:
- addRRSTAOne(req);
- break;
- case LOCAL_CNAME:
- case EXT_CNAME:
- addRRCNOne(req);
- break;
- default:
- req->iterBegin++;
- continue;
- }
- if (tempserial != cfig.serial1)
- {
- AXFRError = true;
- break;
- }
- if (!sTCPmess(req))
- {
- AXFRError = true;
- break;
- }
- else
- records++;
- }
- req->iterBegin++;
- }
- for (int m = 0; m < cfig.mxCount[cacheInd]; m++)
- {
- addRRNone(req);
- req->dnsp->header.qdcount = 0;
- req->data = &req->dnsp->data;
- addRRMXOne(req, m);
- if (tempserial != cfig.serial1)
- {
- AXFRError = true;
- break;
- }
- if (!sTCPmess(req))
- {
- AXFRError = true;
- break;
- }
- else
- records++;
- }
- addRRNone(req);
- req->data = &req->dnsp->data;
- req->dnsp->header.qdcount = 0;
- addRRSOA(req, cfig.serial1);
- if (!AXFRError && tempserial == cfig.serial1)
- {
- if (sTCPmess(req))
- {
- records++;
- sprintf(logBuff, "Zone %s with %u RRs Sent", req->query, records);
- logTCPMess(req, logBuff, 2);
- }
- }
- }
- else if (!strcasecmp(req->query, cfig.authority))
- {
- DWORD tempserial = cfig.serial2;
- WORD records = 0;
- addRRNone(req);
- req->data = &req->dnsp->data;
- req->dnsp->header.qdcount = 0;
- addRRSOA(req, cfig.serial2);
- if (!sTCPmess(req))
- {
- AXFRError = true;
- break;
- }
- else
- records++;
- addRRNone(req);
- req->data = &req->dnsp->data;
- req->dnsp->header.qdcount = 0;
- addRRNSPtr(req);
- if (!sTCPmess(req))
- {
- AXFRError = true;
- break;
- }
- else
- records++;
- time_t t = time(NULL);
- req->iterBegin = dnsCache[cacheInd].begin();
- while (!AXFRError && req->iterBegin != dnsCache[cacheInd].end())
- {
- addRRNone(req);
- req->dnsp->header.qdcount = 0;
- req->data = &req->dnsp->data;
- if (req->iterBegin->second->expiry > t)
- {
- switch (req->iterBegin->second->dataType)
- {
- case LOCAL_PTR_AUTH:
- case STATIC_PTR_AUTH:
- addRRPtrOne(req);
- break;
- case SERVER_PTR_AUTH:
- if (cfig.dnsTcpConn[req->sockInd].server == ntohl(inet_addr(req->iterBegin->second->mapname)))
- {
- addRRPtrOne(req);
- }
- else
- {
- req->iterBegin++;
- continue;
- }
- break;
- default:
- req->iterBegin++;
- continue;
- }
- if (tempserial != cfig.serial2)
- {
- AXFRError = true;
- break;
- }
- if (!sTCPmess(req))
- {
- AXFRError = true;
- break;
- }
- else
- records++;
- }
- req->iterBegin++;
- }
- addRRNone(req);
- req->data = &req->dnsp->data;
- req->dnsp->header.qdcount = 0;
- addRRSOA(req, cfig.serial2);
- if (!AXFRError && tempserial == cfig.serial2)
- {
- if (sTCPmess(req))
- {
- records++;
- sprintf(logBuff, "Zone %s with %u RRs Sent", req->query, records);
- logTCPMess(req, logBuff, 2);
- }
- }
- }
- break;
- }
- }
- closesocket(req->sock);
- return;
- }
- WORD sTCPmess(data5 *req)
- {
- errno = 0;
- req->dnsp->header.ra = 0;
- pUShort(req->raw, req->bytes - 2);
- if (req->bytes != send(req->sock, req->raw, req->bytes, 0) || errno)
- return 0;
- return req->bytes;
- }
- WORD gdnmess(data5 *req, BYTE sockInd)
- {
- memset(req, 0, sizeof(data5));
- req->sockLen = sizeof(req->addr);
- errno = 0;
- req->bytes = recvfrom(cfig.dnsUdpConn[sockInd].sock,
- req->raw,
- sizeof(req->raw),
- 0,
- (sockaddr*)&req->addr,
- &req->sockLen);
- //errno = WSAGetLastError();
- if (errno || req->bytes <= 0)
- return 0;
- req->sockInd = sockInd;
- req->dnsp = (dnsPacket*)req->raw;
- if (req->dnsp->header.opcode != OPCODE_STANDARD_QUERY)
- {
- if (cfig.dnsLogLevel)
- {
- switch (req->dnsp->header.opcode)
- {
- case OPCODE_INVERSE_QUERY:
- sprintf(logBuff, "Inverse query not supported");
- break;
- case OPCODE_SRVR_STAT_REQ:
- sprintf(logBuff, "Server Status Request not supported");
- break;
- case OPCODE_NOTIFY:
- sprintf(logBuff, "Notify not supported");
- break;
- case OPCODE_DYNAMIC_UPDATE:
- sprintf(logBuff, "Dynamic Update not needed/supported by Dual Server");
- break;
- default:
- sprintf(logBuff, "OpCode %u not supported", req->dnsp->header.opcode);
- }
- logDNSMess(req, logBuff, 1);
- }
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NOTIMPL;
- return req->bytes;
- }
- if (req->dnsp->header.qr != 0 || ntohs(req->dnsp->header.qdcount) != 1 || ntohs(req->dnsp->header.ancount))
- {
- if (cfig.dnsLogLevel)
- {
- sprintf(logBuff, "DNS Query Format Error");
- logDNSMess(req, logBuff, 1);
- }
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_FORMATERROR;
- return req->bytes;
- }
- req->data = &req->dnsp->data;
- for (int i = 1; i <= ntohs(req->dnsp->header.qdcount); i++)
- {
- req->data += fQu(req->query, req->dnsp, req->data);
- req->qtype = fUShort(req->data);
- req->data += 2;
- req->qclass = fUShort(req->data);
- req->data += 2;
- }
- if (req->qclass != DNS_CLASS_IN)
- {
- if (cfig.dnsLogLevel)
- {
- sprintf(logBuff, "DNS Class %u not supported", req->qclass);
- logDNSMess(req, logBuff, 1);
- }
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NOTIMPL;
- return req->bytes;
- }
- if (!req->qtype)
- {
- if (cfig.dnsLogLevel)
- {
- sprintf(logBuff, "missing query type");
- logDNSMess(req, logBuff, 1);
- }
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_FORMATERROR;
- return req->bytes;
- }
- req->qLen = strlen(req->query);
- DWORD iip = ntohl(req->addr.sin_addr.s_addr);
- for (int i = 0; i < 32 && cfig.dnsRanges[i].rangeStart; i++)
- {
- if (iip >= cfig.dnsRanges[i].rangeStart && iip <= cfig.dnsRanges[i].rangeEnd)
- return req->bytes;
- }
- for (int i = 0; i < 32 && cfig.dhcpRanges[i].rangeStart; i++)
- {
- if (iip >= cfig.dhcpRanges[i].rangeStart && iip <= cfig.dhcpRanges[i].rangeEnd)
- return req->bytes;
- }
- if (findEntry(cacheInd, IP2String(req->cname, iip)))
- return req->bytes;
- if (req->addr.sin_addr.s_addr == cfig.zoneServers[0] || req->addr.sin_addr.s_addr == cfig.zoneServers[1])
- return req->bytes;
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_REFUSED;
- if (cfig.dnsLogLevel)
- {
- sprintf(logBuff, "DNS UDP Query, Access Denied");
- logDNSMess(req, logBuff, 1);
- }
- return req->bytes;
- }
- WORD sdnmess(data5 *req)
- {
- errno = 0;
- req->bytes = sendto(cfig.dnsUdpConn[req->sockInd].sock,
- req->raw,
- req->bytes,
- 0,
- (sockaddr*)&req->addr,
- sizeof(req->addr));
- //errno = WSAGetLastError();
- if (errno || req->bytes <= 0)
- return 0;
- return req->bytes;
- }
- WORD scanloc(data5 *req)
- {
- if (!req->query[0])
- return 0;
- strcpy(req->cname, req->query);
- strcpy(req->mapname, req->query);
- myLower(req->mapname);
- //printf("%sn",req->query);
- switch (req->qtype)
- {
- case DNS_TYPE_PTR:
- {
- char *dp = strstr(req->mapname, arpa);
- if (dp)
- *dp = 0;
- else
- return 0;
- }
- break;
- case DNS_TYPE_A:
- req->localCode = makeLocal(req->mapname);
- if (req->localCode == 1)
- {
- sprintf(req->cname, "%s.%s", req->query, cfig.zone);
- }
- break;
- case DNS_TYPE_MX:
- if (!strcasecmp(req->query, cfig.zone) && (cfig.authorized || cfig.mxServers[cacheInd][0].hostname[0]))
- {
- addRRNone(req);
- addRRMX(req);
- addAuth(req);
- return 1;
- }
- else
- return 0;
- break;
- case DNS_TYPE_NS:
- if (cfig.authorized)
- {
- if (!strcasecmp(req->query, cfig.authority))
- {
- addRRNone(req);
- addRRNSPtr(req);
- addRRAd(req);
- return 1;
- }
- else if (!strcasecmp(req->query, cfig.zone))
- {
- addRRNone(req);
- addRRNSA(req);
- addRRAd(req);
- return 1;
- }
- }
- return 0;
- break;
- case DNS_TYPE_SOA:
- if (cfig.authorized)
- {
- if (!strcasecmp(req->query, cfig.authority))
- {
- addRRNone(req);
- addRRSOA(req, cfig.serial2);
- return 1;
- }
- else if (!strcasecmp(req->query, cfig.zone))
- {
- addRRNone(req);
- addRRSOA(req, cfig.serial1);
- return 1;
- }
- }
- return 0;
- break;
- case DNS_TYPE_AAAA:
- req->localCode = makeLocal(req->mapname);
- if (req->localCode && cfig.authorized)
- {
- if (cfig.dnsLogLevel)
- {
- sprintf(logBuff, "%s, DNS Query Type %s not supported", req->query, strqtype(tempbuff, req->qtype));
- logDNSMess(req, logBuff, 1);
- }
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NOTIMPL;
- addAuth(req);
- return 1;
- }
- return 0;
- break;
- default:
- if (cfig.authorized)
- {
- char *dp = strstr(req->mapname, cfig.zoneSmall);
- if (!dp)
- dp = strstr(req->mapname, cfig.authority);
- if (dp && (!strcasecmp(dp, cfig.zoneSmall) || !strcasecmp(dp, cfig.authority)))
- {
- if (cfig.dnsLogLevel)
- {
- sprintf(logBuff, "%s, DNS Query Type %s not supported", req->query, strqtype(tempbuff, req->qtype));
- logDNSMess(req, logBuff, 1);
- }
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NOTIMPL;
- addAuth(req);
- return 1;
- }
- return 0;
- }
- return 0;
- }
- time_t t = time(NULL);
- for (int m = 0; m < 3; m++)
- {
- //printf("%s has %u Entriesn", req->mapname, dnsCache[cacheInd].count(req->mapname));
- req->iterBegin = dnsCache[cacheInd].find(req->mapname);
- if (req->iterBegin != dnsCache[cacheInd].end() && req->iterBegin->second->expiry > t)
- {
- memcpy(&req->cache, req->iterBegin->second, sizeof(data7));
- //printf("mapname=%s, datatype=%i exp=%un",req->cache.mapname, req->cache.dataType,req->cache.expiry);
- switch (req->cache.dataType)
- {
- case LOCAL_A:
- case STATIC_A_AUTH:
- addRRNone(req);
- addRRA(req);
- addAuth(req);
- return 1;
- case LOCAL_PTR_AUTH:
- case STATIC_PTR_AUTH:
- case SERVER_PTR_AUTH:
- addRRNone(req);
- addRRPtr(req);
- addAuth(req);
- return 1;
- case LOCALHOST_A:
- addRRNone(req);
- addRRLocalhostA(req);
- addAuth(req);
- return 1;
- case LOCALHOST_PTR:
- addRRNone(req);
- addRRLocalhostPtr(req);
- addAuth(req);
- return 1;
- case STATIC_A_NAUTH:
- addRRNone(req);
- addRRA(req);
- return 1;
- case LOCAL_PTR_NAUTH:
- case SERVER_PTR_NAUTH:
- case STATIC_PTR_NAUTH:
- addRRNone(req);
- addRRPtr(req);
- return 1;
- case SERVER_A:
- addRRNone(req);
- addRRServerA(req);
- addAuth(req);
- return 1;
- case CACHED:
- addRRNone(req);
- addRRExt(req);
- return 1;
- case LOCAL_CNAME:
- case EXT_CNAME:
- if (!strchr(req->cache.hostname, '.'))
- sprintf(req->cname, "%s.%s", req->cache.hostname, cfig.zone);
- else
- strcpy(req->cname, req->cache.hostname);
- strcpy(req->mapname, req->cache.hostname);
- myLower(req->mapname);
- continue;
- default:
- break;
- }
- }
- break;
- }
- //printf("%u=%un", req->cache.dataType, req->localCode);
- if (req->cache.dataType == LOCAL_CNAME)
- {
- addRRNone(req);
- addRRA(req);
- addAuth(req);
- return 1;
- }
- else if (req->cache.dataType == EXT_CNAME)
- {
- //printf("%u=%un", req->cache.dataType, EXT_CNAME);
- req->data = &req->dnsp->data;
- req->data += pQu(req->data, req->cname);
- req->data += pUShort(req->data, DNS_TYPE_A);
- req->data += pUShort(req->data, DNS_CLASS_IN);
- req->bytes = (DWORD)req->data - (DWORD)req->raw;
- }
- else if (req->qtype == DNS_TYPE_A && cfig.wildHosts[0].wildcard[0])
- {
- for (BYTE i = 0; i < 32 && cfig.wildHosts[i].wildcard[0]; i++)
- {
- if (wildcmp(req->mapname, cfig.wildHosts[i].wildcard))
- {
- addRRNone(req);
- if (cfig.wildHosts[i].ip)
- addRRWildA(req, cfig.wildHosts[i].ip);
- return 1;
- }
- }
- }
- return 0;
- }
- WORD fdnmess(data5 *req)
- {
- //checkSize();
- req->qLen = strlen(req->cname);
- BYTE zoneDNS;
- int nRet = -1;
- char mapname[8];
- sprintf(mapname, "%u", req->dnsp->header.xid);
- data7 *queue = findEntry(cacheInd, mapname, QUEUE);
- for (zoneDNS = 0; zoneDNS < 32 && cfig.dnsRoutes[zoneDNS].zLen; zoneDNS++)
- {
- if (req->qLen == cfig.dnsRoutes[zoneDNS].zLen && !strcasecmp(req->cname, cfig.dnsRoutes[zoneDNS].zone))
- req->localCode = 4;
- else if (req->qLen > cfig.dnsRoutes[zoneDNS].zLen)
- {
- char *dp = req->cname + (req->qLen - cfig.dnsRoutes[zoneDNS].zLen - 1);
- if (*dp == '.' && !strcasecmp(dp + 1, cfig.dnsRoutes[zoneDNS].zone))
- req->localCode = 4;
- }
- if (req->localCode == 4)
- {
- if (queue && cfig.dnsRoutes[zoneDNS].dns[1])
- {
- cfig.dnsRoutes[zoneDNS].currentDNS = 1 - cfig.dnsRoutes[zoneDNS].currentDNS;
- }
- if (req->addr.sin_addr.s_addr != cfig.dnsRoutes[zoneDNS].dns[cfig.dnsRoutes[zoneDNS].currentDNS])
- {
- req->target.sin_family = AF_INET;
- req->target.sin_addr.s_addr = cfig.dnsRoutes[zoneDNS].dns[cfig.dnsRoutes[zoneDNS].currentDNS];
- req->target.sin_port = htons(IPPORT_DNS);
- errno = 0;
- nRet = sendto(cfig.forwConn.sock,
- req->raw,
- req->bytes,
- 0,
- (sockaddr*)&req->target,
- sizeof(req->target));
- //errno = WSAGetLastError();
- if (errno || nRet <= 0)
- {
- if (cfig.dnsLogLevel)
- {
- sprintf(logBuff, "Error Forwarding UDP DNS Message to Child Server %s", IP2String(tempbuff, req->target.sin_addr.s_addr));
- logDNSMess(req, logBuff, 1);
- }
- if (cfig.dnsRoutes[zoneDNS].dns[1])
- {
- cfig.dnsRoutes[zoneDNS].currentDNS = 1 - cfig.dnsRoutes[zoneDNS].currentDNS;
- }
- return 0;
- }
- else
- {
- if (cfig.dnsLogLevel == 2)
- {
- sprintf(logBuff, "%s forwarded to Child Server %s", req->cname, IP2String(tempbuff, cfig.dnsRoutes[zoneDNS].dns[cfig.dnsRoutes[zoneDNS].currentDNS]));
- logDNSMess(req, logBuff, 2);
- }
- }
- }
- /*
- if (nRet <= 0)
- {
- addRRNone(req);
- req->dnsp->header.ra = 0;
- req->dnsp->header.rcode = RCODE_SERVERFAIL;
- return 0;
- }
- */
- break;
- }
- }
- // printf("%un", req->localCode);
- if (req->localCode != 4)
- {
- if (cfig.authorized)
- {
- if (req->localCode == 3)
- {
- if (cfig.dnsLogLevel == 2)
- {
- sprintf(logBuff, "%s not found", req->query);
- logDNSMess(req, logBuff, 2);
- }
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NAMEERROR;
- addAuth(req);
- return 0;
- }
- else
- {
- char *dp = 0;
- if (req->qtype != DNS_TYPE_PTR && req->qLen > cfig.zLen)
- {
- dp = req->cname + (req->qLen - cfig.zLen - 1);
- if (*dp != '.' || strcasecmp(dp + 1, cfig.zone))
- dp = 0;
- }
- if (!dp && req->qLen > cfig.aLen)
- {
- dp = req->cname + (req->qLen - cfig.aLen - 1);
- if (*dp != '.' || strcasecmp(dp + 1, cfig.authority))
- dp = 0;
- }
- //printf("%s=%sn", req->cname, dp);
- if (dp) //if child zone matches
- {
- switch (req->qtype)
- {
- case DNS_TYPE_A:
- case DNS_TYPE_MX:
- case DNS_TYPE_PTR:
- if (cfig.dnsLogLevel == 2)
- {
- if (dp != strchr(req->cname, '.'))
- {
- if (cfig.dnsLogLevel == 2)
- {
- while (dp > req->cname)
- {
- dp--;
- if (*dp == '.')
- {
- dp++;
- break;
- }
- }
- sprintf(logBuff, "%s (Child Zone %s) not found", req->query, dp);
- logDNSMess(req, logBuff, 2);
- }
- }
- else
- {
- sprintf(logBuff, "%s not found", req->query);
- logDNSMess(req, logBuff, 2);
- }
- }
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NAMEERROR;
- addAuth(req);
- return 0;
- break;
- case DNS_TYPE_AXFR:
- case DNS_TYPE_NS:
- case DNS_TYPE_SOA:
- if (cfig.dnsLogLevel == 2)
- {
- if (dp != strchr(req->cname, '.'))
- {
- while (dp > req->cname)
- {
- dp--;
- if (*dp == '.')
- {
- dp++;
- break;
- }
- }
- sprintf(logBuff, "%s (Child Zone %s) not found", req->query, dp);
- logDNSMess(req, logBuff, 2);
- }
- else
- {
- sprintf(logBuff, "Child Zone %s not found", req->query);
- logDNSMess(req, logBuff, 2);
- }
- }
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NOTZONE;
- addAuth(req);
- return 0;
- break;
- default:
- if (cfig.dnsLogLevel == 2)
- {
- sprintf(logBuff, "DNS UDP Query Type %s not supported", strqtype(tempbuff, req->qtype));
- logDNSMess(logBuff, 1);
- }
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NOTIMPL;
- addAuth(req);
- return 0;
- }
- }
- }
- } //if (cfig.authorized)
- if (!req->dnsp->header.rd)
- {
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NAMEERROR;
- if (cfig.dnsLogLevel)
- {
- sprintf(logBuff, "%s is not local (recursion not desired)", req->query);
- logDNSMess(req, logBuff, 2);
- }
- return 0;
- }
- if (!cfig.dns[0])
- {
- addRRNone(req);
- req->dnsp->header.rcode = RCODE_NAMEERROR;
- req->dnsp->header.ra = 0;
- if (cfig.dnsLogLevel)
- {
- sprintf(logBuff, "%s not found (recursion not available)", req->query);
- logDNSMess(req, logBuff, 2);
- }
- return 0;
- }
- if (queue && cfig.dns[1] && queue->dnsIndex < MAX_SERVERS && cfig.currentDNS == queue->dnsIndex)
- {
- cfig.currentDNS++;
- if (cfig.currentDNS >= MAX_SERVERS || !cfig.dns[cfig.currentDNS])
- cfig.currentDNS = 0;
- }
- if (req->addr.sin_addr.s_addr != cfig.dns[cfig.currentDNS])
- {
- req->target.sin_family = AF_INET;
- req->target.sin_addr.s_addr = cfig.dns[cfig.currentDNS];
- req->target.sin_port = htons(IPPORT_DNS);
- errno = 0;
- nRet = sendto(cfig.forwConn.sock,
- req->raw,
- req->bytes,
- 0,
- (sockaddr*)&req->target,
- sizeof(req->target));
- //errno = WSAGetLastError();
- if (errno || nRet <= 0)
- {
- if (cfig.dnsLogLevel)
- {
- sprintf(logBuff, "Error forwading UDP DNS Message to Forwarding Server %s", IP2String(tempbuff, cfig.dns[cfig.currentDNS]));
- logDNSMess(req, logBuff, 1);
- }
- if (cfig.dns[1])
- {
- cfig.currentDNS++;
- if (cfig.currentDNS >= MAX_SERVERS || !cfig.dns[cfig.currentDNS])
- cfig.currentDNS = 0;
- }
- return 0;
- }
- else
- {
- if (cfig.dnsLogLevel == 2)
- {
- sprintf(logBuff, "%s forwarded to Forwarding Server %s", req->cname, IP2String(tempbuff, cfig.dns[cfig.currentDNS]));
- logDNSMess(req, logBuff, 2);
- }
- }
- }
- // if (nRet <= 0)
- // {
- // addRRNone(req);
- // req->dnsp->header.ra = 0;
- // req->dnsp->header.rcode = RCODE_SERVERFAIL;
- // return 0;
- // }
- }
- time_t t = time(NULL);
- if (!queue)
- {
- queue = (data7*)calloc(1, sizeof(data7));
- if (queue)
- {
- queue->mapname = cloneString(mapname);
- queue->addr = (SOCKADDR_IN*)calloc(1, sizeof(req->addr));
- queue->query = cloneString(req->query);
- if (!queue->mapname || !queue->addr || !queue->query)
- {
- if (queue->mapname)
- free(queue->mapname);
- if (queue->addr)
- free(queue->addr);
- if (queue->query)
- free(queue->query);
- free(queue);
- sprintf(logBuff, "Memory Allocation Error");
- logDNSMess(logBuff, 1);
- return 0;
- }
- memcpy(queue->addr, &req->addr, sizeof(req->addr));
- queue->expiry = 2 + t;
- queue->dataType = QUEUE;
- addEntry(cacheInd, queue);
- }
- else
- {
- sprintf(logBuff, "Memory Allocation Error");
- logDNSMess(logBuff, 1);
- return 0;
- }
- }
- else
- {
- queue->expiry = 2 + t;
- memcpy(queue->addr, &req->addr, sizeof(req->addr));
- if (strcasecmp(queue->query, req->query))
- {
- char *query = cloneString(req->query);
- if (query)
- {
- free(queue->query);
- queue->query = query;
- }
- else
- {
- sprintf(logBuff, "Memory Allocation Error");
- logDNSMess(logBuff, 1);
- return 0;
- }
- }
- }
- queue->sockInd = req->sockInd;
- if (req->localCode == 4)
- queue->dnsIndex = 128 + (2 * zoneDNS) + cfig.dnsRoutes[zoneDNS].currentDNS;
- else
- queue->dnsIndex = cfig.currentDNS;
- //printf("%u %un", zoneDNS, queue->dnsIndex);
- return (nRet);
- }
- WORD frdnmess(data5 *req)
- {
- memset(req, 0, sizeof(data5));
- req->sockLen = sizeof(req->addr);
- errno = 0;
- req->bytes = recvfrom(cfig.forwConn.sock,
- req->raw,
- sizeof(req->raw),
- 0,
- (sockaddr*)&req->addr,
- &req->sockLen);
- //printf("%un", req->bytes);
- //errno = WSAGetLastError();
- if (errno || req->bytes <= 0)
- return 0;
- req->dnsp = (dnsPacket*)req->raw;
- char mapname[8];
- WORD type = 0;
- sprintf(mapname, "%u", req->dnsp->header.xid);
- data7 *queue = findEntry(cacheInd, mapname);
- if (queue && queue->expiry)
- {
- queue->expiry = 0;
- if (queue->dnsIndex < MAX_SERVERS)
- {
- if (req->addr.sin_addr.s_addr != cfig.dns[cfig.currentDNS])
- {
- for (BYTE i = 0; i < MAX_SERVERS && cfig.dns[i]; i++)
- {
- if (cfig.dns[i] == req->addr.sin_addr.s_addr)
- {
- cfig.currentDNS = i;
- break;
- }
- }
- }
- }
- else if (queue->dnsIndex >= 128 && queue->dnsIndex < 192)
- {
- data6 *dnsRoute = &cfig.dnsRoutes[(queue->dnsIndex - 128) / 2];
- if (dnsRoute->dns[0] == req->addr.sin_addr.s_addr)
- dnsRoute->currentDNS = 0;
- else if (dnsRoute->dns[1] == req->addr.sin_addr.s_addr)
- dnsRoute->currentDNS = 1;
- }
- if (queue->dataType == DNS_CHECK)
- {
- if (cfig.dnsLogLevel)
- {
- if (queue->dnsIndex < MAX_SERVERS)
- {
- sprintf(logBuff, "Forwarding DNS Server %s responded", IP2String(tempbuff, req->addr.sin_addr.s_addr));
- logDNSMess(logBuff, 1);
- }
- else if (queue->dnsIndex >= 128 && queue->dnsIndex < 192)
- {
- sprintf(logBuff, "Child DNS Server %s responded", IP2String(tempbuff, req->addr.sin_addr.s_addr));
- logDNSMess(logBuff, 1);
- }
- }
- return 0;
- }
- else if (queue->dataType == QUEUE)
- {
- memcpy(&req->addr, queue->addr, sizeof(req->addr));
- strcpy(req->query, queue->query);
- req->sockInd = queue->sockInd;
- req->cache.dnsIndex = queue->dnsIndex;
- req->data = &req->dnsp->data;
- for (int i = 1; i <= ntohs(req->dnsp->header.qdcount); i++)
- {
- req->data += fQu(req->cname, req->dnsp, req->data);
- type = fUShort(req->data);
- req->data += 4; //type and class
- }
- if ((type == DNS_TYPE_A || type == DNS_TYPE_PTR) && !req->dnsp->header.rcode && !req->dnsp->header.tc && req->dnsp->header.ancount)
- {
- time_t expiry = 0;
- bool resultFound = false;
- for (int i = 1; i <= ntohs(req->dnsp->header.ancount); i++)
- {
- req->data += fQu(tempbuff, req->dnsp, req->data);
- type = fUShort(req->data);
- //printf("%s %u=%un", tempbuff, type, DNS_TYPE_A);
- if (type == DNS_TYPE_A)
- {
- resultFound = true;
- strcpy(req->mapname, req->cname);
- myLower(req->mapname);
- makeLocal(req->mapname);
- }
- else if (type == DNS_TYPE_PTR)
- {
- strcpy(req->mapname, req->cname);
- myLower(req->mapname);
- char *dp = strstr(req->mapname, arpa);
- if (dp && !strcasecmp(dp, arpa))
- {
- *dp = 0;
- resultFound = true;
- }
- }
- req->data += 4; //type and class
- if (!expiry || fULong(req->data) < (DWORD)expiry)
- expiry = fULong(req->data);
- req->data += 4; //ttl
- int zLen = fUShort(req->data);
- req->data += 2; //datalength
- req->data += zLen;
- }
- time_t t = time(NULL);
- if (resultFound)
- {
- WORD cacheSize = (DWORD)req->data - (DWORD)req->raw;
- if (cfig.minCache && expiry < cfig.minCache)
- expiry = cfig.minCache;
- if (cfig.maxCache && expiry > cfig.maxCache)
- expiry = cfig.maxCache;
- if (expiry < LONG_MAX - t)
- expiry += t;
- else
- expiry = LONG_MAX;
- data7 *cache = findEntry(cacheInd, req->mapname, CACHED);
- if (cache)
- {
- if (cache->bytes < cacheSize)
- {
- BYTE *response = (BYTE*)calloc(1, cacheSize);
- if (response)
- {
- if (cache->response)
- free(cache->response);
- cache->response = response;
- }
- else
- {
- sprintf(logBuff, "Memory Allocation Error");
- logDNSMess(logBuff, 1);
- return 0;
- }
- }
- cache->expiry = expiry;
- }
- else
- {
- //checkSize();
- cache = (data7*)calloc(1, sizeof(data7));
- if (!cache)
- {
- sprintf(logBuff, "Memory Allocation Error");
- logDNSMess(logBuff, 1);
- return 0;
- }
- cache->mapname = cloneString(req->mapname);
- cache->response = (BYTE*)calloc(1, cacheSize);
- if (!cache->mapname || !cache->response)
- {
- if (cache->mapname)
- free(cache->mapname);
- if (cache->response)
- free(cache->response);
- free(cache);
- sprintf(logBuff, "Memory Allocation Error");
- logDNSMess(logBuff, 1);
- return 0;
- }
- cache->expiry = expiry;
- cache->dataType = CACHED;
- addEntry(cacheInd, cache);
- }
- memcpy(cache->response, req->dnsp, cacheSize);
- ((dnsPacket*)cache->response)->header.nscount = 0;
- ((dnsPacket*)cache->response)->header.adcount = 0;
- cache->bytes = cacheSize;
- }
- }
- req->cache.dataType = NON_CACHED;
- addRRExt(req);
- return 1;
- }
- }
- return 0;
- }
- void addToCache(BYTE ind, char *hostname, DWORD ip, time_t expiry, BYTE aType, BYTE pType, DWORD serial)
- {
- //printf("Adding to %u, %s=%s exp=%un",ind, hostname,IP2String(tempbuff, ip),expiry);
- char tempbuff[256];
- char logBuff[256];
- if (!hostname[0] || !ip)
- return;
- data7 *cache = NULL;
- hostMap::iterator p;
- if (pType)
- {
- IP2String(tempbuff, htonl(ip));
- p = dnsCache[ind].find(tempbuff);
- for (;p != dnsCache[ind].end(); p++)
- {
- if (strcasecmp(p->second->mapname, tempbuff))
- break;
- if (!strcasecmp(p->second->hostname, hostname))
- {
- cache = p->second;
- break;
- }
- }
- if (!cache)
- {
- //checkSize();
- cache = (data7*)calloc(1, sizeof(data7));
- if (cache)
- {
- cache->mapname = cloneString(tempbuff);
- cache->hostname = cloneString(hostname);
- if (!cache->mapname || !cache->hostname)
- {
- if (cache->mapname)
- free(cache->mapname);
- if (cache->hostname)
- free(cache->hostname);
- free(cache);
- sprintf(logBuff, "Memory Allocation Error");
- logDNSMess(logBuff, 1);
- return ;
- }
- cache->dataType = pType;
- cache->expiry = expiry;
- addEntry(ind, cache);
- }
- else
- {
- sprintf(logBuff, "Memory Allocation Error");
- logDNSMess(logBuff, 1);
- return ;
- }
- }
- else
- {
- if (strcasecmp(hostname, cache->hostname))
- {
- free(cache->hostname);
- cache->hostname = cloneString(hostname);
- }
- if (cache->expiry < expiry)
- cache->expiry = expiry;
- }
- cache->serial = serial;
- }
- if (aType)
- {
- cache = NULL;
- strcpy(tempbuff, hostname);
- makeLocal(tempbuff);
- myLower(tempbuff);
- p = dnsCache[ind].find(tempbuff);
- for (; p != dnsCache[ind].end(); p++)
- {
- if (strcasecmp(p->second->mapname, tempbuff))
- break;
- if (p->second->ip == ip)
- {
- cache = p->second;
- break;
- }
- }
- if (!cache)
- {
- //checkSize();
- cache = (data7*)calloc(1, sizeof(data7));
- if (cache)
- {
- cache->mapname = cloneString(tempbuff);
- if (!cache->mapname)
- {
- sprintf(logBuff, "Memory Allocation Error");
- free(cache);
- logDNSMess(logBuff, 1);
- return ;
- }
- cache->ip = ip;
- cache->dataType = aType;
- cache->expiry = expiry;
- addEntry(ind, cache);
- }
- else
- {
- sprintf(logBuff, "Memory Allocation Error");
- logDNSMess(logBuff, 1);
- return ;
- }
- }
- else
- {
- cache->ip = ip;
- if (cache->expiry < expiry)
- cache->expiry = expiry;
- }
- cache->serial = serial;
- }
- }
- char* getResult(data5 *req)
- {
- tempbuff[0] = 0;
- char *raw = &req->dnsp->data;
- WORD queueIndex;
- for (int i = 1; i <= ntohs(req->dnsp->header.qdcount); i++)
- {
- raw += fQu(extbuff, req->dnsp, raw);
- raw += 4;
- }
- for (int i = 1; i <= ntohs(req->dnsp->header.ancount); i++)
- {
- raw += fQu(extbuff, req->dnsp, raw);
- int type = fUShort(raw);
- raw += 2; //type
- raw += 2; //class
- raw += 4; //ttl
- int zLen = fUShort(raw);
- raw += 2; //datalength
- if (type == DNS_TYPE_A)
- return IP2String(tempbuff, fIP(raw));
- else if (type == DNS_TYPE_AAAA)
- return IP62String(tempbuff, (BYTE*)raw);
- else if (type == DNS_TYPE_PTR)
- {
- fQu(tempbuff, req->dnsp, raw);
- return tempbuff;
- }
- else if (type == DNS_TYPE_MX)
- {
- fQu(tempbuff, req->dnsp, ++++raw);
- return tempbuff;
- }
- else if (type == DNS_TYPE_CNAME)
- {
- fQu(tempbuff, req->dnsp, raw);
- }
- raw += zLen;
- }
- if (tempbuff[0])
- return tempbuff;
- else
- return NULL;
- }
- bool checkRange(char rangeInd, bool macFound, bool vendFound, bool userFound)
- {
- if (!cfig.hasFilter)
- return true;
- BYTE rangeSetInd = cfig.dhcpRanges[rangeInd].rangeSetInd;
- data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
- //printf("checkRange entering, rangeInd=%i rangeSetInd=%in", rangeInd, rangeSetInd);
- //printf("checkRange entered, macFound=%i vendFound=%i userFound=%in", macFound, vendFound, userFound);
- if((!macFound && !rangeSet->macSize[0]) || (macFound && cfig.macArray[rangeSetInd]))
- if((!vendFound && !rangeSet->vendClassSize[0]) || (vendFound && cfig.vendArray[rangeSetInd]))
- if((!userFound && !rangeSet->userClassSize[0]) || (userFound && cfig.userArray[rangeSetInd]))
- return true;
- //printf("checkRange, returning false rangeInd=%i rangeSetInd=%in", rangeInd, rangeSetInd);
- return false;
- }
- DWORD resad(data1 *req)
- {
- time_t t = time(NULL);
- DWORD minRange = 0;
- DWORD maxRange = 0;
- if (req->dhcpp.header.bp_giaddr)
- {
- setLeaseExpiry(req->dhcpp.header.bp_giaddr, LONG_MAX);
- setLeaseExpiry(req->addr.sin_addr.s_addr, LONG_MAX);
- }
- DWORD iipNew = 0;
- DWORD iipExp = 0;
- DWORD rangeStart = 0;
- DWORD rangeEnd = 0;
- char rangeInd = -1;
- bool rangeFound = false;
- bool macFound = false;
- bool vendFound = false;
- bool userFound = false;
- memset(cfig.macArray, 0, sizeof(cfig.macArray));
- memset(cfig.vendArray, 0, sizeof(cfig.vendArray));
- memset(cfig.userArray, 0, sizeof(cfig.userArray));
- if (cfig.hasFilter)
- {
- for (BYTE rangeSetInd = 0; rangeSetInd < 32 && cfig.rangeSet[rangeSetInd].active; rangeSetInd++)
- {
- data14 *rangeSet = &cfig.rangeSet[rangeSetInd];
- for (BYTE i = 0; i < 32 && rangeSet->macSize[i]; i++)
- {
- 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)
- {
- cfig.macArray[rangeSetInd] = true;
- macFound = true;
- //printf("mac Found, rangeSetInd=%in", rangeSetInd);
- break;
- }
- }
- for (BYTE i = 0; i < 32 && rangeSet->vendClassSize[i]; i++)
- {
- if(req->vendClassSize && rangeSet->vendClassSize[i] == req->vendClassSize && !memcmp(req->vendClass, rangeSet->vendClass[i], rangeSet->vendClassSize[i]))
- {
- cfig.vendArray[rangeSetInd] = true;
- vendFound = true;
- //printf("vend Found, rangeSetInd=%in", rangeSetInd);
- break;
- }
- }
- for (BYTE i = 0; i < 32 && rangeSet->userClassSize[i]; i++)
- {
- if(req->userClassSize && rangeSet->userClassSize[i] == req->userClassSize && !memcmp(req->userClass, rangeSet->userClass[i], rangeSet->userClassSize[i]))
- {
- cfig.userArray[rangeSetInd] = true;
- userFound = true;
- //printf("user Found, rangeSetInd=%in", rangeSetInd);
- break;
- }
- }
- }
- }
- // printArray("macArray", (char*)cfig.macArray);
- // printArray("vendArray", (char*)cfig.vendArray);
- // printArray("userArray", (char*)cfig.userArray);
- if (chad(req))
- {
- bool rangeOK = req->dhcpEntry->fixed;
- if (!rangeOK && req->dhcpEntry->rangeInd >= 0)
- rangeOK = checkRange(req->dhcpEntry->rangeInd, macFound, vendFound, userFound);
- if (rangeOK)
- {
- DWORD mask = INADDR_NONE;
- if (req->dhcpEntry->bitmask)
- mask = htonl(mask << (32 - req->dhcpEntry->bitmask));
- else if (req->dhcpEntry->rangeInd >= 0)
- mask = cfig.dhcpRanges[req->dhcpEntry->rangeInd].mask;
- else
- mask = cfig.mask;
- if (req->dhcpp.header.bp_giaddr)
- calcRangeLimits(req->dhcpp.header.bp_giaddr, mask, &minRange, &maxRange);
- else if (htonl(cfig.dhcpConn[req->sockInd].mask) > htonl(mask))
- calcRangeLimits(cfig.dhcpConn[req->sockInd].server, cfig.dhcpConn[req->sockInd].mask, &minRange, &maxRange);
- else
- calcRangeLimits(cfig.dhcpConn[req->sockInd].server, mask, &minRange, &maxRange);
- if (htonl(req->dhcpEntry->ip) >= minRange && htonl(req->dhcpEntry->ip) <= maxRange)
- {
- setLeaseExpiry(req->dhcpEntry, 20, false);
- return req->dhcpEntry->ip;
- }
- else if (req->dhcpEntry->fixed)
- {
- req->dhcpEntry->no_route = 1;
- setLeaseExpiry(req->dhcpEntry, 20, false);
- return req->dhcpEntry->ip;
- }
- }
- }
- if (req->hostname[0])
- {
- char hostname[256];
- strcpy(hostname, req->hostname);
- myLower(hostname);
- hostMap::iterator it = dnsCache[cacheInd].find(hostname);
- for (; it != dnsCache[cacheInd].end(); it++)
- {
- data7 *cache = it->second;
- //printf("%un", cache->mapname);
- if (strcasecmp(cache->mapname, hostname))
- break;
- if (cache && cache->ip)
- {
- char k = getRangeInd(cache->ip);
- if (k >= 0)
- {
- if (checkRange(k, macFound, vendFound, userFound))
- {
- char ind = getIndex(k, cache->ip);
- data13 *range = &cfig.dhcpRanges[k];
- if (ind >= 0 && range->expiry[ind] <= t && !range->dhcpEntry[ind])
- {
- if (req->dhcpp.header.bp_giaddr)
- calcRangeLimits(req->dhcpp.header.bp_giaddr, range->mask, &minRange, &maxRange);
- else if (htonl(cfig.dhcpConn[req->sockInd].mask) > htonl(range->mask))
- calcRangeLimits(cfig.dhcpConn[req->sockInd].server, cfig.dhcpConn[req->sockInd].mask, &minRange, &maxRange);
- else
- calcRangeLimits(cfig.dhcpConn[req->sockInd].server, range->mask, &minRange, &maxRange);
- DWORD iip = htonl(cache->ip);
- if (iip >= minRange && iip <= maxRange)
- {
- iipNew = iip;
- rangeInd = k;
- break;
- }
- }
- }
- }
- }
- }
- }
- if (!iipNew && req->reqIP)
- {
- char k = getRangeInd(req->reqIP);
- if (k >= 0)
- {
- if (checkRange(k, macFound, vendFound, userFound))
- {
- data13 *range = &cfig.dhcpRanges[k];
- char ind = getIndex(k, req->reqIP);
- if (ind >= 0 && range->expiry[ind] <= t)
- {
- if (req->dhcpp.header.bp_giaddr)
- calcRangeLimits(req->dhcpp.header.bp_giaddr, range->mask, &minRange, &maxRange);
- else if (htonl(cfig.dhcpConn[req->sockInd].mask) > htonl(range->mask))
- calcRangeLimits(cfig.dhcpConn[req->sockInd].server, cfig.dhcpConn[req->sockInd].mask, &minRange, &maxRange);
- else
- calcRangeLimits(cfig.dhcpConn[req->sockInd].server, range->mask, &minRange, &maxRange);
- DWORD iip = htonl(req->reqIP);
- if (iip >= minRange && iip <= maxRange)
- {
- iipNew = iip;
- rangeInd = k;
- }
- }
- }
- }
- }
- for (char k = 0; !iipNew && k < 32 && cfig.dhcpRanges[k].rangeStart; k++)
- {
- if (checkRange(k, macFound, vendFound, userFound))
- {
- data13 *range = &cfig.dhcpRanges[k];
- rangeStart = range->rangeStart;
- rangeEnd = range->rangeEnd;
- if (req->dhcpp.header.bp_giaddr)
- calcRangeLimits(req->dhcpp.header.bp_giaddr, range->mask, &minRange, &maxRange);
- else if (htonl(cfig.dhcpConn[req->sockInd].mask) > htonl(range->mask))
- calcRangeLimits(cfig.dhcpConn[req->sockInd].server, cfig.dhcpConn[req->sockInd].mask, &minRange, &maxRange);
- else
- calcRangeLimits(cfig.dhcpConn[req->sockInd].server, range->mask, &minRange, &maxRange);
- if (rangeStart < minRange)
- rangeStart = minRange;
- if (rangeEnd > maxRange)
- rangeEnd = maxRange;
- if (rangeStart <= rangeEnd)
- {
- rangeFound = true;
- for (DWORD m = rangeStart; m <= rangeEnd; m++)
- {
- if (!range->expiry[m - range->rangeStart])
- {
- iipNew = m;
- rangeInd = k;
- break;
- }
- else if (!iipExp && range->expiry[m - range->rangeStart] < t)
- {
- iipExp = m;
- rangeInd = k;
- }
- }
- }
- }
- }
- if (!iipNew && iipExp)
- {
- char ind = iipExp - cfig.dhcpRanges[rangeInd].rangeStart;
- req->dhcpEntry = cfig.dhcpRanges[rangeInd].dhcpEntry[ind];
- if (req->dhcpEntry)
- {
- dhcpCache.erase(req->dhcpEntry->mapname);
- free(req->dhcpEntry->mapname);
- req->dhcpEntry->mapname = cloneString(toUUE(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen));
- if (!req->dhcpEntry->mapname)
- {
- sprintf(logBuff, "Memory Allocation Error");
- logDHCPMess(logBuff, 1);
- return 0;
- }
- dhcpCache[req->dhcpEntry->mapname] = req->dhcpEntry;
- req->dhcpEntry->ip = htonl(iipExp);
- req->dhcpEntry->rangeInd = rangeInd;
- setLeaseExpiry(req->dhcpEntry, 20, false);
- if (!req->dhcpEntry->fixed)
- {
- if (req->dhcpp.header.bp_giaddr)
- req->dhcpEntry->source = req->dhcpp.header.bp_giaddr;
- else
- req->dhcpEntry->source = cfig.dhcpConn[req->sockInd].server;
- }
- return req->dhcpEntry->ip;
- }
- else
- iipNew = iipExp;
- }
- if (iipNew)
- {
- if (!req->dhcpEntry)
- {
- req->dhcpEntry = (data7*)calloc(1, sizeof(data7));
- if (!req->dhcpEntry)
- {
- sprintf(logBuff, "Memory Allocation Error");
- logDHCPMess(logBuff, 1);
- return 0;
- }
- req->dhcpEntry->mapname = cloneString(toUUE(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen));
- if (!req->dhcpEntry->mapname)
- {
- sprintf(logBuff, "Memory Allocation Error");
- free(req->dhcpEntry);
- logDHCPMess(logBuff, 1);
- return 0;
- }
- dhcpCache[req->dhcpEntry->mapname] = req->dhcpEntry;
- }
- req->dhcpEntry->ip = htonl(iipNew);
- req->dhcpEntry->rangeInd = rangeInd;
- setLeaseExpiry(req->dhcpEntry, 20, false);
- if (!req->dhcpEntry->fixed)
- {
- if (req->dhcpp.header.bp_giaddr)
- req->dhcpEntry->source = req->dhcpp.header.bp_giaddr;
- else
- req->dhcpEntry->source = cfig.dhcpConn[req->sockInd].server;
- }
- return req->dhcpEntry->ip;
- }
- if (!iipNew)
- {
- if (cfig.dhcpLogLevel)
- {
- if (rangeFound)
- {
- if (req->dhcpp.header.bp_giaddr)
- sprintf(logBuff, "No free leases available for DHCP discover from RelayAgent %s", IP2String(tempbuff, req->dhcpp.header.bp_giaddr));
- else
- sprintf(logBuff, "No free leases available for DHCP discover from interface %s", IP2String(tempbuff, cfig.dhcpConn[req->sockInd].server));
- }
- else
- {
- if (req->dhcpp.header.bp_giaddr)
- sprintf(logBuff, "No Matching DHCP Range for DHCP discover from RelayAgent %s", IP2String(tempbuff, req->dhcpp.header.bp_giaddr));
- else
- sprintf(logBuff, "No Matching DHCP Range for DHCP discover from interface %s", IP2String(tempbuff, cfig.dhcpConn[req->sockInd].server));
- }
- logDHCPMess(logBuff, 1);
- }
- }
- return 0;
- }
- DWORD chad(data1 *req)
- {
- req->dhcpEntry = dhcpCache[toUUE(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen)];
- 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 == cfig.dhcpConn[req->sockInd].server))
- {
- if (!req->hostname[0])
- {
- data7 *cache = findEntry(cacheInd, IP2String(tempbuff, htonl(req->dhcpEntry->ip)));
- if (cache && cache->hostname)
- strcpy(req->hostname, cache->hostname);
- else
- sprintf(req->hostname, "%s", hex2String(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, '-'));
- }
- return req->dhcpEntry->ip;
- }
- else
- return 0;
- }
- DWORD sdmess(data1 *req)
- {
- time_t t = time(NULL);
- //printf("Request=%u Req IP=%sn",req->req_type, IP2String(tempbuff, req->dhcpp.header.bp_ciaddr));
- if (req->req_type == DHCP_MESS_NONE)
- {
- req->dhcpp.header.bp_yiaddr = chad(req);
- if (!req->dhcpp.header.bp_yiaddr)
- {
- if (cfig.dhcpLogLevel)
- {
- sprintf(logBuff, "No Static Entry found for BOOTP request from client %s", hex2String(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'));
- logDHCPMess(logBuff, 1);
- }
- return 0;
- }
- }
- else if (req->req_type == DHCP_MESS_DECLINE)
- {
- if (chad(req) == req->dhcpp.header.bp_ciaddr)
- {
- setLeaseExpiry(req->dhcpp.header.bp_ciaddr, LONG_MAX);
- req->dhcpEntry->ip = 0;
- if (cfig.dhcpLogLevel)
- {
- sprintf(logBuff, "IP Address %s declind by Client %s", IP2String(tempbuff, req->dhcpp.header.bp_ciaddr), req->hostname);
- logDHCPMess(logBuff, 1);
- }
- }
- return 0;
- }
- else if (req->req_type == DHCP_MESS_RELEASE)
- {
- if (chad(req) == req->dhcpp.header.bp_ciaddr)
- {
- updateDHCP(req);
- if (req->dhcpEntry->active && cfig.replication)
- {
- expiryMap::iterator p = dhcpAge.begin();
- while (p != dhcpAge.end())
- {
- if (p->second == req->dhcpEntry)
- {
- data7 *cache = p->second;
- dhcpAge.erase(p);
- dhcpAge.insert(pair<long, data7*>(cache->expiry, cache));
- break;
- }
- p++;
- }
- }
- if (cfig.dhcpLogLevel == 2)
- {
- sprintf(logBuff, "IP Address %s released by Client %s (%s)", IP2String(tempbuff, req->dhcpp.header.bp_ciaddr), hex2String(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen, ':'), req->hostname);
- logDHCPMess(logBuff, 2);
- }
- }
- return 0;
- }
- else if (req->req_type == DHCP_MESS_INFORM)
- {
- if (req->serial)
- recvRepl(req);
- return 0;
- }
- else if (req->req_type == DHCP_MESS_DISCOVER && strcasecmp(req->hostname, cfig.servername))
- {
- req->dhcpp.header.bp_yiaddr = resad(req);
- if (!req->dhcpp.header.bp_yiaddr)
- return 0;
- req->resp_type = DHCP_MESS_OFFER;
- }
- else if (req->req_type == DHCP_MESS_REQUEST)
- {
- //printf("%sn", IP2String(tempbuff, req->dhcpp.header.bp_ciaddr));
- if (req->server || req->dhcpp.header.bp_sname[0])
- {
- if (req->server == cfig.dhcpConn[req->sockInd].server || !strcasecmp(req->dhcpp.header.bp_sname, cfig.servername) || !strcasecmp(req->dhcpp.header.bp_sname, cfig.servername_fqn))
- {
- if (req->reqIP && req->reqIP == chad(req) && req->dhcpEntry->expiry > t)
- {
- req->resp_type = DHCP_MESS_ACK;
- req->dhcpp.header.bp_yiaddr = req->reqIP;
- }
- else if (req->dhcpp.header.bp_ciaddr && req->dhcpp.header.bp_ciaddr == chad(req) && req->dhcpEntry->expiry > t)
- {
- req->resp_type = DHCP_MESS_ACK;
- req->dhcpp.header.bp_yiaddr = req->dhcpp.header.bp_ciaddr;
- }
- else
- {
- if (cfig.dhcpLogLevel >= 1)
- {
- sprintf(logBuff, "DHCP Request from Client %s, without Discover, ignored", req->hostname);
- logDHCPMess(logBuff, 1);
- }
- return 0;
- }
- }
- else
- {
- if (cfig.dhcpLogLevel == 2)
- {
- if (req->dhcpp.header.bp_sname[0])
- sprintf(logBuff, "DHCP Request from Client %s, for Server %s, ignored", req->hostname, req->dhcpp.header.bp_sname);
- else
- sprintf(logBuff, "DHCP Request from Client %s, for Server %s, ignored", req->hostname, IP2String(tempbuff, req->server));
- logDHCPMess(logBuff, 2);
- }
- return 0;
- }
- }
- else if (req->dhcpp.header.bp_ciaddr && req->dhcpp.header.bp_ciaddr == chad(req) && req->dhcpEntry->expiry > t)
- {
- req->resp_type = DHCP_MESS_ACK;
- req->dhcpp.header.bp_yiaddr = req->dhcpp.header.bp_ciaddr;
- }
- else if (req->reqIP && req->reqIP == chad(req) && req->dhcpEntry->expiry > t)
- {
- req->resp_type = DHCP_MESS_ACK;
- req->dhcpp.header.bp_yiaddr = req->reqIP;
- }
- else
- {
- if (cfig.dhcpLogLevel >= 1)
- {
- sprintf(logBuff, "DHCP Request from Client %s without Discover, ignored", req->hostname);
- logDHCPMess(logBuff, 1);
- }
- return 0;
- }
- }
- else
- return 0;
- addOptions(req);
- int packSize = (DWORD)(req->vp) - (DWORD)&req->dhcpp;
- packSize++;
- if (req->req_type == DHCP_MESS_NONE)
- packSize = req->bytes;
- if (req->dhcpp.header.bp_giaddr)
- {
- req->addr.sin_port = htons(IPPORT_DHCPS);
- req->addr.sin_addr.s_addr = req->dhcpp.header.bp_giaddr;
- }
- else if (req->dhcpp.header.bp_broadcast || !req->addr.sin_addr.s_addr)
- {
- req->addr.sin_port = htons(IPPORT_DHCPC);
- req->addr.sin_addr.s_addr = INADDR_BROADCAST;
- }
- else
- req->addr.sin_port = htons(IPPORT_DHCPC);
- req->dhcpp.header.bp_op = BOOTP_REPLY;
- errno = 0;
- req->bytes = sendto(cfig.dhcpConn[req->sockInd].sock,
- req->raw,
- packSize,
- 0, //MSG_DONTROUTE,
- (sockaddr*)&req->addr,
- sizeof(req->addr));
- if (errno || req->bytes <= 0)
- return 0;
- //printf("goes=%s %in",IP2String(tempbuff, req->dhcpp.header.bp_yiaddr),req->sockInd);
- return req->dhcpp.header.bp_yiaddr;
- }
- DWORD alad(data1 *req)
- {
- time_t t = time(NULL);
- //printf("inn");
- if (req->dhcpEntry && (req->req_type == DHCP_MESS_NONE || req->resp_type == DHCP_MESS_ACK))
- {
- DWORD retVal = updateDHCP(req);
- if (retVal)
- {
- if (req->lease && !req->dhcpp.header.bp_ciaddr)
- {
- cfig.serial1 = t;
- cfig.serial2 = t;
- if (cfig.replication == 2)
- {
- if (cfig.expire > (DWORD)(LONG_MAX - t))
- cfig.expireTime = LONG_MAX;
- else
- cfig.expireTime = t + cfig.expire;
- }
- else
- cfig.expireTime = LONG_MAX;
- }
- if (cfig.dhcpLogLevel == 2)
- {
- if (req->lease && req->reqIP)
- {
- 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);
- }
- else if (req->req_type)
- {
- 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);
- }
- else
- {
- 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));
- }
- logDHCPMess(logBuff, 2);
- }
- sendRepl(req);
- return retVal;
- }
- }
- else if (cfig.dhcpLogLevel == 2 && req->resp_type == DHCP_MESS_OFFER)
- {
- 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));
- logDHCPMess(logBuff, 2);
- }
- //printf("%u=outn", req->resp_type);
- return 0;
- }
- void addOptions(data1 *req)
- {
- if (!req->messsize && req->req_type == DHCP_MESS_NONE)
- req->messsize = req->bytes;
- else if (!req->messsize)
- req->messsize = sizeof(dhcp_packet);
- data3 op;
- int i;
- if (req->req_type && req->resp_type)
- {
- op.opt_code = DHCP_OPTION_MESSAGETYPE;
- op.size = 1;
- op.value[0] = req->resp_type;
- pvdata(req, &op);
- }
- if (req->dhcpEntry && req->resp_type != DHCP_MESS_DECLINE && req->resp_type != DHCP_MESS_NAK)
- {
- strcpy(req->dhcpp.header.bp_sname, cfig.servername);
- if (req->dhcpEntry->fixed)
- {
- //printf("%u,%un", req->dhcpEntry->options, *req->dhcpEntry->options);
- BYTE *opPointer = req->dhcpEntry->options;
- if (opPointer)
- {
- BYTE requestedOnly = *opPointer;
- opPointer++;
- while (*opPointer && *opPointer < UCHAR_MAX)
- {
- op.opt_code = *opPointer;
- opPointer++;
- op.size = *opPointer;
- opPointer++;
- if (!requestedOnly || req->paramreqlist[op.opt_code])
- {
- memcpy(op.value, opPointer, op.size);
- pvdata(req, &op);
- }
- opPointer += op.size;
- }
- }
- }
- if (req->req_type && req->resp_type)
- {
- if (req->dhcpEntry->rangeInd >= 0)
- {
- BYTE *opPointer = cfig.dhcpRanges[req->dhcpEntry->rangeInd].options;
- //printf("Range=%i Pointer=%un", req->dhcpEntry->rangeInd,opPointer);
- if (opPointer)
- {
- BYTE requestedOnly = *opPointer;
- opPointer++;
- while (*opPointer && *opPointer < UCHAR_MAX)
- {
- op.opt_code = *opPointer;
- opPointer++;
- op.size = *opPointer;
- opPointer++;
- if (!requestedOnly || req->paramreqlist[op.opt_code])
- {
- memcpy(op.value, opPointer, op.size);
- pvdata(req, &op);
- }
- opPointer += op.size;
- }
- }
- }
- BYTE *opPointer = cfig.options;
- if (opPointer)
- {
- BYTE requestedOnly = *opPointer;
- opPointer++;
- while (*opPointer && *opPointer < UCHAR_MAX)
- {
- op.opt_code = *opPointer;
- opPointer++;
- op.size = *opPointer;
- opPointer++;
- if (!requestedOnly || req->paramreqlist[op.opt_code])
- {
- memcpy(op.value, opPointer, op.size);
- pvdata(req, &op);
- }
- opPointer += op.size;
- }
- }
- op.opt_code = DHCP_OPTION_SERVERID;
- op.size = 4;
- pIP(op.value, cfig.dhcpConn[req->sockInd].server);
- pvdata(req, &op);
- op.opt_code = DHCP_OPTION_DOMAINNAME;
- op.size = strlen(cfig.zone);
- memcpy(op.value, cfig.zone, op.size);
- pvdata(req, &op);
- if (!req->opAdded[DHCP_OPTION_IPADDRLEASE])
- {
- op.opt_code = DHCP_OPTION_IPADDRLEASE;
- op.size = 4;
- pULong(op.value, cfig.lease);
- pvdata(req, &op);
- }
- if (!req->opAdded[DHCP_OPTION_NETMASK])
- {
- op.opt_code = DHCP_OPTION_NETMASK;
- op.size = 4;
- if (req->dhcpEntry->rangeInd >= 0)
- pIP(op.value, cfig.dhcpRanges[req->dhcpEntry->rangeInd].mask);
- else
- pIP(op.value, cfig.dhcpConn[req->sockInd].mask);
- pvdata(req, &op);
- }
- /*
- if (!req->opAdded[DHCP_OPTION_ROUTER])
- {
- op.opt_code = DHCP_OPTION_ROUTER;
- op.size = 4;
- pIP(op.value, cfig.dhcpConn[req->sockInd].server);
- pvdata(req, &op);
- }
- */
- if (!req->opAdded[DHCP_OPTION_DNS])
- {
- if (dnsService)
- {
- op.opt_code = DHCP_OPTION_DNS;
- if (cfig.replication == 1)
- {
- op.size = 8;
- pIP(op.value, cfig.dhcpConn[req->sockInd].server);
- pIP(op.value + 4, cfig.zoneServers[1]);
- pvdata(req, &op);
- }
- else if (cfig.replication == 2)
- {
- op.size = 8;
- pIP(op.value, cfig.dhcpConn[req->sockInd].server);
- pIP(op.value + 4, cfig.zoneServers[0]);
- pvdata(req, &op);
- }
- else
- {
- op.size = 4;
- pIP(op.value, cfig.dhcpConn[req->sockInd].server);
- pvdata(req, &op);
- }
- }
- else
- {
- for (i = 0; i < MAX_SERVERS; i++)
- if (!cfig.dns[i])
- break;
- if (i > 0)
- {
- op.opt_code = DHCP_OPTION_DNS;
- op.size = i * 4;
- memcpy(op.value, cfig.dns, op.size);
- pvdata(req, &op);
- }
- }
- }
- /*
- if (!req->opAdded[DHCP_OPTION_HOSTNAME])
- {
- op.opt_code = DHCP_OPTION_HOSTNAME;
- op.size = strlen(req->hostname);
- memcpy(op.value, req->hostname, op.size);
- pvdata(req, &op);
- }
- if (req->clientId.opt_code == DHCP_OPTION_CLIENTID)
- pvdata(req, &req->clientId);
- */
- if (req->agentOption.opt_code == DHCP_OPTION_RELAYAGENTINFO)
- pvdata(req, &req->agentOption);
- }
- }
- *(req->vp) = DHCP_OPTION_END;
- }
- void pvdata(data1 *req, data3 *op)
- {
- if (!req->opAdded[op->opt_code] && (((DWORD)req->vp - (DWORD)&req->dhcpp) + op->size < req->messsize))
- {
- if (op->opt_code == DHCP_OPTION_BOOTFILE)
- memcpy(req->dhcpp.header.bp_file, op->value, op->size);
- else if (op->opt_code == DHCP_OPTION_NEXTSERVER)
- req->dhcpp.header.bp_siaddr = fIP(op->value);
- else if(op->size)
- {
- if (op->opt_code == DHCP_OPTION_IPADDRLEASE)
- {
- if (!req->lease || req->lease > fULong(op->value))
- req->lease = fULong(op->value);
- if (req->dhcpEntry->no_route || req->lease >= LONG_MAX)
- req->lease = ULONG_MAX;
- pULong(op->value, req->lease);
- }
- else if (op->opt_code == DHCP_OPTION_HOSTNAME)
- {
- memcpy(req->hostname, op->value, op->size);
- req->hostname[op->size] = 0;
- }
- memcpy(req->vp, op, (op->size + 2));
- (req->vp) += 2;
- (req->vp) += op->size;
- }
- req->opAdded[op->opt_code] = true;
- }
- }
- DWORD updateDHCP(data1 *req)
- {
- time_t t = time(NULL);
- data8 *dhcpData = (data8*)calloc(1, sizeof(data8));
- strcpy(dhcpData->hostname, req->hostname);
- memcpy(dhcpData->bp_chaddr, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen);
- dhcpData->bp_hlen = req->dhcpp.header.bp_hlen;
- dhcpData->ip = req->dhcpEntry->ip;
- if (!req->dhcpEntry->fixed)
- dhcpData->source = req->dhcpEntry->source;
- if (!req->req_type)
- {
- dhcpData->expiry = LONG_MAX;
- setLeaseExpiry(req->dhcpEntry, LONG_MAX, req->req_type == DHCP_MESS_REQUEST);
- }
- else if (req->lease > (DWORD)(LONG_MAX - t))
- {
- dhcpData->expiry = LONG_MAX;
- setLeaseExpiry(req->dhcpEntry, LONG_MAX, req->req_type == DHCP_MESS_REQUEST);
- }
- else if (req->lease)
- {
- dhcpData->expiry = t + req->lease;
- setLeaseExpiry(req->dhcpEntry, req->lease, req->req_type == DHCP_MESS_REQUEST);
- }
- else
- {
- dhcpData->expiry = 0;
- req->dhcpEntry->expiry = 0;
- }
- addToCache(cacheInd, req->hostname, req->dhcpEntry->ip, dhcpData->expiry, LOCAL_A, NONE, cfig.serial1);
- if (makeLocal(req->dhcpEntry->ip))
- addToCache(cacheInd, req->hostname, req->dhcpEntry->ip, dhcpData->expiry, NONE, LOCAL_PTR_AUTH, cfig.serial2);
- else
- addToCache(cacheInd, req->hostname, req->dhcpEntry->ip, dhcpData->expiry, NONE, LOCAL_PTR_NAUTH, cfig.serial2);
- if (req->dhcpEntry->dhcpInd)
- dhcpData->dhcpInd = req->dhcpEntry->dhcpInd;
- else
- {
- cfig.dhcpIndex++;
- req->dhcpEntry->dhcpInd = cfig.dhcpIndex;
- }
- dhcpData->active = req->dhcpEntry->active;
- pthread_t threadId;
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- int errcode = pthread_create(&threadId, &attr, updateStateFile, (void*)dhcpData);
- pthread_attr_destroy(&attr);
- if(errcode)
- {
- if (cfig.dhcpLogLevel)
- {
- sprintf(logBuff, "Thread Creation Failed");
- logDHCPMess(logBuff, 1);
- }
- free(dhcpData);
- }
- return req->dhcpEntry->ip;
- }
- void setLeaseExpiry(data7 *dhcpEntry, time_t expiry, bool active)
- {
- //printf("%un", active);
- time_t t = time(NULL);
- if (dhcpService && dhcpEntry && dhcpEntry->ip)
- {
- if (LONG_MAX - t < expiry)
- dhcpEntry->expiry = LONG_MAX;
- else
- dhcpEntry->expiry = t + expiry;
- if (active && !dhcpEntry->active)
- {
- dhcpAge.insert(pair<long, data7*>(dhcpEntry->expiry, dhcpEntry));
- dhcpEntry->active = 1;
- }
- if (dhcpEntry->rangeInd >= 0 && dhcpEntry->rangeInd < 32)
- {
- DWORD iip = htonl(dhcpEntry->ip);
- if (iip >= cfig.dhcpRanges[dhcpEntry->rangeInd].rangeStart && iip <= cfig.dhcpRanges[dhcpEntry->rangeInd].rangeEnd)
- {
- int ind = iip - cfig.dhcpRanges[dhcpEntry->rangeInd].rangeStart;
- if (cfig.dhcpRanges[dhcpEntry->rangeInd].expiry[ind] != LONG_MAX)
- cfig.dhcpRanges[dhcpEntry->rangeInd].expiry[ind] = dhcpEntry->expiry;
- cfig.dhcpRanges[dhcpEntry->rangeInd].dhcpEntry[ind] = dhcpEntry;
- }
- }
- }
- }
- void setLeaseExpiry(DWORD ip, time_t expiry)
- {
- time_t t = time(NULL);
- if (dhcpService && ip)
- {
- DWORD iip = htonl(ip);
- for (char rangeInd = 0; rangeInd < 32 && cfig.dhcpRanges[rangeInd].rangeStart; rangeInd++)
- {
- if (iip >= cfig.dhcpRanges[rangeInd].rangeStart && iip <= cfig.dhcpRanges[rangeInd].rangeEnd)
- {
- int ind = iip - cfig.dhcpRanges[rangeInd].rangeStart;
- if (cfig.dhcpRanges[rangeInd].expiry[ind] != LONG_MAX)
- {
- if (LONG_MAX - t < expiry)
- cfig.dhcpRanges[rangeInd].expiry[ind] = LONG_MAX;
- else
- cfig.dhcpRanges[rangeInd].expiry[ind] = t + expiry;
- }
- break;
- }
- }
- }
- }
- DWORD sendRepl(data1 *req)
- {
- data3 op;
- if (cfig.replication == 1)
- req->target.sin_addr.s_addr = cfig.zoneServers[1];
- else if (cfig.replication == 2)
- req->target.sin_addr.s_addr = cfig.zoneServers[0];
- else
- return 0;
- req->target.sin_port = htons(IPPORT_DHCPS);
- req->target.sin_family = AF_INET;
- BYTE *opPointer = req->dhcpp.vend_data;
- while ((*opPointer) < UCHAR_MAX && opPointer < req->vp)
- {
- if ((*opPointer) == DHCP_OPTION_MESSAGETYPE)
- {
- *(opPointer + 2) = DHCP_MESS_INFORM;
- break;
- }
- opPointer = opPointer + *(opPointer + 1) + 2;
- }
- if (opPointer >= req->vp)
- {
- op.opt_code = DHCP_OPTION_MESSAGETYPE;
- op.size = 1;
- op.value[0] = DHCP_MESS_INFORM;
- memcpy(req->vp, &op, (op.size + 2));
- (req->vp) += 2;
- (req->vp) += op.size;
- }
- op.opt_code = DHCP_OPTION_SERIAL;
- op.size = 4;
- pULong(op.value, cfig.serial1);
- memcpy(req->vp, &op, (op.size + 2));
- (req->vp) += 2;
- (req->vp) += op.size;
- //printf("Here1 %un",req->vp);
- *(req->vp) = 255;
- req->bytes = (DWORD)req->vp - (DWORD)req->raw;
- req->bytes++;
- //printf("Here2n");
- req->dhcpp.header.bp_op = BOOTP_REQUEST;
- errno = 0;
- //printf("%in", req->bytes);
- req->bytes = sendto(cfig.dhcpReplConn.sock,
- req->raw,
- req->bytes,
- 0,
- (sockaddr*)&req->target,
- sizeof(req->target));
- //printf("Here3n");
- //errno = WSAGetLastError();
- if (errno || req->bytes <= 0)
- {
- if (cfig.dhcpLogLevel)
- {
- if (cfig.replication == 1)
- sprintf(logBuff, "Error %s Sending DHCP Update to Secondary Server", strerror(errno));
- else
- sprintf(logBuff, "Error %s Sending DHCP Update to Primary Server", strerror(errno));
- logDHCPMess(logBuff, 2);
- }
- return 0;
- }
- else if (cfig.dhcpLogLevel == 2)
- {
- if (cfig.replication == 1)
- sprintf(logBuff, "DHCP Update for host %s sent to Secondary Server", IP2String(tempbuff, req->dhcpEntry->ip));
- else
- sprintf(logBuff, "DHCP Update for host %s sent to Primary Server", IP2String(tempbuff, req->dhcpEntry->ip));
- logDHCPMess(logBuff, 2);
- }
- return req->dhcpp.header.bp_yiaddr;
- }
- DWORD sendRepl(data7 *dhcpEntry)
- {
- data1 req;
- data3 op;
- req.vp = req.dhcpp.vend_data;
- req.messsize = sizeof(dhcp_packet);
- req.dhcpEntry = dhcpEntry;
- if (cfig.replication == 1)
- req.target.sin_addr.s_addr = cfig.zoneServers[1];
- else if (cfig.replication == 2)
- req.target.sin_addr.s_addr = cfig.zoneServers[0];
- else
- return 0;
- req.target.sin_port = htons(IPPORT_DHCPS);
- req.target.sin_family = AF_INET;
- req.dhcpp.header.bp_op = BOOTP_REQUEST;
- req.dhcpp.header.bp_xid = time(NULL);
- req.dhcpp.header.bp_ciaddr = dhcpEntry->ip;
- req.dhcpp.header.bp_yiaddr = dhcpEntry->ip;;
- req.dhcpp.header.bp_hlen = fromUUE(req.dhcpp.header.bp_chaddr, dhcpEntry->mapname);
- req.dhcpp.header.bp_magic_num[0] = 99;
- req.dhcpp.header.bp_magic_num[1] = 130;
- req.dhcpp.header.bp_magic_num[2] = 83;
- req.dhcpp.header.bp_magic_num[3] = 99;
- op.opt_code = DHCP_OPTION_MESSAGETYPE;
- op.size = 1;
- op.value[0] = DHCP_MESS_INFORM;
- memcpy(req.vp, &op, (op.size + 2));
- (req.vp) += 2;
- (req.vp) += op.size;
- op.opt_code = DHCP_OPTION_SERIAL;
- op.size = 4;
- pULong(op.value, cfig.serial1);
- memcpy(req.vp, &op, (op.size + 2));
- (req.vp) += 2;
- (req.vp) += op.size;
- op.opt_code = DHCP_OPTION_IPADDRLEASE;
- op.size = 4;
- pULong(op.value, 0);
- memcpy(req.vp, &op, (op.size + 2));
- (req.vp) += 2;
- (req.vp) += op.size;
- data7 *cache = findEntry(cacheInd, IP2String(tempbuff, htonl(dhcpEntry->ip)));
- if (cache)
- {
- op.opt_code = DHCP_OPTION_HOSTNAME;
- op.size = strlen(cache->hostname);
- memcpy(op.value, cache->hostname, op.size);
- memcpy(req.vp, &op, (op.size + 2));
- (req.vp) += 2;
- (req.vp) += op.size;
- }
- *(req.vp) = 255;
- req.bytes = (DWORD)req.vp - (DWORD)req.raw;
- req.bytes++;
- errno = 0;
- req.bytes = sendto(cfig.dhcpReplConn.sock,
- req.raw,
- req.bytes,
- 0,
- (sockaddr*)&req.target,
- sizeof(req.target));
- //errno = WSAGetLastError();
- if (errno || req.bytes <= 0)
- {
- if (cfig.dhcpLogLevel)
- {
- if (cfig.replication == 1)
- sprintf(logBuff, "Error %s Sending DHCP Update to Secondary Server", strerror(errno));
- else
- sprintf(logBuff, "Error %s Sending DHCP Update to Primary Server", strerror(errno));
- logDHCPMess(logBuff, 2);
- }
- return 0;
- }
- else if (cfig.dhcpLogLevel == 2)
- {
- if (cfig.replication == 1)
- sprintf(logBuff, "DHCP Update for host %s sent to Secondary Server", IP2String(tempbuff, req.dhcpEntry->ip));
- else
- sprintf(logBuff, "DHCP Update for host %s sent to Primary Server", IP2String(tempbuff, req.dhcpEntry->ip));
- logDHCPMess(logBuff, 2);
- }
- return req.dhcpp.header.bp_yiaddr;
- }
- void recvRepl(data1 *req)
- {
- time_t t = time(NULL);
- //printf("Here 2n");
- DWORD ip = req->dhcpp.header.bp_yiaddr ? req->dhcpp.header.bp_yiaddr : req->dhcpp.header.bp_ciaddr;
- if (!cfig.replication || !ip || !req->lease)
- return;
- else if (cfig.replication == 1 && req->addr.sin_addr.s_addr != cfig.zoneServers[1])
- return;
- else if (cfig.replication == 2 && req->addr.sin_addr.s_addr != cfig.zoneServers[0])
- return;
- //printf("Here 3n");
- char rInd = -1;
- if (dhcpService)
- {
- rInd = getRangeInd(ip);
- req->dhcpEntry = dhcpCache[toUUE(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen)];
- if (!req->dhcpEntry && rInd >= 0)
- {
- req->dhcpEntry = (data7*)calloc(1, sizeof(data7));
- if (!req->dhcpEntry)
- {
- sprintf(logBuff, "Memory Allocation Error");
- logDHCPMess(logBuff, 1);
- return;
- }
- req->dhcpEntry->mapname = cloneString(toUUE(tempbuff, req->dhcpp.header.bp_chaddr, req->dhcpp.header.bp_hlen));
- if (!req->dhcpEntry->mapname)
- {
- sprintf(logBuff, "Memory Allocation Error");
- free(req->dhcpEntry);
- logDHCPMess(logBuff, 1);
- return;
- }
- //req->dhcpEntry->dataType = DHCP;
- dhcpCache[req->dhcpEntry->mapname] = req->dhcpEntry;
- }
- }
- if (req->dhcpEntry)
- {
- req->dhcpEntry->ip = ip;
- req->dhcpEntry->rangeInd = rInd;
- //printf("Here 4n");
- if (updateDHCP(req))
- {
- cfig.serial1 = req->serial;
- cfig.serial2 = req->serial;
- if (cfig.replication == 2)
- {
- if (cfig.expire > (DWORD)(LONG_MAX - t))
- cfig.expireTime = LONG_MAX;
- else
- cfig.expireTime = t + cfig.expire;
- }
- else
- {
- cfig.expireTime = LONG_MAX;
- }
- }
- }
- else
- {
- cfig.serial1 = req->serial;
- cfig.serial2 = req->serial;
- if (cfig.replication == 2)
- {
- if (cfig.expire > (DWORD)(LONG_MAX - t))
- cfig.expireTime = LONG_MAX;
- else
- cfig.expireTime = t + cfig.expire;
- }
- else
- {
- cfig.expireTime = LONG_MAX;
- }
- time_t expiry = 0;
- if (req->lease > (DWORD)(LONG_MAX - t))
- expiry = LONG_MAX;
- else
- expiry = t + req->lease;
- addToCache(cacheInd, req->hostname, ip, expiry, LOCAL_A, NONE, cfig.serial1);
- if (makeLocal(ip))
- addToCache(cacheInd, req->hostname, ip, expiry, NONE, LOCAL_PTR_AUTH, cfig.serial2);
- else
- addToCache(cacheInd, req->hostname, ip, expiry, NONE, LOCAL_PTR_NAUTH, cfig.serial2);
- }
- if (cfig.dhcpLogLevel == 2)
- {
- if (cfig.replication == 1)
- sprintf(logBuff, "DHCP Update received for %s from Secondary Server", IP2String(tempbuff, ip));
- else
- sprintf(logBuff, "DHCP Update received for %s from Primary Server", IP2String(tempbuff, ip));
- logDHCPMess(logBuff, 2);
- }
- }
- char getRangeInd(DWORD ip)
- {
- if (dhcpService && ip)
- {
- DWORD iip = htonl(ip);
- for (char k = 0; k < 32 && cfig.dhcpRanges[k].rangeStart; k++)
- if (iip >= cfig.dhcpRanges[k].rangeStart && iip <= cfig.dhcpRanges[k].rangeEnd)
- return k;
- }
- return -1;
- }
- int getIndex(char rangeInd, DWORD ip)
- {
- if (dhcpService && ip && rangeInd >= 0 && rangeInd < 32)
- {
- DWORD iip = htonl(ip);
- if (iip >= cfig.dhcpRanges[rangeInd].rangeStart && iip <= cfig.dhcpRanges[rangeInd].rangeEnd)
- return (iip - cfig.dhcpRanges[rangeInd].rangeStart);
- }
- return -1;
- }
- void loadOptions(char *iniStr, char *sectionName, data20 *optionData)
- {
- optionData->options = 0;
- optionData->ip = 0;
- optionData->mask = 0;
- BYTE maxInd = sizeof(opData) / sizeof(data4);
- BYTE *lastOptionIndex = NULL;
- BYTE options[sizeof(dhcp_packet) - sizeof(dhcp_header)];
- WORD buffsize = sizeof(options);
- BYTE *dp = options;
- *dp = 0;
- dp++;
- char *iniStrPtr = myGetToken(iniStr, 0);
- for (; iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
- {
- char name[512];
- char value[512];
- BYTE hoption[255];
- BYTE valueSize = sizeof(hoption);
- BYTE opTag = 0;
- BYTE opType = 99;
- BYTE valType = 0;
- bool tagFound = false;
- mySplit(name, value, iniStrPtr, '=');
- if (name[0])
- {
- if (value[0] == '"' && value[strlen(value)-1] == '"')
- {
- valType = 1;
- value[strlen(value)-1] = 32;
- value[0] = 32;
- myTrim(value, value);
- if (strlen(value) <= 255)
- valueSize = strlen(value);
- else
- {
- sprintf(logBuff, "Warning: section [%s] option %s value too big, option ignored", sectionName, name);
- logDHCPMess(logBuff, 1);
- continue;
- }
- }
- else if (strchr(value, ':') && strcasecmp(name, "Filter_Mac_Range"))
- {
- valType = 2;
- valueSize = sizeof(hoption);
- char *errorPos = getHexValue(hoption, value, &valueSize);
- if (errorPos)
- {
- sprintf(logBuff, "Warning: section [%s] option %s position %u, Invalid char %c, option ignored", sectionName, name, ((DWORD)errorPos - (DWORD)value) + 1, *(errorPos));
- logDHCPMess(logBuff, 1);
- continue;
- }
- else
- memcpy(value, hoption, valueSize);
- }
- else if ((isIP(value) && my_inet_addr(value)) || !strcasecmp(value, "255.255.255.255") || !strcasecmp(value, "0.0.0.0"))
- valType = 3;
- else if (isInt(value) && atol(value) > USHRT_MAX)
- valType = 4;
- else if (isInt(value) && atoi(value) > UCHAR_MAX)
- valType = 5;
- else if (isInt(value))
- valType = 6;
- else
- {
- valType = 1;
- if (strlen(value) <= 255)
- valueSize = strlen(value);
- else
- {
- sprintf(logBuff, "Warning: section [%s] option %s value too big, option ignored", sectionName, name);
- logDHCPMess(logBuff, 1);
- continue;
- }
- }
- }
- else
- {
- sprintf(logBuff, "Warning: section [%s] option %s, Missing option name, entry %s ignored", sectionName, iniStrPtr);
- logDHCPMess(logBuff, 1);
- continue;
- }
- if (!strcasecmp(name, "DHCP_Range"))
- {
- if (!strcasecmp(sectionName, "DHCP-RANGE"))
- {
- addDHCPRange(value);
- }
- else
- {
- sprintf(logBuff, "Warning: section [%s] option %s not allowed in this section, option ignored", sectionName, iniStrPtr);
- logDHCPMess(logBuff, 1);
- }
- continue;
- }
- else if (!strcasecmp(name, "Subnet_Mask"))
- {
- if (!isIP(value) || !checkMask(my_inet_addr(value)))
- {
- sprintf(logBuff, "Warning: section [%s] Invalid %s %s, option ignored", sectionName, name, value);
- logDHCPMess(logBuff, 1);
- continue;
- }
- else
- (optionData->mask) = my_inet_addr(value);
- }
- else if (!strcasecmp(name, "Filter_Mac_Range"))
- {