📄 ipconfig.c
字号:
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 + -