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

📄 ppp.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 4 页
字号:
		if(c->state == Cauthok) {			setphase(ppp, Pnet);		} else {			/* restart chapp negotiation */			chapinit(ppp);		}				break;	case Csuccess:		netlog("ppp: chap succeeded\n");		break;	case Cfailure:		netlog("ppp: chap failed\n");		break;	default:		syslog(0, LOG, "chap code %d?\n", m->code);		break;	}	qunlock(ppp);	freeb(b);}static voidputpaprequest(PPP *ppp){	Block *b;	Lcpmsg *m;	Chap *c;	int len, nlen, slen;	getauth(ppp);	c = ppp->chap;	c->id++;	netlog("PPP: pap: send authreq %d %s %s\n", c->id, ppp->chapname, "****");	nlen = strlen(ppp->chapname);	slen = strlen(ppp->secret);	len = 4 + 1 + nlen + 1 + slen;	b = alloclcp(Pauthreq, c->id, len, &m);	*b->wptr++ = nlen;	memmove(b->wptr, ppp->chapname, nlen);	b->wptr += nlen;	*b->wptr++ = slen;	memmove(b->wptr, ppp->secret, slen);	b->wptr += slen;	hnputs(m->len, len);	putframe(ppp, Ppasswd, b);	freeb(b);}static voidpapinit(PPP *ppp){	ppp->chap->id = 0;	putpaprequest(ppp);}static voidgetpap(PPP *ppp, Block *b){	Lcpmsg *m;	int len;	m = (Lcpmsg*)b->rptr;	len = 4;	if(BLEN(b) < 4 || BLEN(b) < (len = nhgets(m->len))){		syslog(0, LOG, "short pap message (%ld < %d)", BLEN(b), len);		freeb(b);		return;	}	if(len < sizeof(Lcpmsg))		m->data[0] = 0;	qlock(ppp);	switch(m->code){	case Pauthreq:		netlog("PPP: pap auth request, not supported\n");		break;	case Pauthack:		if(ppp->phase == Pauth		&& ppp->chap->proto == APpasswd		&& m->id <= ppp-> chap->id){			netlog("PPP: pap succeeded\n");			setphase(ppp, Pnet);		}		break;	case Pauthnak:		if(ppp->phase == Pauth		&& ppp->chap->proto == APpasswd		&& m->id <= ppp-> chap->id){			netlog("PPP: pap failed (%d:%.*s)\n",				m->data[0], m->data[0], (char*)m->data+1);			terminate(ppp, 0);		}		break;	default:		netlog("PPP: unknown pap messsage %d\n", m->code);	}	qunlock(ppp);	freeb(b);}static voidprintopts(Pstate *p, Block *b, int send){	Lcpmsg *m;		Lcpopt *o;	int proto, x, period;	uchar *cp;	char *code, *dir;	m = (Lcpmsg*)b->rptr;	switch(m->code) {	default: code = "<unknown>"; break;	case Lconfreq: code = "confrequest"; break;	case Lconfack: code = "confack"; break;	case Lconfnak: code = "confnak"; break;	case Lconfrej: code = "confreject"; break;	}	if(send)		dir = "send";	else		dir = "recv";	netlog("ppp: %s %s: id=%d\n", dir, code, m->id);	for(cp = m->data; cp < b->wptr; cp += o->len){		o = (Lcpopt*)cp;		if(cp + o->len > b->wptr){			netlog("\tbad option length %ux\n", o->type);			return;		}		switch(p->proto){		case Plcp:			switch(o->type){			default:				netlog("\tunknown %d len=%d\n", o->type, o->len);				break;			case Omtu:				netlog("\tmtu = %d\n", nhgets(o->data));				break;			case Octlmap:				netlog("\tctlmap = %ux\n", nhgetl(o->data));				break;			case Oauth:				netlog("\tauth = %ux", nhgetl(o->data));				proto = nhgets(o->data);				switch(proto) {				default:					netlog("unknown auth proto %d\n", proto);					break;				case Ppasswd:					netlog("password\n");					break;				case Pchap:					netlog("chap %ux\n", o->data[2]);					break;				}				break;			case Oquality:				proto = nhgets(o->data);				switch(proto) {				default:					netlog("\tunknown quality proto %d\n", proto);					break;				case Plqm:					x = nhgetl(o->data+2)*10;					period = (x+Period-1)/Period;					netlog("\tlqm period = %d\n", period);					break;				}			case Omagic:				netlog("\tmagic = %ux\n", nhgetl(o->data));				break;			case Opc:				netlog("\tprotocol compress\n");				break;			case Oac:				netlog("\taddr compress\n");				break;			}			break;		case Pccp:			switch(o->type){			default:				netlog("\tunknown %d len=%d\n", o->type, o->len);				break;			case Ocoui:					netlog("\tOUI\n");				break;			case Ocstac:				netlog("\tstac LZS\n");				break;			case Ocmppc:					netlog("\tMicrosoft PPC len=%d %ux\n", o->len, nhgetl(o->data));				break;			case Octhwack:					netlog("\tThwack\n");				break;			}			break;		case Pecp:			switch(o->type){			default:				netlog("\tunknown %d len=%d\n", o->type, o->len);				break;			case Oeoui:					netlog("\tOUI\n");				break;			case Oedese:				netlog("\tDES\n");				break;			}			break;		case Pipcp:			switch(o->type){			default:				netlog("\tunknown %d len=%d\n", o->type, o->len);				break;			case Oipaddrs:					netlog("\tip addrs - deprecated\n");				break;			case Oipcompress:				netlog("\tip compress\n");				break;			case Oipaddr:					netlog("\tip addr %V\n", o->data);				break;			case Oipdns:					netlog("\tdns addr %V\n", o->data);				break;			case Oipwins:					netlog("\twins addr %V\n", o->data);				break;			case Oipdns2:					netlog("\tdns2 addr %V\n", o->data);				break;			case Oipwins2:					netlog("\twins2 addr %V\n", o->data);				break;			}			break;		}	}}static voidsendtermreq(PPP *ppp, Pstate *p){	Block *b;	Lcpmsg *m;	p->termid = ++(p->id);	b = alloclcp(Ltermreq, p->termid, 4, &m);	hnputs(m->len, 4);	putframe(ppp, p->proto, b);	freeb(b);	newstate(ppp, p, Sclosing);}static voidsendechoreq(PPP *ppp, Pstate *p){	Block *b;	Lcpmsg *m;	p->termid = ++(p->id);	b = alloclcp(Lechoreq, p->id, 4, &m);	hnputs(m->len, 4);	putframe(ppp, p->proto, b);	freeb(b);}enum{	CtrlD	= 0x4,	CtrlE	= 0x5,	CtrlO	= 0xf,	Cr	= 13,	View	= 0x80,};int conndone;static voidxfer(int fd){	int i, n;	uchar xbuf[128];	for(;;) {		n = read(fd, xbuf, sizeof(xbuf));		if(n < 0)			break;		if(conndone)			break;		for(i = 0; i < n; i++)			if(xbuf[i] == Cr)				xbuf[i] = ' ';		write(1, xbuf, n);	}	close(fd);}static intreadcr(int fd, char *buf, int nbuf){	char c;	int n, tot;	tot = 0;	while((n=read(fd, &c, 1)) == 1){		if(c == '\n'){			buf[tot] = 0;			return tot;		}		buf[tot++] = c;		if(tot == nbuf)			sysfatal("line too long in readcr");	}	return n;}static voidconnect(int fd, int cfd){	int n, ctl;	char xbuf[128];	if (chatfile) {		int chatfd, lineno, nb;		char *buf, *p, *s, response[128];		Dir *dir;		if ((chatfd = open(chatfile, OREAD)) < 0)			sysfatal("cannot open %s: %r", chatfile);		if ((dir = dirfstat(chatfd)) == nil)			sysfatal("cannot fstat %s: %r",chatfile);		buf = (char *)malloc(dir->length + 1);		assert(buf);		if ((nb = read(chatfd, buf, dir->length)) < 0)			sysfatal("cannot read chatfile %s: %r", chatfile);		assert(nb == dir->length);		buf[dir->length] = '\0';		free(dir);		close(chatfd);		p = buf;		lineno = 0;		for(;;) {			char *_args[3];			if ((s = strchr(p, '\n')) == nil)				break;			*s++ = '\0';					lineno++;			if (*p == '#') {				p = s; 				continue;			}			if (tokenize(p, _args, 3) != 2)				sysfatal("invalid line %d (line expected: 'send' 'expect')", 						lineno);			if (debug)				print("sending %s, expecting %s\n", _args[0], _args[1]);			if(strlen(_args[0])){				nb = fprint(fd, "%s\r", _args[0]);				assert(nb > 0);			}			if (strlen(_args[1]) > 0) {				if ((nb = readcr(fd, response, sizeof response-1)) < 0)					sysfatal("cannot read response from: %r");				if (debug)					print("response %s\n", response);				if (nb == 0)					sysfatal("eof on input?\n");				if (cistrstr(response, _args[1]) == nil)					sysfatal("expected %s, got %s\n", _args[1], response);			}			p = s;		}		free(buf);		return;	}	print("Connect to file system now, type ctrl-d when done.\n");	print("...(Use the view or down arrow key to send a break)\n");	print("...(Use ctrl-e to set even parity or ctrl-o for odd)\n");	ctl = open("/dev/consctl", OWRITE);	if(ctl < 0)		sysfatal("opening consctl");	fprint(ctl, "rawon");	fd = dup(fd, -1);	conndone = 0;	switch(rfork(RFPROC|RFMEM|RFNOWAIT)){	case -1:		sysfatal("forking xfer");	case 0:		xfer(fd);		_exits(nil);	}	for(;;){		read(0, xbuf, 1);		switch(xbuf[0]&0xff) {		case CtrlD:	/* done */			conndone = 1;			close(ctl);			print("\n");			return;		case CtrlE:	/* set even parity */			fprint(cfd, "pe");			break;		case CtrlO:	/* set odd parity */			fprint(cfd, "po");			break;		case View:	/* send a break */			fprint(cfd, "k500");			break;		default:			n = write(fd, xbuf, 1);			if(n < 0) {				errstr(xbuf, sizeof(xbuf));				conndone = 1;				close(ctl);				print("[remote write error (%s)]\n", xbuf);				return;			}		}	}}int interactive;voidusage(void){	fprint(2, "usage: ppp [-cCdfPSu] [-b baud] [-k keyspec] [-m mtu] [-p dev] [-s username] [-x netmntpt] [-t modemcmd] [local-addr [remote-addr]]\n");	exits("usage");}voidmain(int argc, char **argv){	int mtu, baud, framing, user, mediain, mediaout, cfd;	Ipaddr ipaddr, remip;	char *dev, *modemcmd;	char net[128];	PPP *ppp;	char buf[128];	rfork(RFREND|RFNOTEG|RFNAMEG);	fmtinstall('I', eipfmt);	fmtinstall('V', eipfmt);	fmtinstall('E', eipfmt);	dev = nil;	invalidate(ipaddr);	invalidate(remip);	mtu = Defmtu;	baud = 0;	framing = 0;	setnetmtpt(net, sizeof(net), nil);	user = 0;	modemcmd = nil;	ARGBEGIN{	case 'b':		baud = atoi(EARGF(usage()));		if(baud < 0)			baud = 0;		break;	case 'c':		nocompress = 1;		break;	case 'C':		noipcompress = 1;		break;	case 'd':		debug++;		break;	case 'f':		framing = 1;		break;	case 'F':		pppframing = 0;		break;	case 'k':		keyspec = EARGF(usage());		break;	case 'm':		mtu = atoi(EARGF(usage()));		if(mtu < Minmtu)			mtu = Minmtu;		if(mtu > Maxmtu)			mtu = Maxmtu;		break;	case 'M':		chatfile = EARGF(usage());		break;	case 'p':		dev = EARGF(usage());		break;	case 'P':		primary = 1;		break;	case 'S':		server = 1;		break;	case 't':		modemcmd = EARGF(usage());		break;	case 'u':		user = 1;		break;	case 'x':		setnetmtpt(net, sizeof net, EARGF(usage()));		break;	default:		fprint(2, "unknown option %c\n", ARGC());		usage();	}ARGEND;	switch(argc){	case 2:		parseip(remip, argv[1]);	case 1:		parseip(ipaddr, argv[0]);	case 0:		break;	default:		usage();	}	nip = nipifcs(net);	if(nip == 0 && !server)		primary = 1;	if(dev != nil){		mediain = open(dev, ORDWR);		if(mediain < 0){			if(strchr(dev, '!')){				if((mediain = dial(dev, 0, 0, &cfd)) == -1){					fprint(2, "ppp: couldn't dial %s: %r\n", dev);					exits(dev);				}			} else {				fprint(2, "ppp: couldn't open %s\n", dev);				exits(dev);			}		} else {			snprint(buf, sizeof buf, "%sctl", dev);			cfd = open(buf, ORDWR);		}		if(cfd > 0){			if(baud)				fprint(cfd, "b%d", baud);			fprint(cfd, "m1");	/* cts/rts flow control (and fifo's) on */			fprint(cfd, "q64000");	/* increase q size to 64k */			fprint(cfd, "n1");	/* nonblocking writes on */			fprint(cfd, "r1");	/* rts on */			fprint(cfd, "d1");	/* dtr on */			fprint(cfd, "c1");	/* dcdhup on */			if(user || chatfile)				connect(mediain, cfd);			close(cfd);		} else {			if(user || chatfile)				connect(mediain, -1);		}		mediaout = mediain;	} else {		mediain = open("/fd/0", OREAD);		if(mediain < 0){			fprint(2, "ppp: couldn't open /fd/0\n");			exits("/fd/0");		}		mediaout = open("/fd/1", OWRITE);		if(mediaout < 0){			fprint(2, "ppp: couldn't open /fd/0\n");			exits("/fd/1");		}	}	if(modemcmd != nil && mediaout >= 0)		fprint(mediaout, "%s\r", modemcmd);	ppp = mallocz(sizeof(*ppp), 1);	pppopen(ppp, mediain, mediaout, net, ipaddr, remip, mtu, framing);	/* wait until ip is configured */	rendezvous((void*)Rmagic, 0);	if(primary){		/* create a /net/ndb entry */		putndb(ppp, net);	}	exits(0);}voidnetlog(char *fmt, ...){	va_list arg;	char *m;	static long start;	long now;	if(debug == 0)		return;	now = time(0);	if(start == 0)		start = now;	va_start(arg, fmt);	m = vsmprint(fmt, arg);	fprint(2, "%ld %s", now-start, m);	free(m);	va_end(arg);}/* *  return non-zero if this is a valid v4 address */static intvalidv4(Ipaddr addr){	return memcmp(addr, v4prefix, IPv4off) == 0 && memcmp(addr, v4prefix, IPaddrlen) != 0;}static voidinvalidate(Ipaddr addr){	ipmove(addr, IPnoaddr);}/* *  return number of networks */static intnipifcs(char *net){	static Ipifc *ifc;	Ipifc *nifc;	Iplifc *lifc;	int n;	n = 0;	ifc = readipifc(net, ifc, -1);	for(nifc = ifc; nifc != nil; nifc = nifc->next)		for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next)			n++;	return n;}/* *   make an ndb entry and put it into /net/ndb for the servers to see */static voidputndb(PPP *ppp, char *net){	char buf[1024];	char file[64];	char *p, *e;	int fd;	e = buf + sizeof(buf);	p = buf;	p = seprint(p, e, "ip=%I ipmask=255.255.255.255 ipgw=%I\n", ppp->local,			ppp->remote);	if(validv4(ppp->dns[0]))		p = seprint(p, e, "\tdns=%I\n", ppp->dns[0]);	if(validv4(ppp->dns[1]))		p = seprint(p, e, "\tdns=%I\n", ppp->dns[1]);	if(validv4(ppp->wins[0]))		p = seprint(p, e, "\twins=%I\n", ppp->wins[0]);	if(validv4(ppp->wins[1]))		p = seprint(p, e, "\twins=%I\n", ppp->wins[1]);	seprint(file, file+sizeof file, "%s/ndb", net);	fd = open(file, OWRITE);	if(fd < 0)		return;	write(fd, buf, p-buf);	close(fd);	seprint(file, file+sizeof file, "%s/cs", net);	fd = open(file, OWRITE);	write(fd, "refresh", 7);	close(fd);	seprint(file, file+sizeof file, "%s/dns", net);	fd = open(file, OWRITE);	write(fd, "refresh", 7);	close(fd);}static voidgetauth(PPP *ppp){	UserPasswd *up;	if(*ppp->chapname)		return;	up = auth_getuserpasswd(auth_getkey,"proto=pass service=ppp %s", keyspec);	if(up != nil){		strcpy(ppp->chapname, up->user);		strcpy(ppp->secret, up->passwd);	}		}

⌨️ 快捷键说明

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