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

📄 ipconfig.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
	sprint(data, "%s/data", devdir);	fd = open(data, ORDWR);	if(fd < 0)		sysfatal("open udp data: %r");	close(cfd);	return fd;}uchar*optadd(uchar *p, int op, void *d, int n){	p[0] = op;	p[1] = n;	memmove(p+2, d, n);	return p+n+2;}uchar*optaddbyte(uchar *p, int op, int b){	p[0] = op;	p[1] = 1;	p[2] = b;	return p+3;}uchar*optaddulong(uchar *p, int op, ulong x){	p[0] = op;	p[1] = 4;	hnputl(p+2, x);	return p+6;}uchar *optaddaddr(uchar *p, int op, uchar *ip){	p[0] = op;	p[1] = 4;	v6tov4(p+2, ip);	return p+6;}uchar *optaddvec(uchar *p, int op, uchar *v, int n){	p[0] = op;	p[1] = n;	memmove(p+2, v, n);	return p+2+n;}uchar *optaddstr(uchar *p, int op, char *v){	int n;	n = strlen(v)+1;	// microsoft leaves on the null, so we do too	p[0] = op;	p[1] = n;	memmove(p+2, v, n);	return p+2+n;}uchar*optget(uchar *p, int op, int *np){	int len, code;	for(;;) {		code = *p++;		if(code == OBpad)			continue;		if(code == OBend)			return 0;		len = *p++;		if(code != op) {			p += len;			continue;		}		if(np != nil){			if(*np > len)				return 0;			*np = len;		}		return p;	}}intoptgetbyte(uchar *p, int op){	int len;	len = 1;	p = optget(p, op, &len);	if(p == 0)		return 0;	return *p;}ulongoptgetulong(uchar *p, int op){	int len;	len = 4;	p = optget(p, op, &len);	if(p == 0)		return 0;	return nhgetl(p);}intoptgetaddr(uchar *p, int op, uchar *ip){	int len;	len = 4;	p = optget(p, op, &len);	if(p == 0)		return 0;	v4tov6(ip, p);	return 1;}intoptgetaddrs(uchar *p, int op, uchar *ip, int n){	int len, i;	len = 4;	p = optget(p, op, &len);	if(p == 0)		return 0;	len /= IPv4addrlen;	if(len > n)		len = n;	for(i = 0; i < len; i++)		v4tov6(&ip[i*IPaddrlen], &p[i*IPv4addrlen]);	return i;}intoptgetvec(uchar *p, int op, uchar *v, int n){	int len;	len = 1;	p = optget(p, op, &len);	if(p == 0)		return 0;	if(len > n)		len = n;	memmove(v, p, len);	return len;}intoptgetstr(uchar *p, int op, char *s, int n){	int len;	len = 1;	p = optget(p, op, &len);	if(p == 0)		return 0;	if(len >= n)		len = n-1;	memmove(s, p, len);	s[len] = 0;	return len;}// sanity check options area//	- options don't overflow packet//	- options end with an OBendintparseoptions(uchar *p, int n){	int code, len;	int nin = n;	while(n>0) {		code = *p++;		n--;		if(code == OBpad)			continue;		if(code == OBend)			return 0;		if(n == 0) {			fprint(2, "%s: parse: bad option: 0x%ux: truncated: opt length = %d\n",				argv0, code, nin);			return -1;		}		len = *p++;		n--;		if(len > n) {			fprint(2, "%s: parse: bad option: 0x%ux: %d > %d: opt length = %d\n",				argv0, code, len, n, nin);			return -1;		}		p += len;		n -= len;			}	// make sure packet ends with an OBend all the optget code	*p = OBend;	return 0;}//  sanity check received packet://	- magic is dhcp magic//	- options don't overflow packetBootp *parsebootp(uchar *p, int n){	Bootp *bp;	bp = (Bootp*)p;	if(n < bp->optmagic - p) {		fprint(2, "%s: parse: short bootp packet\n", argv0);		return nil;	}	if(conf.xid != nhgetl(bp->xid))		return nil;	if(bp->op != Bootreply) {		fprint(2, "%s: parse: bad op\n", argv0);		return nil;	}	n -= bp->optmagic - p;	p = bp->optmagic;	if(n < 4) {		fprint(2, "%s: parse: not option data\n", argv0);		return nil;	}	if(memcmp(optmagic, p, 4) != 0) {		fprint(2, "%s: parse: bad opt magic %ux %ux %ux %ux\n", argv0,			p[0], p[1], p[2], p[3]);		return nil;	}	p += 4;	n -= 4;	if(parseoptions(p, n) < 0)		return nil;	return bp;}// write out an ndb entryvoidwritendb(char *s, int n, int append){	char file[64];	int fd;	snprint(file, sizeof file, "%s/ndb", conf.mpoint);	if(append){		fd = open(file, OWRITE);		seek(fd, 0, 2);	} else		fd = open(file, OWRITE|OTRUNC);	write(fd, s, n);	close(fd);}// put server addresses into the ndb entrychar*putaddrs(char *p, char *e, char *attr, uchar *a, int len){	int i;	for(i = 0; i < len; i += IPaddrlen, a += IPaddrlen){		if(!validip(a))			break;		p = seprint(p, e, "%s=%I\n", attr, a);	}	return p;}// make an ndb entry and put it into /net/ndb for the servers to seevoidputndb(void){	char buf[1024];	char *p, *e, *np;	int append;	e = buf + sizeof(buf);	p = buf;	if(getndb() == 0){		append = 1;	} else {		append = 0;		p = seprint(p, e, "ip=%I ipmask=%M ipgw=%I\n",				conf.laddr, conf.mask, conf.gaddr);	}	if(np = strchr(conf.hostname, '.')){		if(*conf.domainname == 0)			strcpy(conf.domainname, np+1);		*np = 0;	}	if(*conf.hostname)		p = seprint(p, e, "\tsys=%s\n", conf.hostname);	if(*conf.domainname)		p = seprint(p, e, "\tdom=%s.%s\n", conf.hostname, conf.domainname);	if(validip(conf.fs))		p = putaddrs(p, e, "\tfs", conf.fs, sizeof(conf.fs));	if(validip(conf.auth))		p = putaddrs(p, e, "\tauth", conf.auth, sizeof(conf.auth));	if(validip(conf.dns))		p = putaddrs(p, e, "\tdns", conf.dns, sizeof(conf.dns));	if(validip(conf.ntp))		p = putaddrs(p, e, "\tntp", conf.ntp, sizeof(conf.ntp));	if(ndboptions)		p = seprint(p, e, "%s\n", ndboptions);	if(p > buf)		writendb(buf, p-buf, append);}// get an ndb entry someone else wroteintgetndb(void){	char buf[1024];	int fd;	int n;	char *p;	snprint(buf, sizeof buf, "%s/ndb", conf.mpoint);	fd = open(buf, OREAD);	n = read(fd, buf, sizeof(buf)-1);	close(fd);	if(n <= 0)		return -1;	buf[n] = 0;	p = strstr(buf, "ip=");	if(p == nil)		return -1;	parseip(conf.laddr, p+3);	return 0;}// tell a server to refreshvoidtweakserver(char *server){	char file[64];	int fd;	snprint(file, sizeof(file), "%s/%s", conf.mpoint, server);	fd = open(file, ORDWR);	if(fd < 0)		return;	fprint(fd, "refresh");	close(fd);}// tell all servers to refresh their informationvoidtweakservers(void){	tweakserver("dns");	tweakserver("cs");}// return number of networksintnipifcs(char *net){	Ipifc *nifc;	Iplifc *lifc;	int n;	n = 0;	ifc = readipifc(net, ifc, -1);	for(nifc = ifc; nifc != nil; nifc = nifc->next){		/*		 * ignore loopback devices when trying to		 * figure out if we're the primary interface.		 */		if(strcmp(nifc->dev, "/dev/null") != 0)		for(lifc = nifc->lifc; lifc != nil; lifc = lifc->next)			if(validip(lifc->ip)){				n++;				break;			}		if(strcmp(nifc->dev, conf.dev) == 0)			myifc = nifc->index;	}	return n;}// return true if this is a valid v4 addressintvalidip(uchar *addr){	return ipcmp(addr, IPnoaddr) != 0 && ipcmp(addr, v4prefix) != 0;}char *verbs[] = {[Vadd]		"add",[Vremove]	"remove",[Vunbind]	"unbind",[Vether]	"ether",[Vloopback]	"loopback",};// look for an actionintparseverb(char *name){	int i;	for(i = 0; i < nelem(verbs); i++){		if(verbs[i] == 0)			continue;		if(strcmp(name, verbs[i]) == 0)			return i;	}	return -1;}// get everything out of ndbvoidndbconfig(void){	Ndb *db;	Ndbtuple *t, *nt;	char etheraddr[32];	char *attrs[10];	int nattr;	int ndns = 0;	int nfs = 0;	int nauth = 0;	db = ndbopen(0);	if(db == nil)		sysfatal("can't open ndb: %r");	if(strcmp(conf.type, "ether") != 0 || myetheraddr(conf.hwa, conf.dev) != 0)		sysfatal("can't read hardware address");	sprint(etheraddr, "%E", conf.hwa);	nattr = 0;	attrs[nattr++] = "ip";	attrs[nattr++] = "ipmask";	attrs[nattr++] = "ipgw";	attrs[nattr++] = "@dns";	attrs[nattr++] = "@ntp";	attrs[nattr++] = "@fs";	attrs[nattr++] = "@auth";	attrs[nattr] = nil;	t = ndbipinfo(db, "ether", etheraddr, attrs, nattr);	for(nt = t; nt != nil; nt = nt->entry){		if(strcmp(nt->attr, "ip") == 0){			parseip(conf.laddr, nt->val);		} else if(strcmp(nt->attr, "ipmask") == 0){			parseipmask(conf.mask, nt->val);		} else if(strcmp(nt->attr, "ipgw") == 0){			parseip(conf.gaddr, nt->val);		} else if(ndns < 2 && strcmp(nt->attr, "dns") == 0){			parseip(conf.dns+IPaddrlen*ndns, nt->val);		} else if(strcmp(nt->attr, "ntp") == 0){			parseip(conf.ntp, nt->val);		} else if(nfs < 2 && strcmp(nt->attr, "fs") == 0){			parseip(conf.fs+IPaddrlen*nfs, nt->val);		} else if(nauth < 2 && strcmp(nt->attr, "auth") == 0){			parseip(conf.auth+IPaddrlen*nauth, nt->val);		}	}	ndbfree(t);	if(!validip(conf.laddr))		sysfatal("address not found in ndb");}intaddoption(char *opt){	int i;	Option *o;	if(opt == nil)		return -1;	for(o = option; o < &option[nelem(option)]; o++){		if(o->name == nil)			continue;		if(strcmp(opt, o->name) == 0){			i = o-option;			if(!memchr(requested, i, nrequested))				if(nrequested < nelem(requested))					requested[nrequested++] = i;			return 0;		}	}	return -1;}char*optgetx(uchar *p, uchar opt){	Option *o;	int i, n;	ulong x;	char *s, *ns;	uchar ip[IPaddrlen];	uchar ips[16*IPaddrlen];	char str[256];	uchar vec[256];	o = &option[opt];	if(o->name == nil)		return nil;	s = nil;	switch(o->type){	case Taddr:		if(optgetaddr(p, opt, ip))			s = smprint("%s=%I", o->name, ip);		break;	case Taddrs:		n = optgetaddrs(p, opt, ips, 16);		if(n > 0)			s = smprint("%s=%I", o->name, ips);		for(i = 1; i < n; i++){			ns = smprint("%s %s=%I", s, o->name, &ips[i*IPaddrlen]);			free(s);			s = ns;		}		break;	case Tulong:		x = optgetulong(p, opt);		if(x != 0)			s = smprint("%s=%lud", o->name, x);		break;	case Tbyte:		x = optgetbyte(p, opt);		if(x != 0)			s = smprint("%s=%lud", o->name, x);		break;	case Tstr:		if(optgetstr(p, opt, str, sizeof(str)))			s = smprint("%s=%s", o->name, str);		break;	case Tvec:		n = optgetvec(p, opt, vec, sizeof(vec));		if(n > 0)			s = smprint("%s=%.*H", o->name, n, vec);		break;	}	return s;}voidgetoptions(uchar *p){	int i;	char *s, *t;	for(i = nelem(defrequested); i < nrequested; i++){		s = optgetx(p, requested[i]);		if(s != nil)			DEBUG("%s ", s);		if(ndboptions == nil)			ndboptions = smprint("\t%s", s);		else{			t = ndboptions;			ndboptions = smprint("\t%s%s", s, ndboptions);			free(t);		}		free(s);	}}

⌨️ 快捷键说明

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