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

📄 tftpserver.cpp

📁 Linux下的ppc平台的tftp_server的源代码.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************   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.             ****************************************************************************/// tftpserver.cpp#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <net/if.h>#include <netdb.h>#include <unistd.h>#include <signal.h>#include <stdio.h>#include <fcntl.h>#include <errno.h>#include <sys/time.h>#include <sys/ioctl.h>#include <time.h>#include <stdlib.h>#include <limits.h>#include <memory.h>#include <sys/stat.h>#include <stdio.h>#include <stdlib.h>#include <syslog.h>#include <string>#include <pthread.h>#include "tftpserver.h"//Functionsvoid runProg();void *ProcessRequest(void *lpParam);char *cleanstr(char* buff, bool next);void init();bool getSection(char *sectionName, char *buffer, int sizeofbuffer, char *fileName);char *myLower(char *string);char *myUpper(char *string);char* IP2String(DWORD);void clean(request*);void getServ();BYTE isIP(char*);void logMess(request*, BYTE);void logMess(BYTE);DWORD my_inet_addr(char*);//Global Variablesbool verbatim = false;char iniFile[]="/etc/tftpserver.ini";DWORD blksize = USHRT_MAX - 4;WORD interval = 3;data2 cfig;char tempbuff[256];char logBuff[512];int main(int argc, char **argv){	verbatim = (argc > 1);	if (verbatim)	{		init();		timeval tv;		fd_set readfds;		if (cfig.tftpConn[0].server)		{			printf("\nAccepting requests..\n");			do			{				FD_ZERO(&readfds);				tv.tv_sec = 20;				tv.tv_usec = 0;				for (int i = 0; i < MAX_SERVERS && cfig.tftpConn[i].server; i++)					FD_SET(cfig.tftpConn[i].sock, &readfds);				errno=0;				int fdsReady = select(cfig.maxFD, &readfds, NULL, NULL, &tv);				//if (errno)				//	printf("%s\n", strerror(errno));				for (int i = 0; fdsReady > 0 && i < MAX_SERVERS && cfig.tftpConn[i].server; i++)				{					if (FD_ISSET(cfig.tftpConn[i].sock, &readfds))					{						fdsReady--;						request *req = (request*)malloc(sizeof(request));						memset(req, 0, sizeof(request));						req->clientsize = sizeof(req->client);						errno = 0;						req->bytesRecd = recvfrom(cfig.tftpConn[i].sock, (char*) & req->datain, sizeof(ack), 0, (sockaddr*) & req->client, &req->clientsize);						req->knock = cfig.tftpConn[i].sock;						req->sockInd = i;						if (!errno)						{							if (cfig.hostRanges[0].rangeStart)							{								DWORD iip = ntohl(req->client.sin_addr.s_addr);								BYTE allowed = 0;								for (int j = 0; j <= 32 && cfig.hostRanges[j].rangeStart; j++)								{									if (iip >= cfig.hostRanges[j].rangeStart && iip <= cfig.hostRanges[j].rangeEnd)									{										allowed = 1;										break;									}								}								if (!allowed)								{									req->serverError.opcode = htons(5);									req->serverError.errorcode = htons(2);									strcpy(req->serverError.errormessage, "Access Denied");									logMess(req, 1);									req->bytesSent = sendto(cfig.tftpConn[i].sock, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*) & req->client, req->clientsize);									free(req);									continue;								}							}							if (req->bytesRecd > 0 && (ntohs(req->datain.opcode) == 1 || ntohs(req->datain.opcode) == 2))							{								pthread_create(&req->threadId, 0, ProcessRequest, (void*)req);								if (!req->threadId)								{									req->serverError.opcode = htons(5);									req->serverError.errorcode = htons(0);									strcpy(req->serverError.errormessage, "Thread Creation Error");									logMess(req, 2);									req->bytesSent = sendto(cfig.tftpConn[i].sock, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*) & req->client, req->clientsize);									free(req);								}							}							else if (req->bytesRecd > 0 && (htons(req->datain.opcode) == 5))							{								sprintf(req->serverError.errormessage, "Error Code %i at Client, %s", ntohs(req->clientError.errorcode), req->clientError.errormessage);								logMess(req, 2);								free(req);							}							else							{								req->serverError.opcode = htons(5);								req->serverError.errorcode = htons(0);								sprintf(req->serverError.errormessage, "Invalid Option Code %i", ntohs(req->datain.opcode));								logMess(req, 2);								req->bytesSent = sendto(cfig.tftpConn[i].sock, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*) & req->client, req->clientsize);								free(req);							}						}						else						{							req->serverError.opcode = htons(5);							req->serverError.errorcode = htons(0);							sprintf(req->serverError.errormessage, "Communication Error");							logMess(req, 1);							free(req);						}					}				}			}			while (true);		}		for (int i = 0; i < MAX_SERVERS && cfig.tftpConn[i].server; i++)			close(cfig.tftpConn[i].sock);	}	else	{		/* 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);		}		/* Close out the standard file descriptors */		close(STDIN_FILENO);		close(STDOUT_FILENO);		close(STDERR_FILENO);		/* Daemon-specific initialization goes here */		init();		timeval tv;		fd_set readfds;		if (cfig.tftpConn[0].server)		{			do			{				FD_ZERO(&readfds);				tv.tv_sec = 20;				tv.tv_usec = 0;				for (int i = 0; i < MAX_SERVERS && cfig.tftpConn[i].server; i++)					FD_SET(cfig.tftpConn[i].sock, &readfds);				errno=0;				int fdsReady = select(cfig.maxFD, &readfds, NULL, NULL, &tv);				//if (errno)				//	printf("%s\n", strerror(errno));				for (int i = 0; fdsReady > 0 && i < MAX_SERVERS && cfig.tftpConn[i].server; i++)				{					if (FD_ISSET(cfig.tftpConn[i].sock, &readfds))					{						fdsReady--;						request *req = (request*)malloc(sizeof(request));						memset(req, 0, sizeof(request));						req->clientsize = sizeof(req->client);						errno = 0;						req->bytesRecd = recvfrom(cfig.tftpConn[i].sock, (char*) & req->datain, sizeof(ack), 0, (sockaddr*) & req->client, &req->clientsize);						req->knock = cfig.tftpConn[i].sock;						req->sockInd = i;						if (!errno)						{							if (cfig.hostRanges[0].rangeStart)							{								DWORD iip = ntohl(req->client.sin_addr.s_addr);								BYTE allowed = 0;								for (int j = 0; j <= 32 && cfig.hostRanges[j].rangeStart; j++)								{									if (iip >= cfig.hostRanges[j].rangeStart && iip <= cfig.hostRanges[j].rangeEnd)									{										allowed = 1;										break;									}								}								if (!allowed)								{									req->serverError.opcode = htons(5);									req->serverError.errorcode = htons(0);									strcpy(req->serverError.errormessage, "Access Denied");									logMess(req, 1);									req->bytesSent = sendto(cfig.tftpConn[i].sock, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*) & req->client, req->clientsize);									free(req);									continue;								}							}							if (req->bytesRecd > 0 && (ntohs(req->datain.opcode) == 1 || ntohs(req->datain.opcode) == 2))							{								pthread_create(&req->threadId, 0, ProcessRequest, (void*)req);								if (!req->threadId)								{									req->serverError.opcode = htons(5);									req->serverError.errorcode = htons(0);									strcpy(req->serverError.errormessage, "Thread Creation Error");									logMess(req, 1);									req->bytesSent = sendto(cfig.tftpConn[i].sock, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*) & req->client, req->clientsize);									free(req);								}							}							else if (req->bytesRecd > 0 && (htons(req->datain.opcode) == 5))							{								sprintf(req->serverError.errormessage, "Error Code %i at Client, %s", ntohs(req->clientError.errorcode), req->clientError.errormessage);								logMess(req, 1);								free(req);							}							else							{								req->serverError.opcode = htons(5);								req->serverError.errorcode = htons(0);								sprintf(req->serverError.errormessage, "Invalid Option Code %i", ntohs(req->datain.opcode));								logMess(req, 1);								req->bytesSent = sendto(cfig.tftpConn[i].sock, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*) & req->client, req->clientsize);								free(req);							}						}						else						{							req->serverError.opcode = htons(5);							req->serverError.errorcode = htons(0);							sprintf(req->serverError.errormessage, "Communication Error");							logMess(req, 1);							free(req);						}					}				}			}			while (true);		}		for (int i = 0; i < MAX_SERVERS && cfig.tftpConn[i].server; i++)			close(cfig.tftpConn[i].sock);	}}void *ProcessRequest(void *lpParam){	//printf("here\n");	request *req = (request*)lpParam;	req->blksize = 512;	req->interval = interval - (interval/2);	bool fetchAck = false;	req->m_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);	if (req->m_socket == -1)	{		req->serverError.opcode = htons(5);		req->serverError.errorcode = htons(0);		strcpy(req->serverError.errormessage, "Thread Socket Creation Error");		req->bytesSent = sendto(req->knock, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*) & req->client, req->clientsize);		logMess(req, 1);		free(req);		pthread_exit(NULL);	}	WORD comport;	sockaddr_in service;	for (comport = cfig.minport;;comport++)	{		service.sin_family = AF_INET;		service.sin_addr.s_addr = cfig.tftpConn[req->sockInd].server;		service.sin_port = htons(comport);		if (comport > cfig.maxport)		{			req->serverError.opcode = htons(5);			req->serverError.errorcode = htons(0);			strcpy(req->serverError.errormessage, "No port is free");			req->bytesSent = sendto(req->knock, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*) & req->client, req->clientsize);			logMess(req, 1);			clean(req);			pthread_exit(NULL);		}		else if (bind(req->m_socket, (sockaddr*) &service, sizeof(service) ) == -1)			continue;		else			break;	}	if (connect(req->m_socket, (sockaddr*)&req->client, req->clientsize) == -1)	{		req->serverError.opcode = htons(5);		req->serverError.errorcode = htons(0);		strcpy(req->serverError.errormessage, "Connect Failed");		req->bytesSent = sendto(req->knock, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*) & req->client, req->clientsize);		logMess(req, 1);		clean(req);		pthread_exit(NULL);	}	char *temp = (char*) & req->datain;	temp += 2;	req->filename = temp;	temp += strlen(temp) + 1;	req->mode = temp;	temp += strlen(temp) + 1;	req->alias = req->filename;	for (int i = 0; i < strlen(req->alias); i++)		if (req->alias[i] == '\\')			req->alias[i] = '/';	if (strstr(req->alias, "../"))	{		req->serverError.opcode = htons(5);		req->serverError.errorcode = htons(2);		strcpy(req->serverError.errormessage, "Access violation");		req->bytesSent = send(req->m_socket, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0);		logMess(req, 1);		clean(req);		pthread_exit(NULL);	}	if (req->alias[0] == '/')		req->alias++;	if (!cfig.homes[0].alias[0])	{		strcpy(req->path, cfig.homes[0].target);		strcat(req->path, req->alias);	}	else	{		char *ptr = strchr(req->alias, '/');		if (ptr)		{			*ptr = 0;			ptr++;		}		else		{			req->serverError.opcode = htons(5);			req->serverError.errorcode = htons(2);			sprintf(req->serverError.errormessage, "Missing directory/alias");			req->bytesSent = send(req->m_socket, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0);			logMess(req, 1);			clean(req);			pthread_exit(NULL);		}		for (int i = 0; i < 8; i++)		{			//printf("%s=%i\n", req->alias, cfig.homes[i].alias[0]);			if (cfig.homes[i].alias[0] && !strcasecmp(req->alias, cfig.homes[i].alias))			{				strcpy(req->path, cfig.homes[i].target);				strcat(req->path, ptr);				break;			}			else if (i == 7 || !cfig.homes[i].alias[0])			{				req->serverError.opcode = htons(5);				req->serverError.errorcode = htons(2);				sprintf(req->serverError.errormessage, "No such directory/alias");				req->bytesSent = send(req->m_socket, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0);				logMess(req, 1);				clean(req);				pthread_exit(NULL);			}		}	}	if (ntohs(req->datain.opcode) == 1)	{		errno = 0;		if (!strcasecmp(req->mode, "netascii") || !strcasecmp(req->mode, "ascii"))			req->file = fopen(req->path, "rt");		else			req->file = fopen(req->path, "rb");		if (errno || !req->file)		{			req->serverError.opcode = htons(5);			req->serverError.errorcode = htons(1);			strcpy(req->serverError.errormessage, "File Not Found");			logMess(req, 1);			req->bytesSent = send(req->m_socket, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0);			clean(req);			pthread_exit(NULL);		}	}	else	{		if (!cfig.overwrite)		{			req->file = fopen(req->path, "rb");			if (req->file)			{				req->serverError.opcode = htons(5);				req->serverError.errorcode = htons(6);				strcpy(req->serverError.errormessage, "File already exists");				logMess(req, 1);				req->bytesSent = send(req->m_socket, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0);				clean(req);				pthread_exit(NULL);			}		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -