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

📄 rinetd.c

📁 Linux 下端口映射工具
💻 C
📖 第 1 页 / 共 3 页
字号:
			pidLogFileName = malloc(strlen(nt) + 1);			if (!pidLogFileName) {				goto lowMemory;			}			strcpy(pidLogFileName, nt);		} else if (!strcmp(bindAddress, "logcommon")) {			logFormatCommon = 1;		} else {			/* A regular forwarding rule. */			bindPortS = strtok(0, " \t\r\n");			if (!bindPortS) {				fprintf(stderr, "rinetd: no bind port "					"specified on line %d.\n", lnum);					continue;			}			service = getservbyname(bindPortS, "tcp");				if (service) {				bindPort = ntohs(service->s_port);			} else {				bindPort = atoi(bindPortS);			}			if ((bindPort == 0) || (bindPort >= 65536)) {				fprintf(stderr, "rinetd: bind port missing "					"or out of range on line %d.\n", lnum);				continue;			}			connectAddress = strtok(0, " \t\r\n");			if (!connectAddress) {				fprintf(stderr, "rinetd: no connect address "					"specified on line %d.\n", lnum);					continue;			}				connectPortS = strtok(0, " \t\r\n");			if (!connectPortS) {				fprintf(stderr, "rinetd: no connect port "					"specified on line %d.\n", lnum);					continue;			}			service = getservbyname(connectPortS, "tcp");				if (service) {				connectPort = ntohs(service->s_port);			} else {				connectPort = atoi(connectPortS);			}			if ((connectPort == 0) || (connectPort >= 65536)) {				fprintf(stderr, "rinetd: bind port missing "					"or out of range on line %d.\n", lnum);				continue;			}			/* Turn all of this stuff into reasonable addresses */			if (!getAddress(bindAddress, &iaddr)) {				fprintf(stderr, "rinetd: host %s could not be "					"resolved on line %d.\n", 					bindAddress, lnum);				continue;			}				/* Make a server socket */			seFds[i] = socket(PF_INET, SOCK_STREAM, 0);			if (seFds[i] == INVALID_SOCKET) {				fprintf(stderr, "rinetd: couldn't create "					"server socket!\n");				seFds[i] = -1;				continue;			}
#ifndef WIN32			if (seFds[i] > maxfd) {				maxfd = seFds[i];			}#endif
			saddr.sin_family = AF_INET;			memcpy(&saddr.sin_addr, &iaddr, sizeof(iaddr));			saddr.sin_port = htons(bindPort);			j = 1;			setsockopt(seFds[i], SOL_SOCKET, SO_REUSEADDR,				(const char *) &j, sizeof(j));			if (bind(seFds[i], (struct sockaddr *) 				&saddr, sizeof(saddr)) == SOCKET_ERROR) 			{				/* Warn -- don't exit. */				fprintf(stderr, "rinetd: couldn't bind to "					"address %s port %d\n", 					bindAddress, bindPort);					closesocket(seFds[i]);				seFds[i] = INVALID_SOCKET;				continue;			}			if (listen(seFds[i], 5) == SOCKET_ERROR) {				/* Warn -- don't exit. */				fprintf(stderr, "rinetd: couldn't listen to "					"address %s port %d\n",					bindAddress, bindPort);					closesocket(seFds[i]);				seFds[i] = INVALID_SOCKET;				continue;			}
			ioctlsocket(seFds[i], FIONBIO, &j);
			if (!getAddress(connectAddress, &iaddr)) {				/* Warn -- don't exit. */				fprintf(stderr, "rinetd: host %s could not be "					"resolved on line %d.\n", 					bindAddress, lnum);				closesocket(seFds[i]);				seFds[i] = INVALID_SOCKET;				continue;			}				seLocalAddrs[i] = iaddr;			seLocalPorts[i] = htons(connectPort);			seFromHosts[i] = malloc(strlen(bindAddress) + 1);			if (!seFromHosts[i]) {				goto lowMemory;			}			strcpy(seFromHosts[i], bindAddress);			seFromPorts[i] = bindPort;			seToHosts[i] = malloc(strlen(connectAddress) + 1);			if (!seToHosts[i]) {				goto lowMemory;			}			strcpy(seToHosts[i], connectAddress);			seToPorts[i] = connectPort;			i++;			if (i < seTotal) {				seAllowRulesTotal[i] = 0;				seDenyRulesTotal[i] = 0;			}		}	}	/* Open the log file */	if (logFile) {		fclose(logFile);		logFile = 0;	}	if (logFileName) {		logFile = fopen(logFileName, "a");		if (!logFile) {			fprintf(stderr, "rinetd: could not open %s to append.\n",				logFileName);		}	}	return;lowMemory:	fprintf(stderr, "rinetd: not enough memory to start rinetd.\n");	exit(1);}int getConfLine(FILE *in, char *line, int space, int *lnum){	char *p;	while (1) {		if (!fgets(line, space, in)) {			return 0;		}		p = line;		while (isspace(*p)) {			p++;		}		if (!(*p)) {			/* Blank lines are OK */			continue;		}		if (*p == '#') {			/* Comment lines are also OK */			continue;		}		(*lnum)++;		return 1;	}}void initArrays(void){	int j;	coTotal = 64;	reFds = (SOCKET *) malloc(sizeof(int) * coTotal);	loFds = (SOCKET *) malloc(sizeof(int) * coTotal);	coInputRPos = (int *) malloc(sizeof(int) * coTotal);	coInputWPos = (int *) malloc(sizeof(int) * coTotal);	coOutputRPos = (int *) malloc(sizeof(int) * coTotal);	coOutputWPos = (int *) malloc(sizeof(int) * coTotal);	coClosed = (int *) malloc(sizeof(int) * coTotal);	coClosing = (int *) malloc(sizeof(int) * coTotal);	reClosed = (int *) malloc(sizeof(int) * coTotal);	loClosed = (int *) malloc(sizeof(int) * coTotal);	coInput = (char **) malloc(sizeof(char *) * coTotal);	coOutput = (char **) malloc(sizeof(char *) * coTotal);	coBytesInput = (int *) malloc(sizeof(int) * coTotal);	coBytesOutput = (int *) malloc(sizeof(int) * coTotal);	reAddresses = (unsigned char *) malloc(coTotal * 4);	coLog = (int *) malloc(sizeof(int) * coTotal);	coSe = (int *) malloc(sizeof(int) * coTotal);	if ((!reFds) || (!loFds) || (!coInputRPos) || (!coInputWPos) ||		(!coOutputRPos) || (!coOutputWPos) || 		(!coClosed) || (!coClosing) ||		(!reClosed) || (!loClosed) ||		(!coInput) || (!coOutput) ||		(!coBytesInput) || (!coBytesOutput) || 		(!coLog) || (!coSe) || (!reAddresses)) 	{		fprintf(stderr, "rinetd: not enough memory to start rinetd.\n");		exit(1);	}		for (j = 0; (j < coTotal); j++) {		coClosed[j] = 1;		coInput[j] = (char *) malloc(sizeof(char) * bufferSpace);		coOutput[j] = (char *) malloc(sizeof(char) * bufferSpace);		if ((!coInput[j]) || (!coOutput[j])) {			fprintf(stderr, "rinetd: not enough memory to start "				"rinetd.\n");			exit(1);		}	}}void selectPass(void);void selectLoop(void) {	while (1) {		selectPass();	}}void handleRemoteWrite(int i);void handleRemoteRead(int i);void handleLocalWrite(int i);void handleLocalRead(int i);void handleCloseFromLocal(int i);void handleCloseFromRemote(int i);void handleAccept(int i);void openLocalFd(int se, int i);int getAddress(char *host, struct in_addr *iaddr);void selectPass(void) {	int i;	fd_set readfds, writefds;	FD_ZERO(&readfds);	FD_ZERO(&writefds);	/* Server sockets */	for (i = 0; (i < seTotal); i++) {		if (seFds[i] != INVALID_SOCKET) {			FD_SET(seFds[i], &readfds);		}	}	/* Connection sockets */	for (i = 0; (i < coTotal); i++) {		if (coClosed[i]) {			continue;		}		if (coClosing[i]) {			if (!reClosed[i]) {				FD_SET(reFds[i], &writefds);			}				if (!loClosed[i]) {				FD_SET(loFds[i], &writefds);			}			}		/* Get more input if we have room for it */		if ((!reClosed[i]) && (coInputRPos[i] < bufferSpace)) {			FD_SET(reFds[i], &readfds);		}		/* Send more output if we have any */			if ((!reClosed[i]) && (coOutputWPos[i] < coOutputRPos[i])) {			FD_SET(reFds[i], &writefds);		}			/* Accept more output from the local 			server if there's room */		if ((!loClosed[i]) && (coOutputRPos[i] < bufferSpace)) {			FD_SET(loFds[i], &readfds);		}		/* Send more input to the local server 			if we have any */		if ((!loClosed[i]) && (coInputWPos[i] < coInputRPos[i])) {			FD_SET(loFds[i], &writefds);		}		}	select(maxfd + 1, &readfds, &writefds, 0, 0);	for (i = 0; (i < seTotal); i++) {		if (seFds[i] != -1) {			if (FD_ISSET(seFds[i], &readfds)) {				handleAccept(i);			}		}	}	for (i = 0; (i < coTotal); i++) {		if (coClosed[i]) {			continue;		}		if (!reClosed[i]) {			if (FD_ISSET(reFds[i], &readfds)) {				handleRemoteRead(i);			}		}		if (!reClosed[i]) {			if (FD_ISSET(reFds[i], &writefds)) {				handleRemoteWrite(i);			}		}		if (!loClosed[i]) {			if (FD_ISSET(loFds[i], &readfds)) {				handleLocalRead(i);			}		}		if (!loClosed[i]) {			if (FD_ISSET(loFds[i], &writefds)) {				handleLocalWrite(i);			}		}		if (loClosed[i] && reClosed[i]) {			coClosed[i] = 1;		}		}}void handleRemoteRead(int i){	int got;	if (bufferSpace == coInputRPos[i]) {		return;	}	got = recv(reFds[i], coInput[i] + coInputRPos[i],		bufferSpace - coInputRPos[i], 0);	if (got == 0) {		/* Prepare for closing */		handleCloseFromRemote(i);		return;	}	if (got < 0) {		if (GetLastError() == WSAEWOULDBLOCK) {			return;		}		if (GetLastError() == WSAEINPROGRESS) {			return;		}		handleCloseFromRemote(i);		return;	}	coBytesInput[i] += got;	coInputRPos[i] += got;}void handleRemoteWrite(int i){	int got;	if (coClosing[i] && (coOutputWPos[i] == coOutputRPos[i])) {		reClosed[i] = 1;		coClosed[i] = 1;		PERROR("rinetd: local closed and no more output");		log(i, coSe[i], logDone | coLog[i]); 		closesocket(reFds[i]);		return;	}	got = send(reFds[i], coOutput[i] + coOutputWPos[i],		coOutputRPos[i] - coOutputWPos[i], 0);	if (got < 0) {		if (GetLastError() == WSAEWOULDBLOCK) {			return;		}		if (GetLastError() == WSAEINPROGRESS) {			return;		}		handleCloseFromRemote(i);		return;	}	coOutputWPos[i] += got;	if (coOutputWPos[i] == coOutputRPos[i]) {		coOutputWPos[i] = 0;		coOutputRPos[i] = 0;	}	coBytesOutput[i] += got;}void handleLocalRead(int i){	int got;	if (bufferSpace == coOutputRPos[i]) {		return;	}	got = recv(loFds[i], coOutput[i] + coOutputRPos[i], 		bufferSpace - coOutputRPos[i], 0);	if (got == 0) {		handleCloseFromLocal(i);		return;	}	if (got < 0) {		if (GetLastError() == WSAEWOULDBLOCK) {			return;		}		if (GetLastError() == WSAEINPROGRESS) {			return;		}		handleCloseFromLocal(i);		return;	}	coOutputRPos[i] += got;}void handleLocalWrite(int i){	int got;	if (coClosing[i] && (coInputWPos[i] == coInputRPos[i])) {		loClosed[i] = 1;		coClosed[i] = 1;		PERROR("remote closed and no more input");		log(i, coSe[i], logDone | coLog[i]);		closesocket(loFds[i]);		return;	}	got = send(loFds[i], coInput[i] + coInputWPos[i],		coInputRPos[i] - coInputWPos[i], 0);	if (got < 0) {		if (GetLastError() == WSAEWOULDBLOCK) {			return;		}		if (GetLastError() == WSAEINPROGRESS) {			return;		}		handleCloseFromLocal(i);		return;	}	coInputWPos[i] += got;	if (coInputWPos[i] == coInputRPos[i]) {		coInputWPos[i] = 0;		coInputRPos[i] = 0;	}}void handleCloseFromLocal(int i){	int arg;	coClosing[i] = 1;	/* The local end fizzled out, so make sure		we're all done with that */	PERROR("close from local");	closesocket(loFds[i]);	loClosed[i] = 1;	if (!reClosed[i]) {#ifndef LINUX #ifndef WIN32
		/* Now set up the remote end for a polite closing */		/* Request a low-water mark equal to the entire			output buffer, so the next write notification			tells us for sure that we can close the socket. */		arg = 1024;		setsockopt(reFds[i], SOL_SOCKET, SO_SNDLOWAT, 			&arg, sizeof(arg));	
#endif /* WIN32 */#endif /* LINUX */		coLog[i] = logLocalClosedFirst;	} }void handleCloseFromRemote(int i){	int arg;	coClosing[i] = 1;	/* The remote end fizzled out, so make sure		we're all done with that */	PERROR("close from remote");	closesocket(reFds[i]);	reClosed[i] = 1;	if (!loClosed[i]) {#ifndef LINUX
#ifndef WIN32		/* Now set up the local end for a polite closing */		/* Request a low-water mark equal to the entire			output buffer, so the next write notification			tells us for sure that we can close the socket. */		arg = 1024;		setsockopt(loFds[i], SOL_SOCKET, SO_SNDLOWAT, 			&arg, sizeof(arg));	
#endif /* WIN32 */#endif /* LINUX */		loClosed[i] = 0;		coLog[i] = logRemoteClosedFirst;	}}void refuse(int index, int logCode);void handleAccept(int i){	struct sockaddr addr;	struct sockaddr_in *sin;	unsigned char address[4];	char addressText[64];	int j;	int addrlen;	int index = -1;	int o;	SOCKET nfd;	addrlen = sizeof(addr);	nfd = accept(seFds[i], &addr, &addrlen);	if (nfd == INVALID_SOCKET) {		log(-1, i, logAcceptFailed);		return;	}#ifndef WIN32
	if (nfd > maxfd) {		maxfd = nfd;	}#endif /* WIN32 */
	j = 1;	ioctlsocket(nfd, FIONBIO, &j);
	j = 0;#ifndef WIN32
	setsockopt(nfd, SOL_SOCKET, SO_LINGER, &j, sizeof(j));#endif
	for (j = 0; (j < coTotal); j++) {			if (coClosed[j]) {			index = j;			break;		}	}	if (index == -1) {		o = coTotal;		coTotal *= 2;		if (!SAFE_REALLOC(&reFds, sizeof(int) * o,			sizeof(SOCKET) * coTotal)) 		{			goto shortage;		}		if (!SAFE_REALLOC(&loFds, sizeof(int) * o,

⌨️ 快捷键说明

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