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

📄 tftpserver.cpp

📁 一个简单的tftp服务器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
						request *req1 = tftpCache[req.mapname];						if (!req1)							tftpCache.erase(req.mapname);						//printf("%u\n",req1);						//printf("Here\n");						if (req1)						{							req1->bytesRecd = req.bytesRecd;							if (ntohs(datain->opcode) == 3 && req1->opcode == 2)							{								if ((WORD)req1->bytesRecd  <= req1->blksize + 4)								{									req1->tblock = req1->block + 1;									if (req1->attempt <= 3 && ntohs(datain->block) == req1->tblock)									{										req1->block = req1->tblock;										req1->fblock++;										req1->attempt = 0;										req1->acout.opcode = htons(4);										req1->acout.block = ntohs(req1->block);										processRecv(req1);									}								}								else								{									req1->serverError.opcode = htons(5);									req1->serverError.errorcode = htons(4);									req1->bytesSent = sendto(cfig.tftpConn[req1->sockInd].sock, (const char*)&req1->serverError, strlen(req1->serverError.errormessage) + 5, 0, (sockaddr*)&req1->client, req1->clientsize);									sprintf(req1->serverError.errormessage, "Error: Incoming Packet too large");									logMess(req1, 1);									req1->attempt = UCHAR_MAX;								}							}							else if (ntohs(datain->opcode) == 4 && req1->opcode == 1)							{								if (req1->bytesRecd >= 4)								{									if (req1->attempt <= 3 && ntohs(datain->block) == req1->block)									{										req1->block++;										req1->fblock++;										req1->attempt = 0;										processSend(req1);									}								}							}							else if (req1->bytesRecd > 512)							{								req1->serverError.opcode = htons(5);								req1->serverError.errorcode = htons(4);								req1->bytesSent = sendto(cfig.tftpConn[req1->sockInd].sock, (const char*)&req1->serverError, strlen(req1->serverError.errormessage) + 5, 0, (sockaddr*)&req1->client, req1->clientsize);								sprintf(req1->serverError.errormessage, "Error: Incoming Packet too large");								logMess(req1, 1);								req1->attempt = UCHAR_MAX;							}							else if (ntohs(datain->opcode) == 1 || ntohs(datain->opcode) == 2)							{								if (req1->file)								{									fclose(req1->file);									req1->file = 0;								}								if (!processNew(&req))								{									memcpy(req1, &req, sizeof(request));								}							}							else if (ntohs(datain->opcode) == 5)							{								sprintf(req1->serverError.errormessage, "Error %i at Client, %s", ntohs(datain->block), &datain->buffer);								logMess(req1, 1);								req1->attempt = UCHAR_MAX;								if (req1->file)								{									fclose(req1->file);									req1->file = 0;								}							}							else							{								req1->serverError.opcode = htons(5);								req1->serverError.errorcode = htons(4);								sprintf(req1->serverError.errormessage, "Unexpected Option Code %u", ntohs(datain->opcode));								req1->bytesSent = sendto(cfig.tftpConn[req1->sockInd].sock, (const char*)&req1->serverError, strlen(req1->serverError.errormessage) + 5, 0, (sockaddr*)&req1->client, req1->clientsize);								logMess(req1, 1);								req1->attempt = UCHAR_MAX;								if (req1->file)								{									fclose(req1->file);									req1->file = 0;								}							}						}						else if (req.bytesRecd < 4 || errno)						{							req.serverError.opcode = htons(5);							req.serverError.errorcode = htons(0);							sprintf(req.serverError.errormessage, "Communication Error");							logMess(&req, 1);							continue;						}						else if (ntohs(datain->opcode) != 1 && ntohs(datain->opcode) != 2)						{							req.serverError.opcode = htons(5);							req.serverError.errorcode = htons(5);							sprintf(req.serverError.errormessage, "Unknown transfer ID");							req.bytesSent = sendto(cfig.tftpConn[i].sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);							logMess(&req, 1);						}						else if (req.bytesRecd > 512)						{							req.serverError.opcode = htons(5);							req.serverError.errorcode = htons(4);							sprintf(req.serverError.errormessage, "Error: Incoming Packet too large");							req.bytesSent = sendto(cfig.tftpConn[i].sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);							logMess(&req, 1);						}						else if (ntohs(datain->opcode) == 5)						{							sprintf(req.serverError.errormessage, "Error %i at Client, %s", ntohs(datain->block), &datain->buffer);							logMess(&req, 1);							continue;						}						else						{							if (cfig.hostRanges[0].rangeStart)							{								DWORD iip = ntohl(req.client.sin_addr.s_addr);								BYTE allowed = false;								for (WORD j = 0; j <= sizeof(cfig.hostRanges) && cfig.hostRanges[j].rangeStart; j++)								{									if (iip >= cfig.hostRanges[j].rangeStart && iip <= cfig.hostRanges[j].rangeEnd)									{										allowed = true;										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);									continue;								}							}							if (!processNew(&req))							{								request *req1 = (request*)calloc(1, sizeof(request));								if (!req1)								{									sprintf(logBuff,"Memory Error");									logMess(logBuff, 1);									continue;								}								memcpy(req1, &req, sizeof(request));								tftpCache[req1->mapname] = req1;								tftpAge.insert(pair<long, request*>(req1->expiry, req1));							}						}					}				}				myMultiMap::iterator p = tftpAge.begin();				myMultiMap::iterator q;				time_t currentTime = time(NULL);				while (p != tftpAge.end())				{					if (!tftpAge.size())						break;					request *req = p->second;					if (p->first > currentTime)					{						break;					}					else if (p->first < req->expiry && req->expiry > currentTime)					{						q = p;						p++;						tftpAge.erase(q);						tftpAge.insert(pair<long, request*>(req->expiry, req));					}					else if (req->expiry <= currentTime && req->attempt >= 3)					{						if (req->attempt < UCHAR_MAX)						{							req->serverError.opcode = htons(5);							req->serverError.errorcode = htons(0);							if (req->fblock && !req->block)								strcpy(req->serverError.errormessage, "Large File, Block# Rollover not supported by Client");							else								strcpy(req->serverError.errormessage, "Timeout");							req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*) &req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);							logMess(req, 1);						}						q = p;						p++;						tftpAge.erase(q);						tftpCache.erase(req->mapname);						clean(req);					}					else if (req->expiry <= currentTime)					{						if (ntohs(req->acout.opcode) == 3)						{							if (processSend(req))								req->attempt = 255;							else							{								req->attempt++;								req->expiry = currentTime + req->timeout;							}						}						else						{							errno = 0;							req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*)&req->acout, req->bytesSent, 0, (sockaddr*)&req->client, req->clientsize);							if (errno)								req->attempt = 255;							else							{								req->attempt++;								req->expiry = currentTime + req->timeout;							}						}						p++;					}					else						p++;				}			}			while (kRunning);		}	}}void closeConn(){	kRunning = false;	sprintf(logBuff, "Closing Network Connections...");	logMess(logBuff, 1);	for (int i = 0; i < MAX_SERVERS && cfig.tftpConn[i].server; i++)		close(cfig.tftpConn[i].sock);	sprintf(logBuff, "TFTP Server Stopped !");	logMess(logBuff, 1);	//exit(EXIT_SUCCESS);}void catch_int(int sig_num){	closeConn();}int processNew(request *req){	req->block = 0;	req->bytesSent = 0;	req->blksize = 512;	req->timeout = timeout;	req->expiry = time(NULL) + req->timeout;	req->opcode = ntohs(datain->opcode);	char *inPtr = (char*)datain;	*(inPtr + (req->bytesRecd - 1)) = 0;	inPtr += 2;	req->filename = inPtr;	if (!strlen(req->filename) || strlen(req->filename) > 255)	{		req->serverError.opcode = htons(5);		req->serverError.errorcode = htons(4);		strcpy(req->serverError.errormessage, "Malformed Request, Invalid/Missing Filename");		req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*)&req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);		req->attempt = UCHAR_MAX;		logMess(req, 1);		return 1;	}	inPtr += strlen(inPtr) + 1;	req->mode = inPtr;	if (!strlen(req->mode) || strlen(req->mode) > 25)	{		req->serverError.opcode = htons(5);		req->serverError.errorcode = htons(4);		strcpy(req->serverError.errormessage, "Malformed Request, Invalid/Missing Mode");		req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*)&req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);		req->attempt = UCHAR_MAX;		logMess(req, 1);		return 1;	}	inPtr += strlen(inPtr) + 1;	for (WORD i = 0; i < strlen(req->filename); i++)		if (req->filename[i] == '\\')			req->filename[i] = '/';	if (strstr(req->filename, "../"))	{		req->serverError.opcode = htons(5);		req->serverError.errorcode = htons(2);		strcpy(req->serverError.errormessage, "Access violation");		req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*)&req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);		logMess(req, 1);		req->attempt = UCHAR_MAX;		return 1;	}/*	if (strchr(req->filename, '~') || strchr(req->filename, '`') || strchr(req->filename, '$') || strchr(req->filename, '<') || strchr(req->filename, '>') || strchr(req->filename, ';') || strchr(req->filename, ';'))	{		req->serverError.opcode = htons(5);		req->serverError.errorcode = htons(0);		strcpy(req->serverError.errormessage, "Invalid Filename");		req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*)&req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);		logMess(req, 1);		req->attempt = UCHAR_MAX;		return 1;	}*/	if (req->filename[0] == '/')		req->filename++;	if (!cfig.homes[0].alias[0])	{		if (strlen(cfig.homes[0].target) + strlen(req->filename) >= sizeof(req->path))		{			req->serverError.opcode = htons(5);			req->serverError.errorcode = htons(4);			strcpy(req->serverError.errormessage, "Filename too large");			req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*)&req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);			logMess(req, 1);			req->attempt = UCHAR_MAX;			return 1;		}		strcpy(req->path, cfig.homes[0].target);		strcat(req->path, req->filename);	}	else	{		char *bname = strchr(req->filename, '/');		if (bname)		{			*bname = 0;			bname++;		}		else		{			req->serverError.opcode = htons(5);			req->serverError.errorcode = htons(1);			sprintf(req->serverError.errormessage, "Missing directory/alias");			req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*)&req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);			logMess(req, 1);			req->attempt = UCHAR_MAX;			return 1;		}		for (int i = 0; i < 8; i++)		{			if (cfig.homes[i].alias[0] && !strcasecmp(req->filename, cfig.homes[i].alias))			{				if (strlen(cfig.homes[i].target) + strlen(bname) >= sizeof(req->path))				{					req->serverError.opcode = htons(5);					req->serverError.errorcode = htons(4);					strcpy(req->serverError.errormessage, "Filename too large");					req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*) &req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);					logMess(req, 1);					req->attempt = UCHAR_MAX;					return 1;				}				strcpy(req->path, cfig.homes[i].target);				strcat(req->path, bname);				break;			}			else if (i == 7 || !cfig.homes[i].alias[0])			{				req->serverError.opcode = htons(5);				req->serverError.errorcode = htons(1);				sprintf(req->serverError.errormessage, "No such directory/alias");				req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*) &req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);				logMess(req, 1);				req->attempt = UCHAR_MAX;				return 1;			}		}	}    if (ntohs(datain->opcode) == 1)    {        errno = 0;		if (cfig.fileRead)		{			if (!strcasecmp(req->mode, "netascii") || !strcasecmp(req->mode, "ascii"))				req->file = fopen(req->path, "rt");			else				req->file = fopen(req->path, "rb");		}		if (errno || !cfig.fileRead || !req->file)		{            req->serverError.opcode = htons(5);            req->serverError.errorcode = htons(1);            strcpy(req->serverError.errormessage, "File Not Found/No Access");            req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*)&req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);            logMess(req, 1);            req->attempt = UCHAR_MAX;            return 1;        }    }    else    {		req->file = fopen(req->path, "rb");		if (req->file)		{			fclose(req->file);			req->file = NULL;			if (!cfig.fileOverwrite)			{                req->serverError.opcode = htons(5);                req->serverError.errorcode = htons(6);                strcpy(req->serverError.errormessage, "File already exists");                req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*)&req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);                logMess(req, 1);                req->attempt = UCHAR_MAX;                return 1;            }        }		else if (!cfig.fileWrite)		{			req->serverError.opcode = htons(5);			req->serverError.errorcode = htons(2);			strcpy(req->serverError.errormessage, "Create File Access Denied");			req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*)&req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);			logMess(req, 1);			req->attempt = UCHAR_MAX;			return 1;		}		errno = 0;		if (strcasecmp(req->mode, "netascii"))			req->file = fopen(req->path, "wb");		else			req->file = fopen(req->path, "wt");		if (errno || !req->file)		{			req->serverError.opcode = htons(5);			req->serverError.errorcode = htons(1);			strcpy(req->serverError.errormessage, "Invalid Path or No Access");			req->bytesSent = sendto(cfig.tftpConn[req->sockInd].sock, (const char*)&req->serverError, strlen(req->serverError.errormessage) + 5, 0, (sockaddr*)&req->client, req->clientsize);			logMess(req, 1);			req->attempt = UCHAR_MAX;			return 1;		}	}	if (*inPtr)	{		char *outPtr = req->acout.buffer;		req->acout.opcode = htons(6);		DWORD val;		while (*inPtr)		{			//printf("%s", inPtr);			if (!strcasecmp(inPtr, "blksize"))			{				strcpy(outPtr, inPtr);				outPtr += strlen(outPtr) + 1;				inPtr += strlen(inPtr) + 1;				val = atol(inPtr);				if (val < 512)					val = 512;				else if (val > blksize)					val = blksize;				req->blksize = val;

⌨️ 快捷键说明

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