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

📄 dhcpd.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
			rp->id = toid( o, n);			break;		case ODparams:			if(n > sizeof(rp->requested))				n = sizeof(rp->requested);			memmove(rp->requested, o, n);			break;		case ODvendorclass:			if(n >= sizeof(rp->vendorclass))				n = sizeof(rp->vendorclass)-1;			memmove(rp->vendorclass, o, n);			rp->vendorclass[n] = 0;			if(strncmp((char*)rp->vendorclass, "p9-", 3) == 0)				strcpy(rp->cputype, (char*)rp->vendorclass+3);			break;		case OBend:			return;		}	}}voidremrequested(Req *rp, int opt){	uchar *p;	p = memchr(rp->requested, opt, sizeof(rp->requested));	if(p != nil)		*p = OBpad;}voidmiscoptions(Req *rp, uchar *ip){	char *p;	int i, j;	uchar *addrs[2];	uchar x[2*IPaddrlen];	uchar vopts[64];	uchar *op, *omax;	char *attr[100], **a;	int na;	Ndbtuple *t;	addrs[0] = x;	addrs[1] = x+IPaddrlen;	/* always supply these */	maskopt(rp, OBmask, rp->gii.ipmask);	if(validip(rp->gii.gwip)){		remrequested(rp, OBrouter);		addropt(rp, OBrouter, rp->gii.gwip);	} else if(validip(rp->giaddr)){		remrequested(rp, OBrouter);		addropt(rp, OBrouter, rp->giaddr);	}	// OBhostname for the HP4000M switches	// (this causes NT to log infinite errors - tough shit )	if(*rp->ii.domain){		remrequested(rp, OBhostname);		stringopt(rp, OBhostname, rp->ii.domain);	}	if(*rp->ii.rootpath)		stringopt(rp, OBrootpath, rp->ii.rootpath);	/* figure out what we need to lookup */	na = 0;	a = attr;	if(*rp->ii.domain == 0)		a[na++] = "dom";	for(i = 0; i < sizeof(rp->requested); i++)		switch(rp->requested[i]){		case OBrouter:			a[na++] = "@ipgw";			break;		case OBdnserver:			a[na++] = "@dns";			break;		case OBnetbiosns:			a[na++] = "@wins";			break;		case OBsmtpserver:			a[na++] = "@smtp";			break;		case OBpop3server:			a[na++] = "@pop3";			break;		case OBwwwserver:			a[na++] = "@www";			break;		case OBntpserver:			a[na++] = "@ntp";			break;		case OBtimeserver:			a[na++] = "@time";			break;		}	if(strncmp((char*)rp->vendorclass, "plan9_", 6) == 0	|| strncmp((char*)rp->vendorclass, "p9-", 3) == 0){		a[na++] = "@fs";		a[na++] = "@auth";	}	t = lookupinfo(ip, a, na);	/* lookup anything we might be missing */	if(*rp->ii.domain == 0)		lookupname(rp->ii.domain, t);	/* add any requested ones that we know about */	for(i = 0; i < sizeof(rp->requested); i++)		switch(rp->requested[i]){		case OBrouter:			j = lookupserver("ipgw", addrs, t);			addrsopt(rp, OBrouter, addrs, j);			break;		case OBdnserver:			j = lookupserver("dns", addrs, t);			addrsopt(rp, OBdnserver, addrs, j);			break;		case OBhostname:			if(*rp->ii.domain)				stringopt(rp, OBhostname, rp->ii.domain);			break;		case OBdomainname:			p = strchr(rp->ii.domain, '.');			if(p)				stringopt(rp, OBdomainname, p+1);			break;		case OBnetbiosns:			j = lookupserver("wins", addrs, t);			addrsopt(rp, OBnetbiosns, addrs, j);			break;		case OBnetbiostype:			/* p-node: peer to peer WINS queries */			byteopt(rp, OBnetbiostype, 0x2);			break;		case OBsmtpserver:			j = lookupserver("smtp", addrs, t);			addrsopt(rp, OBsmtpserver, addrs, j);			break;		case OBpop3server:			j = lookupserver("pop3", addrs, t);			addrsopt(rp, OBpop3server, addrs, j);			break;		case OBwwwserver:			j = lookupserver("www", addrs, t);			addrsopt(rp, OBwwwserver, addrs, j);			break;		case OBntpserver:			j = lookupserver("ntp", addrs, t);			addrsopt(rp, OBntpserver, addrs, j);			break;		case OBtimeserver:			j = lookupserver("time", addrs, t);			addrsopt(rp, OBtimeserver, addrs, j);			break;		case OBttl:			byteopt(rp, OBttl, 255);			break;		}	// add plan9 specific options	if(strncmp((char*)rp->vendorclass, "plan9_", 6) == 0	|| strncmp((char*)rp->vendorclass, "p9-", 3) == 0){		// point to temporary area		op = rp->p;		omax = rp->max;		rp->p = vopts;		rp->max = vopts + sizeof(vopts) - 1;		j = lookupserver("fs", addrs, t);		addrsopt(rp, OP9fs, addrs, j);		j = lookupserver("auth", addrs, t);		addrsopt(rp, OP9auth, addrs, j);		// point back		j = rp->p - vopts;		rp->p = op;		rp->max = omax;		vectoropt(rp, OBvendorinfo, vopts, j);	}	ndbfree(t);}intopenlisten(char *net){	int fd, cfd;	char data[128];	char devdir[40];	sprint(data, "%s/udp!*!bootp", net);	cfd = announce(data, devdir);	if(cfd < 0)		fatal(1, "can't announce");	if(fprint(cfd, "headers") < 0)		fatal(1, "can't set header mode");	fprint(cfd, "oldheaders");	sprint(data, "%s/data", devdir);	fd = open(data, ORDWR);	if(fd < 0)		fatal(1, "open udp data");	return fd;}voidfatal(int syserr, char *fmt, ...){	char buf[ERRMAX];	va_list arg;	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	if(syserr)		syslog(1, blog, "%s: %r", buf);	else		syslog(1, blog, "%s", buf);	exits(buf);}extern voidwarning(int syserr, char *fmt, ...){	char buf[256];	va_list arg;	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	if(syserr){		syslog(0, blog, "%s: %r", buf);		if(debug)			fprint(2, "%s: %r\n", buf);	} else {		syslog(0, blog, "%s", buf);		if(debug)			fprint(2, "%s\n", buf);	}}char*readsysname(void){	static char name[128];	char *p;	int n, fd;	fd = open("/dev/sysname", OREAD);	if(fd >= 0){		n = read(fd, name, sizeof(name)-1);		close(fd);		if(n > 0){			name[n] = 0;			return name;		}	}	p = getenv("sysname");	if(p == nil || *p == 0)		return "unknown";	return p;}extern intvalidip(uchar *ip){	if(ipcmp(ip, IPnoaddr) == 0)		return 0;	if(ipcmp(ip, v4prefix) == 0)		return 0;	return 1;}voidlongopt(Req *rp, int t, long v){	if(rp->p + 6 > rp->max)		return;	*rp->p++ = t;	*rp->p++ = 4;	hnputl(rp->p, v);	rp->p += 4;	op = seprint(op, oe, "%s(%ld)", optname[t], v);}voidaddropt(Req *rp, int t, uchar *ip){	if(rp->p + 6 > rp->max)		return;	*rp->p++ = t;	*rp->p++ = 4;	memmove(rp->p, ip+IPv4off, 4);	rp->p += 4;	op = seprint(op, oe, "%s(%I)", optname[t], ip);}voidmaskopt(Req *rp, int t, uchar *ip){	if(rp->p + 6 > rp->max)		return;	*rp->p++ = t;	*rp->p++ = 4;	memmove(rp->p, ip+IPv4off, 4);	rp->p += 4;	op = seprint(op, oe, "%s(%M)", optname[t], ip);}voidaddrsopt(Req *rp, int t, uchar **ip, int i){	if(i <= 0)		return;	if(rp->p + 2 + 4*i > rp->max)		return;	*rp->p++ = t;	*rp->p++ = 4*i;	op = seprint(op, oe, "%s(", optname[t]);	while(i-- > 0){		v6tov4(rp->p, *ip);		rp->p += 4;		op = seprint(op, oe, "%I", *ip);		ip++;		if(i > 0)			op = seprint(op, oe, " ");	}	op = seprint(op, oe, ")");}voidbyteopt(Req *rp, int t, uchar v){	if(rp->p + 3 > rp->max)		return;	*rp->p++ = t;	*rp->p++ = 1;	*rp->p++ = v;	op = seprint(op, oe, "%s(%d)", optname[t], v);}voidtermopt(Req *rp){	if(rp->p + 1 > rp->max)		return;	*rp->p++ = OBend;}voidstringopt(Req *rp, int t, char *str){	int n;	n = strlen(str);	if(n > 255)		n = 255;	if(rp->p+n+2 > rp->max)		return;	*rp->p++ = t;	*rp->p++ = n;	memmove(rp->p, str, n);	rp->p += n;	op = seprint(op, oe, "%s(%s)", optname[t], str);}voidvectoropt(Req *rp, int t, uchar *v, int n){	int i;	if(n > 255)		n = 255;	if(rp->p+n+2 > rp->max)		return;	*rp->p++ = t;	*rp->p++ = n;	memmove(rp->p, v, n);	rp->p += n;	op = seprint(op, oe, "%s(", optname[t]);	if(n > 0)		op = seprint(op, oe, "%ud", 0);	for(i = 1; i < n; i++)		op = seprint(op, oe, " %ud", v[i]);}intfromhex(int x){	if(x >= '0' && x <= '9')		return x - '0';	return x - 'a';}voidhexopt(Req *rp, int t, char *str){	int n;	n = strlen(str);	n /= 2;	if(n > 255)		n = 255;	if(rp->p+n+2 > rp->max)		return;	*rp->p++ = t;	*rp->p++ = n;	while(n-- > 0){		*rp->p++ = (fromhex(str[0])<<4)|fromhex(str[1]);		str += 2;	}	op = seprint(op, oe, "%s(%s)", optname[t], str);}voidarpenter(uchar *ip, uchar *ether){	int f;	char buf[256];	/* brazil */	sprint(buf, "%s/arp", net);	f = open(buf, OWRITE);	if(f < 0){		syslog(debug, blog, "open %s: %r", buf);		return;	}	fprint(f, "add ether %I %E", ip, ether);	close(f);}char *dhcpmsgname[] ={	[Discover]	"Discover",	[Offer]		"Offer",	[Request]	"Request",	[Decline]	"Decline",	[Ack]		"Ack",	[Nak]		"Nak",	[Release]	"Release",	[Inform]	"Inform",};voidlogdhcp(Req *rp){	char buf[4096];	char *p, *e;	int i;	p = buf;	e = buf + sizeof(buf);	if(rp->dhcptype > 0 && rp->dhcptype <= Inform)		p = seprint(p, e, "%s(", dhcpmsgname[rp->dhcptype]);	else		p = seprint(p, e, "%d(", rp->dhcptype);	p = seprint(p, e, "%I->%I) xid(%ux)flag(%ux)", rp->up->raddr, rp->up->laddr,		nhgetl(rp->bp->xid), nhgets(rp->bp->flags));	if(rp->bp->htype == 1)		p = seprint(p, e, "ea(%E)", rp->bp->chaddr);	if(validip(rp->ciaddr))		p = seprint(p, e, "ci(%I)", rp->ciaddr);	if(validip(rp->giaddr))		p = seprint(p, e, "gi(%I)", rp->giaddr);	if(validip(rp->ip))		p = seprint(p, e, "ip(%I)", rp->ip);	if(rp->id != nil)		p = seprint(p, e, "id(%s)", rp->id);	if(rp->leasetime)		p = seprint(p, e, "leas(%d)", rp->leasetime);	if(validip(rp->server))		p = seprint(p, e, "sid(%I)", rp->server);	p = seprint(p, e, "need(");	for(i = 0; i < sizeof(rp->requested); i++)		if(rp->requested[i] != 0)			p = seprint(p, e, "%s ", optname[rp->requested[i]]);	p = seprint(p, e, ")");	USED(p);	syslog(0, blog, "%s", buf);}voidlogdhcpout(Req *rp, char *type){	syslog(0, blog, "%s(%I-%I)id(%s)ci(%V)gi(%V)yi(%V)si(%V) %s",		type, rp->up->laddr, rp->up->raddr, rp->id,		rp->bp->ciaddr, rp->bp->giaddr, rp->bp->yiaddr, rp->bp->siaddr, optbuf);}/* *  if we get behind, it's useless to try answering since the sender *  will probably have retransmitted with a differnt sequence number. *  So dump all the last message in the queue. */void ding(void*, char *msg){	if(strstr(msg, "alarm"))		noted(NCONT);	else		noted(NDFLT);}intreadlast(int fd, uchar *buf, int len){	int lastn, n;	notify(ding);	lastn = 0;	for(;;){		alarm(20);		n = read(fd, buf, len);		alarm(0);		if(n < 0){			if(lastn > 0)				return lastn;			break;		}		lastn = n;	}	return read(fd, buf, len);}

⌨️ 快捷键说明

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