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

📄 tftpserver.c

📁 tftpServer 是支持tftp(trivial file transport protocol)协议的服务器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************   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.             ****************************************************************************/// modified by chen yong, 2007.06.10 #include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.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 <pthread.h>#include "tftpserver.h"//Function prototypesint init();int getSection(char *sectionName, char *buffer, int sizeofbuffer, char *fileName);char *myLower(char *string);char *myUpper(char *string);char *cleanstr(char* buff, int next);BYTE isIP(char *string);DWORD my_inet_addr(char*);char * IP2String(DWORD ip);void logMess(BYTE);void logMess_2(struct request *req, BYTE messLevel);//Global Variablesint verbatim;char iniFile[]="tftpserver.ini";char tempbuff[256];char logBuff[512];struct data2 cfig;WORD interval = 3;void *ProcessRequest(void *lpParam);void cleanReq(struct request*);int main(int argc, char **argv){	verbatim = 0;	struct timeval tv;	fd_set readfds;	int fdsReady;	int i;	struct request * req;		verbatim = (argc > 1);	if (verbatim)	{		if (init() == 0)		{			exit(1);		}        printf("\nAccepting requests..\n");                while (1)		{		    FD_ZERO(&readfds);			tv.tv_sec = 20;			tv.tv_usec = 0;			errno = 0;			fdsReady = select(cfig.sock + 1, &readfds, NULL, NULL, &tv);			FD_SET(cfig.sock, &readfds);			if (FD_ISSET(cfig.sock, &readfds))			{			    req = (struct request *)malloc(sizeof(struct request));                if (!req)				{				    sprintf(logBuff,"Memory Error");					logMess(1);					continue;				}				req->clientsize = sizeof(req->client);				errno = 0;				req->bytesReceived = recvfrom(cfig.sock, (char*)&(req->datain), sizeof(req->datain), 0, (struct sockaddr *)&(req->client), &req->clientsize);				req->knock = cfig.sock;				if (!errno)				{                    if (req->bytesReceived > 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_2(req, 2);							req->bytesSent = sendto(req->knock, (const char*)&(req->serverError), strlen(req->serverError.errormessage) + 5, 0, (struct sockaddr*)&(req->client), req->clientsize);														free(req);						}					}					else if (req->bytesReceived > 0 && (htons(req->datain.opcode) == 5))					{					    sprintf(req->serverError.errormessage, "Error Code %i at Client, %s", ntohs(req->clientError.errorcode), req->clientError.errormessage);						logMess_2(req, 2);												free(req);					}					else					{						req->serverError.opcode = htons(5);						req->serverError.errorcode = htons(4);						sprintf(req->serverError.errormessage, "Invalid Option Code %i", ntohs(req->datain.opcode));						logMess_2(req, 2);						req->bytesSent = sendto(req->knock, (const char*)&(req->serverError), strlen(req->serverError.errormessage) + 5, 0, (struct sockaddr*)&(req->client), req->clientsize);												free(req);					}				}				else				{					sprintf(req->serverError.errormessage, "Communication Error");					logMess_2(req, 1);										free(req);				}			}		}	}}int init(){	socklen_t nRet;		memset(&cfig, 0, sizeof(cfig));		sprintf(cfig.homedir, "/home/yongchen/test/");	cfig.overwrite = 0;	cfig.logLevel = 2;	cfig.minport = 30000;	cfig.maxport = 30020;		cfig.server = inet_addr("192.168.130.154");	cfig.port = 69; 	cfig.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);	if (cfig.sock == -1)    {	    sprintf(logBuff, "Failed to Create Socket");        logMess(1);        return 0;    }          cfig.addr.sin_family = AF_INET;    cfig.addr.sin_addr.s_addr = cfig.server;    cfig.addr.sin_port = htons(cfig.port);        nRet = bind(cfig.sock, (struct sockaddr *)&cfig.addr, sizeof(struct sockaddr_in));    if (nRet == -1)	{	    close(cfig.sock);		sprintf(logBuff, "%s Port %u, bind failed, %s", IP2String(cfig.server), cfig.port, strerror(errno));		logMess(1);		return 0;	}        if (verbatim)	{		printf("\nStarting TFTP...\n");	}	return 1;}char * IP2String(DWORD ip){	struct in_addr inaddr;	inaddr.s_addr = ip;	sprintf(tempbuff, "%s", inet_ntoa(inaddr));	return tempbuff;}BYTE isIP(char *string){	int j = 0;	for ( ; *string; string++)	{		if (*string == '.')			j++;		else if (*string < '0' || *string > '9')			return 0;	}	if (j == 3)		return 1;	else		return 0;}void logMess(BYTE messLevel){	if (verbatim)		printf("%s\n", logBuff);}DWORD my_inet_addr(char* str){	if (str == NULL)		return INADDR_ANY;	DWORD x = inet_addr(str);	if (x == INADDR_NONE)		return INADDR_ANY;	else		return x;}void logMess_2(struct request *req, BYTE messLevel){	if (verbatim)	{		if (!req->serverError.errormessage[0])			printf(req->serverError.errormessage, strerror(errno));		if (req->path[0])			printf("Client %s:%u %s, %s\n", inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), req->path, req->serverError.errormessage);		else			printf("Client %s:%u, %s\n", inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), req->serverError.errormessage);	}}void *ProcessRequest(void *lpParam){	struct request * req = (struct request *)lpParam;	req->blksize = 512;	req->interval = interval - (interval / 2);	WORD comport;	struct sockaddr_in service;	char * temp;	int i;    //step1. create socket, bind address, and connect to client.	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, (struct sockaddr*) & (req->client), req->clientsize);		logMess_2(req, 1);				free(req);		pthread_exit(NULL);	}	for (comport = cfig.minport; ;comport++)	{		service.sin_family = AF_INET;		service.sin_addr.s_addr = cfig.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, (struct sockaddr*) & (req->client), req->clientsize);			logMess_2(req, 1);					cleanReq(req);			pthread_exit(NULL);		}		else if (bind(req->m_socket, (struct sockaddr *) &service, sizeof(service)) == -1)			continue;		else			break;	}	if (connect(req->m_socket, (struct 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, (struct sockaddr*) & (req->client), req->clientsize);		logMess_2(req, 1);				cleanReq(req);		pthread_exit(NULL);	}	temp = (char*) & (req->datain);	temp += 2;	req->filename = temp;	temp += strlen(temp) + 1;	req->mode = temp;	temp += strlen(temp) + 1;	req->alias = req->filename;    //step2. handle filename, mode.	for (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_2(req, 1);				cleanReq(req);		pthread_exit(NULL);	}	if (req->alias[0] == '/')		req->alias++;	strcpy(req->path, cfig.homedir);	strcat(req->path, req->alias);		req->fblock = 0;	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_2(req, 1);			req->bytesSent = send(req->m_socket, (const char*) & (req->serverError), strlen(req->serverError.errormessage) + 5, 0);						cleanReq(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_2(req, 1);				req->bytesSent = send(req->m_socket, (const char*) & (req->serverError), strlen(req->serverError.errormessage) + 5, 0);								cleanReq(req);				pthread_exit(NULL);			}		}		errno = 0;		if (!strcasecmp(req->mode, "netascii") || !strcasecmp(req->mode, "ascii"))			req->file = fopen(req->path, "wt");		else			req->file = fopen(req->path, "wb");

⌨️ 快捷键说明

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