#include <u.h>#include <libc.h>#include <ip.h>#include <bio.h>#include <ndb.h>#include "dhcp.h" int noconfig;int debug;int dodhcp;int nip;int myifc = -1;int plan9 = 1;int beprimary = -1;int nodhcpwatch;int sendhostname;int dondbconfig = 0;int Oflag; char *ndboptions; Ipifc *ifc; // possible verbsenum{ Vadd, Vremove, Vunbind, Vether, Vloopback,}; struct { // locally generated char *type; char *dev; char mpoint[32]; int cfd; // ifc control channel char *cputype; uchar hwa[32]; // hardware address int hwatype; int hwalen; uchar cid[32]; int cidlen; char *baud; // learned info uchar gaddr[IPaddrlen]; uchar laddr[IPaddrlen]; uchar mask[IPaddrlen]; uchar raddr[IPaddrlen]; uchar dns[2*IPaddrlen]; uchar fs[2*IPaddrlen]; uchar auth[2*IPaddrlen]; uchar ntp[IPaddrlen]; int mtu; // dhcp specific int state; int fd; ulong xid; ulong starttime; char sname[64]; char hostname[32]; char domainname[64]; uchar server[IPaddrlen]; /* server IP address */ ulong offered; /* offered lease time */ ulong lease; /* lease time */ ulong resend; /* number of resends for current state */ ulong timeout; /* time to timeout - seconds */} conf; 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 -- presottoOption 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; 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 ipconfig(void);void lookforip(char*);void mkclientid(void);void ndbconfig(void);int nipifcs(char*);int openlisten(void);uchar* optadd(uchar*, int, void*, int);uchar* optaddaddr(uchar*, int, uchar*);uchar* optaddbyte(uchar*, int, int);uchar* optaddstr(uchar*, int, char*);uchar* optaddulong(uchar*, int, ulong);uchar* optaddvec(uchar*, int, uchar*, int);uchar* optget(uchar*, int, int*);int optgetaddr(uchar*, int, uchar*);int optgetaddrs(uchar*, int, uchar*, int);int optgetbyte(uchar*, int);int optgetstr(uchar*, int, char*, 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 putndb(void);void tweakservers(void);void usage(void);int validip(uchar*);void writendb(char*, int, int); char optmagic[4] = { 0x63, 0x82, 0x53, 0x63 }; #define DEBUG if(debug)print typedef struct Ctl Ctl;struct Ctl{ Ctl *next; char *ctl;};Ctl *firstctl, **ctll; voidusage(void){ fprint(2, "usage: %s [-ndDrGX] [-x netmtpt] [-m mtu] [-b baud] [-g gateway] [-h hostname] [-c control-string]* type device [verb] [localaddr [mask [remoteaddr [fsaddr [authaddr]]]]]\n", argv0); exits("usage");} voidmain(int argc, char **argv){ char *p; int retry, verb, action; Ctl *cp; srand(truerand()); fmtinstall('E', eipfmt); fmtinstall('I', eipfmt); fmtinstall('M', eipfmt); fmtinstall('V', eipfmt); setnetmtpt(conf.mpoint, sizeof(conf.mpoint), nil); conf.cputype = getenv("cputype"); if(conf.cputype == nil) conf.cputype = "386"; retry = 0; ctll = &firstctl; // init set of requested parameters with the default nrequested = sizeof(defrequested); memcpy(requested, defrequested, nrequested); ARGBEGIN { case 'D': debug = 1; break; case 'G': plan9 = 0; break; case 'N': dondbconfig = 1; break; case 'O': Oflag = 1; break; case 'p': beprimary = 1; break; case 'P': beprimary = 0; case 'b': p = ARGF(); if(p == nil) usage(); conf.baud = p; break; case 'c': p = ARGF(); if(p == nil) usage(); cp = malloc(sizeof(*cp)); if(cp == nil) sysfatal("%r"); *ctll = cp; ctll = &cp->next; cp->next = nil; cp->ctl = p; break; case 'd': dodhcp = 1; break; case 'g': p = ARGF(); if(p == nil) usage(); parseip(conf.gaddr, p); break; case 'h': p = ARGF(); if(p == nil) usage(); snprint(conf.hostname, sizeof(conf.hostname), "%s", p); sendhostname = 1; break; case 'n': noconfig = 1; break; case 'm': p = ARGF(); if(p == nil) usage(); conf.mtu = atoi(p); break; case 'r': retry = 1; break; case 'x': p = ARGF(); if(p == nil) usage(); setnetmtpt(conf.mpoint, sizeof(conf.mpoint), p); break; case 'X': nodhcpwatch = 1; break; case 'o': if(addoption(ARGF()) < 0) usage(); break; } ARGEND; // 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); } // default conf.type = "ether"; conf.dev = "/net/ether0"; action = Vadd; // get verb, default is "add" while(argc > 0){ verb = parseverb(argv[0]); switch(verb){ case Vadd: case Vremove: case Vunbind: action = verb; break; case Vether: case Vloopback: conf.type = argv[0]; if(argc > 1){ conf.dev = argv[1]; argc--, argv++; } break; } if(verb < 0) break; argc--, argv++; } // get addresses switch(argc){ case 5: parseip(conf.auth, argv[4]); /* fall through */ case 4: parseip(conf.fs, argv[3]); /* fall through */ case 3: parseip(conf.raddr, argv[2]); /* fall through */ case 2: if(strcmp(argv[1], "0") != 0) parseipmask(conf.mask, argv[1]); /* fall through */ case 1: parseip(conf.laddr, argv[0]); break; } switch(action){ case Vadd: doadd(retry); break; case Vremove: doremove(); break; case Vunbind: dounbind(); break; } exits(0);} inthavendb(char *net){ Dir *d; char buf[128]; snprint(buf, sizeof buf, "%s/ndb", net); if((d = dirstat("/net/ndb")) == nil) return 0; if(d->length == 0){ free(d); return 0; } free(d); return 1;} voiddoadd(int retry){ int tries; // get number of preexisting interfaces nip = nipifcs(conf.mpoint); if(beprimary == -1 && (nip == 0 || !havendb(conf.mpoint))) beprimary = 1; // get ipifc into name space and condition device for ip if(!noconfig){ lookforip(conf.mpoint); controldevice(); binddevice(); } if(!validip(conf.laddr)){ if(dondbconfig) ndbconfig(); else dodhcp = 1; } // run dhcp if we need something if(dodhcp){ mkclientid(); for(tries = 0; tries < 2; tries++){ dhcpquery(!noconfig, Sselecting); if(conf.state == Sbound) break; sleep(1000); } } if(!validip(conf.laddr)){ if(retry && dodhcp && !noconfig){ fprint(2, "%s: couldn't determine ip address, retrying\n", argv0); dhcpwatch(1); return; } else { fprint(2, "%s: no success with DHCP\n", argv0); exits("failed"); } } if(!noconfig){ if(ipconfig() < 0) sysfatal("can't start ip"); if(dodhcp && conf.lease != Lforever) dhcpwatch(0); } // leave everything we've learned somewhere other procs can find it if(beprimary == 1){ putndb(); tweakservers(); }} voiddoremove(void){ char file[128]; int cfd; Ipifc *nifc;Lines 1–500 of 1748. Load more
#include <u.h> #include <libc.h> #include <ip.h> #include <bio.h> #include <ndb.h> #include "dhcp.h" int noconfig; int debug; int dodhcp; int nip; int myifc = -1; int plan9 = 1; int beprimary = -1; int nodhcpwatch; int sendhostname; int dondbconfig = 0; int Oflag; char *ndboptions; Ipifc *ifc; // possible verbs enum { Vadd, Vremove, Vunbind, Vether, Vloopback, }; struct { // locally generated char *type; char *dev; char mpoint[32]; int cfd; // ifc control channel char *cputype; uchar hwa[32]; // hardware address int hwatype; int hwalen; uchar cid[32]; int cidlen; char *baud; // learned info uchar gaddr[IPaddrlen]; uchar laddr[IPaddrlen]; uchar mask[IPaddrlen]; uchar raddr[IPaddrlen]; uchar dns[2*IPaddrlen]; uchar fs[2*IPaddrlen]; uchar auth[2*IPaddrlen]; uchar ntp[IPaddrlen]; int mtu; // dhcp specific int state; int fd; ulong xid; ulong starttime; char sname[64]; char hostname[32]; char domainname[64]; uchar server[IPaddrlen]; /* server IP address */ ulong offered; /* offered lease time */ ulong lease; /* lease time */ ulong resend; /* number of resends for current state */ ulong timeout; /* time to timeout - seconds */ } conf; 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; 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 ipconfig(void); void lookforip(char*); void mkclientid(void); void ndbconfig(void); int nipifcs(char*); int openlisten(void); uchar* optadd(uchar*, int, void*, int); uchar* optaddaddr(uchar*, int, uchar*); uchar* optaddbyte(uchar*, int, int); uchar* optaddstr(uchar*, int, char*); uchar* optaddulong(uchar*, int, ulong); uchar* optaddvec(uchar*, int, uchar*, int); uchar* optget(uchar*, int, int*); int optgetaddr(uchar*, int, uchar*); int optgetaddrs(uchar*, int, uchar*, int); int optgetbyte(uchar*, int); int optgetstr(uchar*, int, char*, 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 putndb(void); void tweakservers(void); void usage(void); int validip(uchar*); void writendb(char*, int, int); char optmagic[4] = { 0x63, 0x82, 0x53, 0x63 }; #define DEBUG if(debug)print typedef struct Ctl Ctl; struct Ctl { Ctl *next; char *ctl; }; Ctl *firstctl, **ctll; void usage(void) { fprint(2, "usage: %s [-ndDrGX] [-x netmtpt] [-m mtu] [-b baud] [-g gateway] [-h hostname] [-c control-string]* type device [verb] [localaddr [mask [remoteaddr [fsaddr [authaddr]]]]]\n", argv0); exits("usage"); } void main(int argc, char **argv) { char *p; int retry, verb, action; Ctl *cp; srand(truerand()); fmtinstall('E', eipfmt); fmtinstall('I', eipfmt); fmtinstall('M', eipfmt); fmtinstall('V', eipfmt); setnetmtpt(conf.mpoint, sizeof(conf.mpoint), nil); conf.cputype = getenv("cputype"); if(conf.cputype == nil) conf.cputype = "386"; retry = 0; ctll = &firstctl; // init set of requested parameters with the default nrequested = sizeof(defrequested); memcpy(requested, defrequested, nrequested); ARGBEGIN { case 'D': debug = 1; break; case 'G': plan9 = 0; break; case 'N': dondbconfig = 1; break; case 'O': Oflag = 1; break; case 'p': beprimary = 1; break; case 'P': beprimary = 0; case 'b': p = ARGF(); if(p == nil) usage(); conf.baud = p; break; case 'c': p = ARGF(); if(p == nil) usage(); cp = malloc(sizeof(*cp)); if(cp == nil) sysfatal("%r"); *ctll = cp; ctll = &cp->next; cp->next = nil; cp->ctl = p; break; case 'd': dodhcp = 1; break; case 'g': p = ARGF(); if(p == nil) usage(); parseip(conf.gaddr, p); break; case 'h': p = ARGF(); if(p == nil) usage(); snprint(conf.hostname, sizeof(conf.hostname), "%s", p); sendhostname = 1; break; case 'n': noconfig = 1; break; case 'm': p = ARGF(); if(p == nil) usage(); conf.mtu = atoi(p); break; case 'r': retry = 1; break; case 'x': p = ARGF(); if(p == nil) usage(); setnetmtpt(conf.mpoint, sizeof(conf.mpoint), p); break; case 'X': nodhcpwatch = 1; break; case 'o': if(addoption(ARGF()) < 0) usage(); break; } ARGEND; // 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); } // default conf.type = "ether"; conf.dev = "/net/ether0"; action = Vadd; // get verb, default is "add" while(argc > 0){ verb = parseverb(argv[0]); switch(verb){ case Vadd: case Vremove: case Vunbind: action = verb; break; case Vether: case Vloopback: conf.type = argv[0]; if(argc > 1){ conf.dev = argv[1]; argc--, argv++; } break; } if(verb < 0) break; argc--, argv++; } // get addresses switch(argc){ case 5: parseip(conf.auth, argv[4]); /* fall through */ case 4: parseip(conf.fs, argv[3]); /* fall through */ case 3: parseip(conf.raddr, argv[2]); /* fall through */ case 2: if(strcmp(argv[1], "0") != 0) parseipmask(conf.mask, argv[1]); /* fall through */ case 1: parseip(conf.laddr, argv[0]); break; } switch(action){ case Vadd: doadd(retry); break; case Vremove: doremove(); break; case Vunbind: dounbind(); break; } exits(0); } int havendb(char *net) { Dir *d; char buf[128]; snprint(buf, sizeof buf, "%s/ndb", net); if((d = dirstat("/net/ndb")) == nil) return 0; if(d->length == 0){ free(d); return 0; } free(d); return 1; } void doadd(int retry) { int tries; // get number of preexisting interfaces nip = nipifcs(conf.mpoint); if(beprimary == -1 && (nip == 0 || !havendb(conf.mpoint))) beprimary = 1; // get ipifc into name space and condition device for ip if(!noconfig){ lookforip(conf.mpoint); controldevice(); binddevice(); } if(!validip(conf.laddr)){ if(dondbconfig) ndbconfig(); else dodhcp = 1; } // run dhcp if we need something if(dodhcp){ mkclientid(); for(tries = 0; tries < 2; tries++){ dhcpquery(!noconfig, Sselecting); if(conf.state == Sbound) break; sleep(1000); } } if(!validip(conf.laddr)){ if(retry && dodhcp && !noconfig){ fprint(2, "%s: couldn't determine ip address, retrying\n", argv0); dhcpwatch(1); return; } else { fprint(2, "%s: no success with DHCP\n", argv0); exits("failed"); } } if(!noconfig){ if(ipconfig() < 0) sysfatal("can't start ip"); if(dodhcp && conf.lease != Lforever) dhcpwatch(0); } // leave everything we've learned somewhere other procs can find it if(beprimary == 1){ putndb(); tweakservers(); } } void doremove(void) { char file[128]; int cfd; Ipifc *nifc;