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

📄 smisc.c

📁 网友张巍提供的tcpip协议栈,是一个成功稳定的以太网接口上的TCP/IP协议程序。里面包括有说明
💻 C
字号:
/* Miscellaneous Internet servers: discard, echo and remote
 */
#include <stdio.h>
#include "global.h"
#include "mbuf.h"
#include "socket.h"
#include "proc.h"
#include "remote.h"
#include "smtp.h"
#include "tcp.h"
#include "commands.h"
#include "hardware.h"
#include "mailbox.h"
#include "asy.h"
#include "n8250.h"
#include "devparam.h"
#include "telnet.h"

char *Rempass = "";	/* Remote access password */

static int chkrpass(struct mbuf *bp);
static void discserv(int s,void *unused,void *p);
static void echoserv(int s,void *unused,void *p);
static void termserv(int s,void *unused,void *p);
static void termrx(int s,void *p1,void *p2);
static void tunregister(struct iface *,int);
static void tregister(struct iface *);

static int Rem = -1;
static int Bsr = -1;

struct tserv {
	struct tserv *next;
	struct proc *proc;
	struct iface *ifp;
};
struct tserv *Tserv;

/* Start up TCP discard server */
int
dis1(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	uint16 port;

	if(argc < 2)
		port = IPPORT_DISCARD;
	else
		port = atoi(argv[1]);
	return start_tcp(port,"Discard Server",discserv,576);
}
static void
discserv(s,unused,p)
int s;
void *unused;
void *p;
{
	struct mbuf *bp;

	sockowner(s,Curproc);
	logmsg(s,"open discard");
	if(availmem() == 0){
		while(recv_mbuf(s,&bp,0,NULL,NULL) > 0)
			free_p(&bp);
	}
	logmsg(s,"close discard");
	close_s(s);
}
/* Stop discard server */
int
dis0(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	uint16 port;

	if(argc < 2)
		port = IPPORT_DISCARD;
	else
		port = atoi(argv[1]);
	return stop_tcp(port);
}
/* Start up TCP echo server */
int
echo1(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	uint16 port;

	if(argc < 2)
		port = IPPORT_ECHO;
	else
		port = atoi(argv[1]);
	return start_tcp(port,"Echo Server",echoserv,512);
}
static void
echoserv(s,unused,p)
int s;
void *unused;
void *p;
{
	struct mbuf *bp;

	sockowner(s,Curproc);
	logmsg(s,"open echo");
	if(availmem() == 0){
		while(recv_mbuf(s,&bp,0,NULL,NULL) > 0)
			send_mbuf(s,&bp,0,NULL,0);
	}
	logmsg(s,"close echo");
	close_s(s);
}
/* stop echo server */
int
echo0(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	uint16 port;

	if(argc < 2)
		port = IPPORT_ECHO;
	else
		port = atoi(argv[1]);
	return stop_tcp(port);
}
/* Start remote exit/reboot server */
int
rem1(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	struct sockaddr_in lsocket,fsock;
	int i;
	int command;
	struct mbuf *bp;
	int32 addr;
	int (*kp)(int32);

	if(Rem != -1){
		return 0;
	}
	ksignal(Curproc,0);
	chname(Curproc,"Remote listener");
	lsocket.sin_family = AF_INET;
	lsocket.sin_addr.s_addr = INADDR_ANY;
	if(argc < 2)
		lsocket.sin_port = IPPORT_REMOTE;
	else
		lsocket.sin_port = atoi(argv[1]);
	
	Rem = socket(AF_INET,SOCK_DGRAM,0);
	bind(Rem,(struct sockaddr *)&lsocket,sizeof(lsocket));
	for(;;){
		i = sizeof(fsock);
		if(recv_mbuf(Rem,&bp,0,(struct sockaddr *)&fsock,&i) == -1)
			break;
		command = PULLCHAR(&bp);

		switch(command){
#ifdef	MSDOS	/* Only present on PCs running MSDOS */
		case SYS_RESET:
			i = chkrpass(bp);
			logmsg(Rem,"%s - Remote reset %s",
			 psocket((struct sockaddr *)&fsock),
			 i == 0 ? "PASSWORD FAIL" : "" );
			if(i != 0){
				iostop();
				sysreset();	/* No return */
			}
			break;
#endif
		case SYS_EXIT:
			i = chkrpass(bp);
			logmsg(Rem,"%s - Remote exit %s",
			 psocket((struct sockaddr *)&fsock),
			 i == 0 ? "PASSWORD FAIL" : "" );
			if(i != 0){
				iostop();
				exit(0);
			}
			break;
		case KICK_ME:
			if(len_p(bp) >= sizeof(int32))
				addr = pull32(&bp);
			else
				addr = fsock.sin_addr.s_addr;
			for(i=0;(kp = Kicklist[i]) != NULL;i++)
				(*kp)(addr);
			break;
		}
		free_p(&bp);
	}
	close_s(Rem);
	Rem = -1;
	return 0;
}
/* Check remote password */
static int
chkrpass(bp)
struct mbuf *bp;
{
	char *lbuf;
	uint16 len;
	int rval = 0;

	len = len_p(bp);
	if(strlen(Rempass) != len)
		return rval;
	lbuf = mallocw(len);
	pullup(&bp,lbuf,len);
	if(strncmp(Rempass,lbuf,len) == 0)
		rval = 1;
	free(lbuf);
	return rval;
}
int
rem0(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	close_s(Rem);
	return 0;
}

/* Start up TCP term server */
int
term1(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	uint16 port;

	if(argc < 2)
		port = IPPORT_TERM;
	else
		port = atoi(argv[1]);
	return start_tcp(port,"Term Server",termserv,576);
}
static void
termserv(s,unused,p)
int s;
void *unused;
void *p;
{
	FILE *network = NULL;
	FILE *asy;
	char *buf = NULL;
	struct iface *ifp;
	struct route *rp;
	struct sockaddr_in fsocket;
	struct proc *rxproc = NULL;
	int i;
	
	sockowner(s,Curproc);
	logmsg(s,"open term");
	network = fdopen(s,"r+");

	if(network == NULL || (buf = malloc(BUFSIZ)) == NULL)
		goto quit;

	if(SETSIG(EABORT)){
		fprintf(network,"Abort\r\n");
		goto quit;
	}
	/* Prompt for and check remote password */
	fprintf(network,"Password: ");
	fgets(buf,BUFSIZ,network);
	rip(buf);
	if(strcmp(buf,Rempass) != 0){
		fprintf(network,"Login incorrect\n");
		goto quit;
	}
	/* Prompt for desired interface. Verify that it exists, that
	 * we're not using it for our TCP connection, that it's an
	 * asynch port, and that there isn't already another tip, term
	 * or dialer session active on it.
	 */
	for(;;){
		fprintf(network,"Interface: ");
		fgets(buf,BUFSIZ,network);
		rip(buf);
		if((ifp = if_lookup(buf)) == NULL){
			fprintf(network,"Interface %s does not exist\n",buf);
			continue;
		}
		if(getpeername(s,(struct sockaddr *)&fsocket,&i) != -1
		 && !ismyaddr(fsocket.sin_addr.s_addr)
		 && (rp = rt_lookup(fsocket.sin_addr.s_addr)) != NULL
		 && rp->iface == ifp){
			fprintf(network,"You're using interface %s!\n",ifp->name);
			continue;
		}
		if((asy = asyopen(buf,"r+b")) != NULL)
			break;
		fprintf(network,"Can't open interface %s\n",buf);
		fprintf(network,"Try to bounce current user? ");
		fgets(buf,BUFSIZ,network);
		if(buf[0] == 'y' || buf[0] == 'Y'){
			tunregister(ifp,1);
			kwait(NULL);
		}
	}
	setvbuf(asy,NULL,_IONBF,0);
	tregister(ifp);
	fprintf(network,"Wink DTR? ");
	fgets(buf,BUFSIZ,network);
	if(buf[0] == 'y' || buf[0] == 'Y'){
		asy_ioctl(ifp,PARAM_DTR,1,0);	/* drop DTR */
		ppause(1000L);
		asy_ioctl(ifp,PARAM_DTR,1,1);	/* raise DTR */
	}
	fmode(network,STREAM_BINARY);	/* Switch to raw mode */
	setvbuf(network,NULL,_IONBF,0);
	fprintf(network,"Turn off local echo? ");
	fgets(buf,BUFSIZ,network);
	if(buf[0] == 'y' || buf[0] == 'Y'){
		fprintf(network,"%c%c%c",IAC,WILL,TN_ECHO);
		/* Eat the response */
		for(i=0;i<3;i++)
			(void)fgetc(network);
	}
#ifdef	notdef
	FREE(buf);
#endif
	/* Now fork into receive and transmit processes */
	rxproc = newproc("term rx",1500,termrx,s,network,asy,0);

	/* We continue to handle the TCP->asy direction */
	fblock(network,PART_READ);
	while((i = fread(buf,1,BUFSIZ,network)) > 0)
		fwrite(buf,1,i,asy);
quit:	fclose(network);
	fclose(asy);
	killproc(rxproc);
	logmsg(s,"close term");
	free(buf);
	close_s(s);
	tunregister(ifp,0);
}
void
termrx(s,p1,p2)
int s;
void *p1,*p2;
{
	int i;
	FILE *network = (FILE *)p1;
	FILE *asy = (FILE *)p2;
	char buf[BUFSIZ];
	
	fblock(asy,PART_READ);
	while((i = fread(buf,1,BUFSIZ,asy)) > 0){
		fwrite(buf,1,i,network);
		kwait(NULL);
	}
}
void
tregister(ifp)
struct iface *ifp;
{
	struct tserv *tserv;

	tserv = (struct tserv *)calloc(1,sizeof(struct tserv));
	tserv->ifp = ifp;
	tserv->proc = Curproc;
	tserv->next = Tserv;
	Tserv = tserv;
}
void
tunregister(ifp,kill)
struct iface *ifp;
int kill;
{
	struct tserv *tserv;
	struct tserv *prev = NULL;

	for(tserv = Tserv;tserv != NULL;prev = tserv,tserv = tserv->next){
		if(tserv->ifp == ifp)
			break;
	}
	if(tserv == NULL)
		return;
	if(kill)
		alert(tserv->proc,EABORT);

	if(prev == NULL)
		Tserv = tserv->next;
	else
		prev->next = tserv->next;
	free(tserv);
}


/* Stop term server */
int
term0(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	uint16 port;

	if(argc < 2)
		port = IPPORT_TERM;
	else
		port = atoi(argv[1]);
	return stop_tcp(port);
}
/* Start BSR server */
int
bsr1(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	struct sockaddr_in lsocket,fsock;
	int i,c;
	struct mbuf *bp;
	char *cp;
	uint8 *dp;
	FILE *asy;

	if(Bsr != -1)
		return 1;

	ksignal(Curproc,0);
	chname(Curproc,"BSR listener");

	if((asy = asyopen(argv[1],"r+b")) == NULL){
		printf("Can't open interface %s\n",argv[1]);
		return 1;
	}
	/* Set up the UDP socket where we'll take commands */
	lsocket.sin_family = AF_INET;
	lsocket.sin_addr.s_addr = INADDR_ANY;
	if(argc < 3)
		lsocket.sin_port = IPPORT_BSR;
	else
		lsocket.sin_port = atoi(argv[2]);
	
	Bsr = socket(AF_INET,SOCK_DGRAM,0);
	bind(Bsr,(struct sockaddr *)&lsocket,sizeof(lsocket));

	/* Process commands */
	for(;;){
		i = sizeof(fsock);
		if(recv_mbuf(Bsr,&bp,0,(struct sockaddr *)&fsock,&i) == -1)
			break;
		/* Check password */
		for(cp = Rempass;;cp++){
			c = PULLCHAR(&bp);
			if(c == -1 || *cp != c)
				goto endcmd;
			if(*cp == '\0')
				break;
		}
		/* Send remainder of packet to BSR */
		while((c = PULLCHAR(&bp)) != -1){
			fputc(c,asy);
		}
		free_p(&bp);	/* Shouldn't be necessary */

		/* Now generate response */
		bp = ambufw(512);	/* Larger than max response */
		dp = bp->data;
		kalarm(500L);	/* Allow BSR time to respond */
		while((c = fgetc(asy)) != -1){
			kalarm(100L);	/* Reset timer */
			*dp++ = c;
			bp->cnt++;
		}
		kalarm(0L);
		/* Send response */
		send_mbuf(Bsr,&bp,0,(struct sockaddr *)&fsock,sizeof(fsock));
endcmd:
		free_p(&bp);
	}
	fclose(asy);
	close_s(Bsr);
	Bsr = -1;
	return 0;
}

int
bsr0(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	close_s(Bsr);
	return 0;
}

⌨️ 快捷键说明

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