⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opendhcpd.cpp

📁 Linux下的DHCP服务器程序源代码, 实现DHCP Server端协议
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************   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 + -