/* * ipconfig - configure parameters of an ip stack */#include <u.h>#include <libc.h>#include <bio.h>#include <ip.h>#include <ndb.h>#include "ipconfig.h"#include "../dhcp.h" #include <libsec.h> /* genrandom() */ Conf conf;Ipifc* myifc;int beprimary = -1;int noconfig;Ctl *firstctl, **ctll = &firstctl; int debug;int dolog; int plan9 = 1;int Oflag;int rflag;int tflag;int yflag; int dodhcp;int nodhcpwatch;int sendhostname;char *ndboptions;char *ipnet; int ipv6auto;int dupl_disc = 1; /* flag: V6 duplicate neighbor discovery */ int dondbconfig;char *dbfile; static char logfile[] = "ipconfig"; static void openiproute(void);static void binddevice(void);static void controldevice(void);extern void pppbinddev(void); static void doadd(void);static void dodel(void);static void dounbind(void);static void ndbconfig(void); static int Ufmt(Fmt*);#pragma varargck type "U" char* voidusage(void){ fprint(2, "usage: %s [-6dDGnNOpPrtuXy][-b baud][-c ctl]* [-U duid] [-g gw]" "[-h host][-i ipnet][-m mtu][-s dns]...\n" "\t[-f dbfile][-x mtpt][-o dhcpopt] type dev [verb] [laddr [mask " "[raddr [fs [auth]]]]]\n", argv0); exits("usage");} static voidinit(void){ srand(truerand()); fmtinstall('H', encodefmt); fmtinstall('E', eipfmt); fmtinstall('I', eipfmt); fmtinstall('M', eipfmt); fmtinstall('V', eipfmt); fmtinstall('U', Ufmt); fmtinstall('$', ndbvalfmt); nsec(); /* make sure time file is open before forking */ conf.cfd = -1; conf.rfd = -1; setnetmtpt(conf.mpoint, sizeof conf.mpoint, nil); conf.cputype = getenv("cputype"); if(conf.cputype == nil) conf.cputype = "386"; v6paraminit(&conf); dhcpinit();} 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: if (strcmp(argv[1], "0") != 0){ if (parseipandmask(conf.laddr, conf.mask, argv[0], argv[1]) == -1) usage(); break; } /* fall through */ case 1: if (parseip(conf.laddr, argv[0]) == -1) usage(); /* fall through */ case 0: break; default: usage(); }} static char*finddev(char *dir, char *name, char *dev){ int fd, i, nd; Dir *d; fd = open(dir, OREAD); if(fd >= 0){ d = nil; nd = dirreadall(fd, &d); close(fd); for(i=0; i<nd; i++){ if(strncmp(d[i].name, name, strlen(name))) continue; if(strstr(d[i].name, "ctl") != nil) continue; /* ignore ctl files */ dev = smprint("%s/%s", dir, d[i].name); break; } free(d); } return dev;} /* look for an action */static intparseverb(char *name){ static char *verbs[] = { [Vadd] "add", [Vdel] "del", [Vunbind] "unbind", [Vether] "ether", [Vgbe] "gbe", [Vppp] "ppp", [Vloopback] "loopback", [Vaddpref6] "add6", [Vra6] "ra6", [Vtorus] "torus", [Vtree] "tree", [Vpkt] "pkt", [Vnull] "null", }; int i; for(i = 0; i < nelem(verbs); i++) if(verbs[i] != nil && strcmp(name, verbs[i]) == 0) return i; if(strcmp(name, "remove")==0) return Vdel; return -1;} 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) utf2idn(p, conf.hostname, sizeof(conf.hostname)); } /* defaults */ conf.type = "ether"; conf.dev = nil; action = Vadd; /* get optional medium and device */ if (argc > 0){ verb = parseverb(*argv); switch(verb){ case Vether: case Vgbe: case Vloopback: case Vpkt: case Vppp: case Vtorus: case Vtree: case Vnull: conf.type = *argv++; argc--; if(argc > 0){ conf.dev = *argv++; argc--; } else if(verb == Vppp) conf.dev = finddev("/dev", "eia", "/dev/eia0"); break; } } if(conf.dev == nil){ if(!isether()) sysfatal("no device specified for medium %s", conf.type); conf.dev = finddev(conf.mpoint, "ether", "/net/ether0"); } /* 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: case Vnull: sysfatal("medium %s already specified", conf.type); case Vadd: case Vdel: case Vunbind: case Vaddpref6: case Vra6: argv++; argc--; action = verb; break; } } /* get verb-dependent arguments */ switch (action) { case Vadd: case Vdel: case Vunbind: parsenorm(argc, argv); break; case Vaddpref6: parse6pref(argc, argv); break; case Vra6: parse6ra(argc, argv); break; } return action;} /* all interfaces on conf.mpoint stack */static Ipifc *allifcs; static Ipifc*findmyifc(void){ Ipifc *nifc; allifcs = readipifc(conf.mpoint, allifcs, -1); for(nifc = allifcs; nifc != nil; nifc = nifc->next){ if(strcmp(nifc->dev, conf.dev) == 0){ myifc = readipifc(conf.mpoint, myifc, nifc->index); return myifc; } } return nil;} intmyip(Ipifc *ifc, uchar *ip){ for(; ifc != nil; ifc = ifc->next) { if(iplocalonifc(ifc, ip) != nil) return 1; } return 0;} intisether(void){ switch(parseverb(conf.type)){ case Vether: case Vgbe: return 1; } return 0;} /* create a client id */static voidmkclientid(void){ if(isether() && myetheraddr(conf.hwa, conf.dev) == 0){ conf.hwalen = 6; conf.hwatype = 1; conf.cid[0] = conf.hwatype; memmove(&conf.cid[1], conf.hwa, conf.hwalen); conf.cidlen = conf.hwalen+1; if(conf.duidlen == 0){ /* DUID-LL */ conf.duid[0] = 0x00; conf.duid[1] = 0x03; conf.duid[2] = conf.hwatype >> 8; conf.duid[3] = conf.hwatype; memmove(conf.duid+4, conf.hwa, conf.hwalen); conf.duidlen = conf.hwalen+4; } } else { conf.hwatype = -1; snprint((char*)conf.cid, sizeof conf.cid, "plan9_%ld.%d", lrand(), getpid()); conf.cidlen = strlen((char*)conf.cid); genrandom(conf.hwa, sizeof(conf.hwa)); } ea2lla(conf.lladdr, conf.hwa);} voidmain(int argc, char **argv){ uchar ip[IPaddrlen]; int action; Ctl *cp; char *s; init(); 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 'f': dbfile = EARGF(usage()); break; case 'g': if (parseip(conf.gaddr, EARGF(usage())) == -1) usage(); break; case 'G': plan9 = 0; break; case 'h': if(utf2idn(EARGF(usage()), conf.hostname, sizeof(conf.hostname)) <= 0) sysfatal("bad hostname"); sendhostname = 1; break; case 'i': ipnet = EARGF(usage()); break; case 'm': conf.mtu = atoi(EARGF(usage())); break; case 'n': noconfig = 1; break; case 'N': dondbconfig = 1; break; case 'o': if(addoption(EARGF(usage())) < 0) usage(); break; case 'O': Oflag = 1; break; case 'p': beprimary = 1; break; case 'P': beprimary = 0; break; case 'r': rflag = 1; break; case 's': if(parseip(ip, EARGF(usage())) == -1) usage(); addaddrs(conf.dns, sizeof(conf.dns), ip, sizeof(ip)); break; case 't': tflag = 1; break; case 'u': /* IPv6: duplicate neighbour disc. off */ dupl_disc = 0; break; case 'U': /* device unique id used for dhcpv6 */ s = EARGF(usage()); conf.duidlen = dec16(conf.duid, sizeof(conf.duid), s, strlen(s)); if(conf.duidlen <= 0) usage(); break; case 'x': setnetmtpt(conf.mpoint, sizeof conf.mpoint, EARGF(usage())); break; case 'X': nodhcpwatch = 1; break; case 'y': yflag = 1; break; default: usage(); } ARGEND; action = parseargs(argc, argv); if(beprimary == -1 && (ipv6auto || ISIPV6LINKLOCAL(conf.laddr) || parseverb(conf.type) == Vloopback)) beprimary = 0; openiproute(); if(findmyifc() == nil) { switch(action){ default: if(noconfig) break; /* bind new interface */ controldevice(); binddevice(); findmyifc(); case Vunbind: break; case Vdel: /* * interface gone, just remove * default route and ndb entries. */ dodel(); exits(nil); } if(myifc == nil) sysfatal("interface not found for: %s", conf.dev); } else if(!noconfig) { /* open old interface */ binddevice(); } switch(action){ case Vadd: mkclientid(); if(dondbconfig){ dodhcp = 0; beprimary = 0; ndbconfig(); break; }Lines 1–500 of 1297. Load more
/* * ipconfig - configure parameters of an ip stack */ #include <u.h> #include <libc.h> #include <bio.h> #include <ip.h> #include <ndb.h> #include "ipconfig.h" #include "../dhcp.h" #include <libsec.h> /* genrandom() */ Conf conf; Ipifc* myifc; int beprimary = -1; int noconfig; Ctl *firstctl, **ctll = &firstctl; int debug; int dolog; int plan9 = 1; int Oflag; int rflag; int tflag; int yflag; int dodhcp; int nodhcpwatch; int sendhostname; char *ndboptions; char *ipnet; int ipv6auto; int dupl_disc = 1; /* flag: V6 duplicate neighbor discovery */ int dondbconfig; char *dbfile; static char logfile[] = "ipconfig"; static void openiproute(void); static void binddevice(void); static void controldevice(void); extern void pppbinddev(void); static void doadd(void); static void dodel(void); static void dounbind(void); static void ndbconfig(void); static int Ufmt(Fmt*); #pragma varargck type "U" char* void usage(void) { fprint(2, "usage: %s [-6dDGnNOpPrtuXy][-b baud][-c ctl]* [-U duid] [-g gw]" "[-h host][-i ipnet][-m mtu][-s dns]...\n" "\t[-f dbfile][-x mtpt][-o dhcpopt] type dev [verb] [laddr [mask " "[raddr [fs [auth]]]]]\n", argv0); exits("usage"); } static void init(void) { srand(truerand()); fmtinstall('H', encodefmt); fmtinstall('E', eipfmt); fmtinstall('I', eipfmt); fmtinstall('M', eipfmt); fmtinstall('V', eipfmt); fmtinstall('U', Ufmt); fmtinstall('$', ndbvalfmt); nsec(); /* make sure time file is open before forking */ conf.cfd = -1; conf.rfd = -1; setnetmtpt(conf.mpoint, sizeof conf.mpoint, nil); conf.cputype = getenv("cputype"); if(conf.cputype == nil) conf.cputype = "386"; v6paraminit(&conf); dhcpinit(); } void warning(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 void parsenorm(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: if (strcmp(argv[1], "0") != 0){ if (parseipandmask(conf.laddr, conf.mask, argv[0], argv[1]) == -1) usage(); break; } /* fall through */ case 1: if (parseip(conf.laddr, argv[0]) == -1) usage(); /* fall through */ case 0: break; default: usage(); } } static char* finddev(char *dir, char *name, char *dev) { int fd, i, nd; Dir *d; fd = open(dir, OREAD); if(fd >= 0){ d = nil; nd = dirreadall(fd, &d); close(fd); for(i=0; i<nd; i++){ if(strncmp(d[i].name, name, strlen(name))) continue; if(strstr(d[i].name, "ctl") != nil) continue; /* ignore ctl files */ dev = smprint("%s/%s", dir, d[i].name); break; } free(d); } return dev; } /* look for an action */ static int parseverb(char *name) { static char *verbs[] = { [Vadd] "add", [Vdel] "del", [Vunbind] "unbind", [Vether] "ether", [Vgbe] "gbe", [Vppp] "ppp", [Vloopback] "loopback", [Vaddpref6] "add6", [Vra6] "ra6", [Vtorus] "torus", [Vtree] "tree", [Vpkt] "pkt", [Vnull] "null", }; int i; for(i = 0; i < nelem(verbs); i++) if(verbs[i] != nil && strcmp(name, verbs[i]) == 0) return i; if(strcmp(name, "remove")==0) return Vdel; return -1; } static int parseargs(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) utf2idn(p, conf.hostname, sizeof(conf.hostname)); } /* defaults */ conf.type = "ether"; conf.dev = nil; action = Vadd; /* get optional medium and device */ if (argc > 0){ verb = parseverb(*argv); switch(verb){ case Vether: case Vgbe: case Vloopback: case Vpkt: case Vppp: case Vtorus: case Vtree: case Vnull: conf.type = *argv++; argc--; if(argc > 0){ conf.dev = *argv++; argc--; } else if(verb == Vppp) conf.dev = finddev("/dev", "eia", "/dev/eia0"); break; } } if(conf.dev == nil){ if(!isether()) sysfatal("no device specified for medium %s", conf.type); conf.dev = finddev(conf.mpoint, "ether", "/net/ether0"); } /* 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: case Vnull: sysfatal("medium %s already specified", conf.type); case Vadd: case Vdel: case Vunbind: case Vaddpref6: case Vra6: argv++; argc--; action = verb; break; } } /* get verb-dependent arguments */ switch (action) { case Vadd: case Vdel: case Vunbind: parsenorm(argc, argv); break; case Vaddpref6: parse6pref(argc, argv); break; case Vra6: parse6ra(argc, argv); break; } return action; } /* all interfaces on conf.mpoint stack */ static Ipifc *allifcs; static Ipifc* findmyifc(void) { Ipifc *nifc; allifcs = readipifc(conf.mpoint, allifcs, -1); for(nifc = allifcs; nifc != nil; nifc = nifc->next){ if(strcmp(nifc->dev, conf.dev) == 0){ myifc = readipifc(conf.mpoint, myifc, nifc->index); return myifc; } } return nil; } int myip(Ipifc *ifc, uchar *ip) { for(; ifc != nil; ifc = ifc->next) { if(iplocalonifc(ifc, ip) != nil) return 1; } return 0; } int isether(void) { switch(parseverb(conf.type)){ case Vether: case Vgbe: return 1; } return 0; } /* create a client id */ static void mkclientid(void) { if(isether() && myetheraddr(conf.hwa, conf.dev) == 0){ conf.hwalen = 6; conf.hwatype = 1; conf.cid[0] = conf.hwatype; memmove(&conf.cid[1], conf.hwa, conf.hwalen); conf.cidlen = conf.hwalen+1; if(conf.duidlen == 0){ /* DUID-LL */ conf.duid[0] = 0x00; conf.duid[1] = 0x03; conf.duid[2] = conf.hwatype >> 8; conf.duid[3] = conf.hwatype; memmove(conf.duid+4, conf.hwa, conf.hwalen); conf.duidlen = conf.hwalen+4; } } else { conf.hwatype = -1; snprint((char*)conf.cid, sizeof conf.cid, "plan9_%ld.%d", lrand(), getpid()); conf.cidlen = strlen((char*)conf.cid); genrandom(conf.hwa, sizeof(conf.hwa)); } ea2lla(conf.lladdr, conf.hwa); } void main(int argc, char **argv) { uchar ip[IPaddrlen]; int action; Ctl *cp; char *s; init(); 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 'f': dbfile = EARGF(usage()); break; case 'g': if (parseip(conf.gaddr, EARGF(usage())) == -1) usage(); break; case 'G': plan9 = 0; break; case 'h': if(utf2idn(EARGF(usage()), conf.hostname, sizeof(conf.hostname)) <= 0) sysfatal("bad hostname"); sendhostname = 1; break; case 'i': ipnet = EARGF(usage()); break; case 'm': conf.mtu = atoi(EARGF(usage())); break; case 'n': noconfig = 1; break; case 'N': dondbconfig = 1; break; case 'o': if(addoption(EARGF(usage())) < 0) usage(); break; case 'O': Oflag = 1; break; case 'p': beprimary = 1; break; case 'P': beprimary = 0; break; case 'r': rflag = 1; break; case 's': if(parseip(ip, EARGF(usage())) == -1) usage(); addaddrs(conf.dns, sizeof(conf.dns), ip, sizeof(ip)); break; case 't': tflag = 1; break; case 'u': /* IPv6: duplicate neighbour disc. off */ dupl_disc = 0; break; case 'U': /* device unique id used for dhcpv6 */ s = EARGF(usage()); conf.duidlen = dec16(conf.duid, sizeof(conf.duid), s, strlen(s)); if(conf.duidlen <= 0) usage(); break; case 'x': setnetmtpt(conf.mpoint, sizeof conf.mpoint, EARGF(usage())); break; case 'X': nodhcpwatch = 1; break; case 'y': yflag = 1; break; default: usage(); } ARGEND; action = parseargs(argc, argv); if(beprimary == -1 && (ipv6auto || ISIPV6LINKLOCAL(conf.laddr) || parseverb(conf.type) == Vloopback)) beprimary = 0; openiproute(); if(findmyifc() == nil) { switch(action){ default: if(noconfig) break; /* bind new interface */ controldevice(); binddevice(); findmyifc(); case Vunbind: break; case Vdel: /* * interface gone, just remove * default route and ndb entries. */ dodel(); exits(nil); } if(myifc == nil) sysfatal("interface not found for: %s", conf.dev); } else if(!noconfig) { /* open old interface */ binddevice(); } switch(action){ case Vadd: mkclientid(); if(dondbconfig){ dodhcp = 0; beprimary = 0; ndbconfig(); break; }