1949 lines · 39.4 KB · C
RawDownload
/* * ipconfig - configure parameters of an ip stack */#include <u.h>#include <libc.h>#include <ip.h>#include <bio.h>#include <ndb.h>#include "../dhcp.h"#include "ipconfig.h" #define DEBUG if(debug)warning /* possible verbs */enum{	/* commands */	Vadd,	Vremove,	Vunbind,	Vaddpref6,	Vra6,	/* media */	Vether,	Vgbe,	Vppp,	Vloopback,	Vtorus,	Vtree,	Vpkt,}; enum{	Taddr,	Taddrs,	Tstr,	Tbyte,	Tulong,	Tvec,}; typedef struct Option Option;struct Option{	char	*name;	int	type;}; /* * I was too lazy to look up the types for each of these * options.  If someone feels like it, please mail me a * corrected array -- presotto */Option option[256] ={[OBmask]		{ "ipmask",		Taddr },[OBtimeoff]		{ "timeoff",		Tulong },[OBrouter]		{ "ipgw",		Taddrs },[OBtimeserver]		{ "time",		Taddrs },[OBnameserver]		{ "name",		Taddrs },[OBdnserver]		{ "dns",		Taddrs },[OBlogserver]		{ "log",		Taddrs },[OBcookieserver]	{ "cookie",		Taddrs },[OBlprserver]		{ "lpr",		Taddrs },[OBimpressserver]	{ "impress",		Taddrs },[OBrlserver]		{ "rl",			Taddrs },[OBhostname]		{ "sys",		Tstr },[OBbflen]		{ "bflen",		Tulong },[OBdumpfile]		{ "dumpfile",		Tstr },[OBdomainname]		{ "dom",		Tstr },[OBswapserver]		{ "swap",		Taddrs },[OBrootpath]		{ "rootpath",		Tstr },[OBextpath]		{ "extpath",		Tstr },[OBipforward]		{ "ipforward",		Taddrs },[OBnonlocal]		{ "nonlocal",		Taddrs },[OBpolicyfilter]	{ "policyfilter",	Taddrs },[OBmaxdatagram]		{ "maxdatagram",	Tulong },[OBttl]			{ "ttl",		Tulong },[OBpathtimeout]		{ "pathtimeout",	Taddrs },[OBpathplateau]		{ "pathplateau",	Taddrs },[OBmtu]			{ "mtu",		Tulong },[OBsubnetslocal]	{ "subnetslocal",	Taddrs },[OBbaddr]		{ "baddr",		Taddrs },[OBdiscovermask]	{ "discovermask",	Taddrs },[OBsupplymask]		{ "supplymask",		Taddrs },[OBdiscoverrouter]	{ "discoverrouter",	Taddrs },[OBrsserver]		{ "rs",			Taddrs },[OBstaticroutes]	{ "staticroutes",	Taddrs },[OBtrailerencap]	{ "trailerencap",	Taddrs },[OBarptimeout]		{ "arptimeout",		Tulong },[OBetherencap]		{ "etherencap",		Taddrs },[OBtcpttl]		{ "tcpttl",		Tulong },[OBtcpka]		{ "tcpka",		Tulong },[OBtcpkag]		{ "tcpkag",		Tulong },[OBnisdomain]		{ "nisdomain",		Tstr },[OBniserver]		{ "ni",			Taddrs },[OBntpserver]		{ "ntp",		Taddrs },[OBnetbiosns]		{ "netbiosns",		Taddrs },[OBnetbiosdds]		{ "netbiosdds",		Taddrs },[OBnetbiostype]		{ "netbiostype",	Taddrs },[OBnetbiosscope]	{ "netbiosscope",	Taddrs },[OBxfontserver]		{ "xfont",		Taddrs },[OBxdispmanager]	{ "xdispmanager",	Taddrs },[OBnisplusdomain]	{ "nisplusdomain",	Tstr },[OBnisplusserver]	{ "nisplus",		Taddrs },[OBhomeagent]		{ "homeagent",		Taddrs },[OBsmtpserver]		{ "smtp",		Taddrs },[OBpop3server]		{ "pop3",		Taddrs },[OBnntpserver]		{ "nntp",		Taddrs },[OBwwwserver]		{ "www",		Taddrs },[OBfingerserver]	{ "finger",		Taddrs },[OBircserver]		{ "irc",		Taddrs },[OBstserver]		{ "st",			Taddrs },[OBstdaserver]		{ "stdar",		Taddrs }, [ODipaddr]		{ "ipaddr",		Taddr },[ODlease]		{ "lease",		Tulong },[ODoverload]		{ "overload",		Taddr },[ODtype]		{ "type",		Tbyte },[ODserverid]		{ "serverid",		Taddr },[ODparams]		{ "params",		Tvec },[ODmessage]		{ "message",		Tstr },[ODmaxmsg]		{ "maxmsg",		Tulong },[ODrenewaltime]		{ "renewaltime",	Tulong },[ODrebindingtime]	{ "rebindingtime",	Tulong },[ODvendorclass]		{ "vendorclass",	Tvec },[ODclientid]		{ "clientid",		Tvec },[ODtftpserver]		{ "tftp",		Taddr },[ODbootfile]		{ "bootfile",		Tstr },}; uchar defrequested[] = {	OBmask, OBrouter, OBdnserver, OBhostname, OBdomainname, OBntpserver,}; uchar	requested[256];int	nrequested; int	Oflag;int	beprimary = -1;Conf	conf;int	debug;int	dodhcp;int	dolog;int	dondbconfig = 0;int	dupl_disc = 1;		/* flag: V6 duplicate neighbor discovery */Ctl	*firstctl, **ctll;Ipifc	*ifc;int	ipv6auto = 0;int	myifc = -1;char	*ndboptions;int	nip;int	noconfig;int	nodhcpwatch;char 	optmagic[4] = { 0x63, 0x82, 0x53, 0x63 };int	plan9 = 1;int	sendhostname; static char logfile[] = "ipconfig"; char *verbs[] = {[Vadd]		"add",[Vremove]	"remove",[Vunbind]	"unbind",[Vether]	"ether",[Vgbe]		"gbe",[Vppp]		"ppp",[Vloopback]	"loopback",[Vaddpref6]	"add6",[Vra6]		"ra6",[Vtorus]	"torus",[Vtree]		"tree",[Vpkt]		"pkt",}; void	adddefroute(char*, uchar*);int	addoption(char*);void	binddevice(void);void	bootprequest(void);void	controldevice(void);void	dhcpquery(int, int);void	dhcprecv(void);void	dhcpsend(int);int	dhcptimer(void);void	dhcpwatch(int);void	doadd(int);void	doremove(void);void	dounbind(void);int	getndb(void);void	getoptions(uchar*);int	ip4cfg(void);int	ip6cfg(int a);void	lookforip(char*);void	mkclientid(void);void	ndbconfig(void);int	nipifcs(char*);int	openlisten(void);uchar*	optaddaddr(uchar*, int, uchar*);uchar*	optaddbyte(uchar*, int, int);uchar*	optaddstr(uchar*, int, char*);uchar*	optadd(uchar*, int, void*, int);uchar*	optaddulong(uchar*, int, ulong);uchar*	optaddvec(uchar*, int, uchar*, int);int	optgetaddrs(uchar*, int, uchar*, int);int	optgetp9addrs(uchar*, int, uchar*, int);int	optgetaddr(uchar*, int, uchar*);int	optgetbyte(uchar*, int);int	optgetstr(uchar*, int, char*, int);uchar*	optget(uchar*, int, int*);ulong	optgetulong(uchar*, int);int	optgetvec(uchar*, int, uchar*, int);char*	optgetx(uchar*, uchar);Bootp*	parsebootp(uchar*, int);int	parseoptions(uchar *p, int n);int	parseverb(char*);void	pppbinddev(void);void	putndb(void);void	tweakservers(void);void	usage(void);int	validip(uchar*);void	writendb(char*, int, int); voidusage(void){	fprint(2, "usage: %s [-6dDGnNOpPruX][-b baud][-c ctl]* [-g gw]"		"[-h host][-m mtu]\n"		"\t[-x mtpt][-o dhcpopt] type dev [verb] [laddr [mask "		"[raddr [fs [auth]]]]]\n", argv0);	exits("usage");} voidwarning(char *fmt, ...){	char buf[1024];	va_list arg; 	va_start(arg, fmt);	vseprint(buf, buf + sizeof buf, fmt, arg);	va_end(arg);	if (dolog)		syslog(0, logfile, "%s", buf);	else		fprint(2, "%s: %s\n", argv0, buf);} static voidparsenorm(int argc, char **argv){	switch(argc){	case 5:		 if (parseip(conf.auth, argv[4]) == -1)			usage();		/* fall through */	case 4:		 if (parseip(conf.fs, argv[3]) == -1)			usage();		/* fall through */	case 3:		 if (parseip(conf.raddr, argv[2]) == -1)			usage();		/* fall through */	case 2:		/*		 * can't test for parseipmask()==-1 cuz 255.255.255.255		 * looks like that.		 */		if (strcmp(argv[1], "0") != 0)			parseipmask(conf.mask, argv[1]);		/* fall through */	case 1:		 if (parseip(conf.laddr, argv[0]) == -1)			usage();		/* fall through */	case 0:		break;	default:		usage();	}} static voidparse6pref(int argc, char **argv){	switch(argc){	case 6:		conf.preflt = strtoul(argv[5], 0, 10);		/* fall through */	case 5:		conf.validlt = strtoul(argv[4], 0, 10);		/* fall through */	case 4:		conf.autoflag = (atoi(argv[3]) != 0);		/* fall through */	case 3:		conf.onlink = (atoi(argv[2]) != 0);		/* fall through */	case 2:		conf.prefixlen = atoi(argv[1]);		/* fall through */	case 1:		if (parseip(conf.v6pref, argv[0]) == -1)			sysfatal("bad address %s", argv[0]);		break;	}	DEBUG("parse6pref: pref %I len %d", conf.v6pref, conf.prefixlen);} /* parse router advertisement (keyword, value) pairs */static voidparse6ra(int argc, char **argv){	int i, argsleft;	char *kw, *val; 	if (argc % 2 != 0)		usage(); 	i = 0;	for (argsleft = argc; argsleft > 1; argsleft -= 2) {		kw =  argv[i];		val = argv[i+1];		if (strcmp(kw, "recvra") == 0)			conf.recvra = (atoi(val) != 0);		else if (strcmp(kw, "sendra") == 0)			conf.sendra = (atoi(val) != 0);		else if (strcmp(kw, "mflag") == 0)			conf.mflag = (atoi(val) != 0);		else if (strcmp(kw, "oflag") == 0)			conf.oflag = (atoi(val) != 0);		else if (strcmp(kw, "maxraint") == 0)			conf.maxraint = atoi(val);		else if (strcmp(kw, "minraint") == 0)			conf.minraint = atoi(val);		else if (strcmp(kw, "linkmtu") == 0)			conf.linkmtu = atoi(val);		else if (strcmp(kw, "reachtime") == 0)			conf.reachtime = atoi(val);		else if (strcmp(kw, "rxmitra") == 0)			conf.rxmitra = atoi(val);		else if (strcmp(kw, "ttl") == 0)			conf.ttl = atoi(val);		else if (strcmp(kw, "routerlt") == 0)			conf.routerlt = atoi(val);		else {			warning("bad ra6 keyword %s", kw);			usage();		}		i += 2;	} 	/* consistency check */	if (conf.maxraint < conf.minraint)		sysfatal("maxraint %d < minraint %d",			conf.maxraint, conf.minraint);} static voidinit(void){	srand(truerand());	fmtinstall('E', eipfmt);	fmtinstall('I', eipfmt);	fmtinstall('M', eipfmt);	fmtinstall('V', eipfmt); 	nsec();			/* make sure time file is open before forking */ 	setnetmtpt(conf.mpoint, sizeof conf.mpoint, nil);	conf.cputype = getenv("cputype");	if(conf.cputype == nil)		conf.cputype = "386"; 	ctll = &firstctl;	v6paraminit(&conf); 	/* init set of requested dhcp parameters with the default */	nrequested = sizeof defrequested;	memcpy(requested, defrequested, nrequested);} static intparseargs(int argc, char **argv){	char *p;	int action, verb; 	/* default to any host name we already have */	if(*conf.hostname == 0){		p = getenv("sysname");		if(p == nil || *p == 0)			p = sysname();		if(p != nil)			strncpy(conf.hostname, p, sizeof conf.hostname-1);	} 	/* defaults */	conf.type = "ether";	conf.dev = "/net/ether0";	action = Vadd; 	/* get optional medium and device */	if (argc > 0){		verb = parseverb(*argv);		switch(verb){		case Vether:		case Vgbe:		case Vppp:		case Vloopback:		case Vtorus:		case Vtree:		case Vpkt:			conf.type = *argv++;			argc--;			if(argc > 0){				conf.dev = *argv++;				argc--;			} else if(verb == Vppp)				conf.dev = "/dev/eia0";			break;		}	} 	/* get optional verb */	if (argc > 0){		verb = parseverb(*argv);		switch(verb){		case Vether:		case Vgbe:		case Vppp:		case Vloopback:		case Vtorus:		case Vtree:		case Vpkt:			sysfatal("medium %s already specified", conf.type);		case Vadd:		case Vremove:		case Vunbind:		case Vaddpref6:		case Vra6:			argv++;			argc--;			action = verb;			break;		}	} 	/* get verb-dependent arguments */	switch (action) {	case Vadd:	case Vremove:	case Vunbind:		parsenorm(argc, argv);		break;	case Vaddpref6:		parse6pref(argc, argv);		break;	case Vra6:		parse6ra(argc, argv);		break;	}	return action;} voidmain(int argc, char **argv){	int retry, action;	Ctl *cp; 	init();	retry = 0;	ARGBEGIN {	case '6': 			/* IPv6 auto config */		ipv6auto = 1;		break;	case 'b':		conf.baud = EARGF(usage());		break;	case 'c':		cp = malloc(sizeof *cp);		if(cp == nil)			sysfatal("%r");		*ctll = cp;		ctll = &cp->next;		cp->next = nil;		cp->ctl = EARGF(usage());		break;	case 'd':		dodhcp = 1;		break;	case 'D':		debug = 1;		break;	case 'g':		if (parseip(conf.gaddr, EARGF(usage())) == -1)			usage();		break;	case 'G':

Lines 1–500 of 1949.