📄 opendhcpd.cpp
字号:
/*************************************************************************** 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. ****************************************************************************/// opendhcpd.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 "opendhcpd.h"//Global Variablesdata2 cfig;bool kRunning = true;dhcpMap dhcpCache;char tempbuff[256] = "";char logBuff[256] = "";bool verbatim = false;char iniFile[256] = "";char leaFile[256] = "";char logFile[256] = "";char arpa[] = ".in-addr.arpa";timeval tv;fd_set readfds;fd_set writefds;pthread_mutex_t mutStateFile = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t mutLogFile = PTHREAD_MUTEX_INITIALIZER;//constantsconst char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";const char send200[] = "HTTP/1.1 200 OK\r\nDate: %s\r\nLast-Modified: %s\r\nContent-Type: text/html\r\nConnection: Close\r\nTransfer-Encoding: chunked\r\n";const char sVersion[] = "Open DHCP Server Version 0.3 Linux Build 1003";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("%i\n", 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], "-l") && argc > i + 1 && argv[i + 1][0] != '-' ) { myTrim(logFile, 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 (!strncasecmp(argv[i], "-i", 2)) myTrim(iniFile, argv[i] + 2); else if (!strncasecmp(argv[i], "-l", 2)) myTrim(logFile, argv[i] + 2); else if (!strncasecmp(argv[i], "-s", 2)) myTrim(leaFile, argv[i] + 2); else sprintf(logBuff, "Error: Invalid Argument %s", argv[i]); } if (!leaFile[0]) strcpy(leaFile, "/etc/opendhcpd.state"); if (!iniFile[0]) strcpy(iniFile, "/etc/opendhcpd.ini"); if (verbatim) { if (logBuff[0]) { printf("%s\n", logBuff); exit(EXIT_FAILURE); } if (getuid()) { printf("Error: Only root should run this program\n"); exit(EXIT_FAILURE); } //printf("%i\n",sizeof(data7)); data1 dhcpr; data19 httpr; init(); while (kRunning) { FD_ZERO(&readfds); tv.tv_sec = 20; tv.tv_usec = 0; 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); //printf("%i\n",select(cfig.maxFD, &readfds, NULL, NULL, &tv)); if (select(cfig.maxFD, &readfds, NULL, NULL, &tv)) { if (cfig.httpConn.server && FD_ISSET(cfig.httpConn.sock, &readfds)) { errno = 0; httpr.sockLen = sizeof(httpr.addr); httpr.sock = accept(cfig.httpConn.sock, (sockaddr*)&httpr.addr, &httpr.sockLen); if (httpr.sock == INVALID_SOCKET) printf("Accept Failed, Error=%s\n", strerror(errno)); else procHTTP(&httpr); } if (cfig.replication && FD_ISSET(cfig.dhcpReplConn.sock, &readfds)) { //printf("Repl\n"); 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); } } //printf("Here\n"); } 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; data19 httpr; init(); /* The Big Loop */ while (kRunning) { FD_ZERO(&readfds); tv.tv_sec = 20; tv.tv_usec = 0; 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); //printf("%i\n",select(USHRT_MAX, &readfds, NULL, NULL, &tv)); if (select(cfig.maxFD, &readfds, NULL, NULL, &tv)) { if (cfig.httpConn.server && FD_ISSET(cfig.httpConn.sock, &readfds)) { errno = 0; httpr.sockLen = sizeof(httpr.addr); httpr.sock = accept(cfig.httpConn.sock, (sockaddr*)&httpr.addr, &httpr.sockLen); if (httpr.sock == INVALID_SOCKET) { sprintf(logBuff, "Accept Failed, Error=%s\n", strerror(errno)); logMess(logBuff, 2); } else procHTTP(&httpr); } if (cfig.replication && FD_ISSET(cfig.dhcpReplConn.sock, &readfds)) { //printf("Repl\n"); 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); } } } closeConn();}void closeConn(){ kRunning = false; sprintf(logBuff, "Closing Network Connections..."); logMess(logBuff, 1); for (int i = 0; i < MAX_SERVERS && cfig.dhcpConn[i].server; i++) shutdown(cfig.dhcpConn[i].sock, 2); for (int i = 0; i < MAX_SERVERS && cfig.dhcpConn[i].server; i++) close(cfig.dhcpConn[i].sock); shutdown(cfig.dhcpListener.sock, 2); close(cfig.dhcpListener.sock); if (cfig.replication) { shutdown(cfig.dhcpReplConn.sock, 2); close(cfig.dhcpReplConn.sock); } sprintf(logBuff, "DHCP Server Stopped !"); logMess(logBuff, 1); exit(EXIT_SUCCESS);}void catch_int(int sig_num){ closeConn();}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 *myCloseSocket(void *lpthread){ SOCKET sd = (SOCKET)lpthread; sleep(30); shutdown(sd, 2); close(sd); pthread_exit(NULL);}void procHTTP(data19 *req){ //printf("%i\n", req->sock); errno = 0; req->bytes = recv(req->sock, tempbuff, sizeof(tempbuff), 0); //errno = WSAGetLastError(); if (errno) { sprintf(logBuff, "Error %u Receiving HTTP Message from Client %s", errno, IP2String(tempbuff, req->addr.sin_addr.s_addr)); logMess(logBuff, 1); close(req->sock); return; } else if (cfig.logLevel >= 2) { sprintf(logBuff, "HTTP Request Received from Client %s", IP2String(tempbuff, req->addr.sin_addr.s_addr)); logMess(logBuff, 2); } time_t currTime = time(NULL); BYTE bp_chaddr[16]; const char line200[] = "<td>%s</td>"; dhcpMap::iterator p = NULL; int ind = 0; DWORD iip = 0; data7 *dhcpEntry = NULL; data7 *cache = NULL; //printf("Mem=%u\n", memSize); char size[9]; char *maxChunk = req->buffer + (sizeof(req->buffer) - 512);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -