📄 dhcpd.c
字号:
rp->id = toid( o, n); break; case ODparams: if(n > sizeof(rp->requested)) n = sizeof(rp->requested); memmove(rp->requested, o, n); break; case ODvendorclass: if(n >= sizeof(rp->vendorclass)) n = sizeof(rp->vendorclass)-1; memmove(rp->vendorclass, o, n); rp->vendorclass[n] = 0; if(strncmp((char*)rp->vendorclass, "p9-", 3) == 0) strcpy(rp->cputype, (char*)rp->vendorclass+3); break; case OBend: return; } }}voidremrequested(Req *rp, int opt){ uchar *p; p = memchr(rp->requested, opt, sizeof(rp->requested)); if(p != nil) *p = OBpad;}voidmiscoptions(Req *rp, uchar *ip){ char *p; int i, j; uchar *addrs[2]; uchar x[2*IPaddrlen]; uchar vopts[64]; uchar *op, *omax; char *attr[100], **a; int na; Ndbtuple *t; addrs[0] = x; addrs[1] = x+IPaddrlen; /* always supply these */ maskopt(rp, OBmask, rp->gii.ipmask); if(validip(rp->gii.gwip)){ remrequested(rp, OBrouter); addropt(rp, OBrouter, rp->gii.gwip); } else if(validip(rp->giaddr)){ remrequested(rp, OBrouter); addropt(rp, OBrouter, rp->giaddr); } // OBhostname for the HP4000M switches // (this causes NT to log infinite errors - tough shit ) if(*rp->ii.domain){ remrequested(rp, OBhostname); stringopt(rp, OBhostname, rp->ii.domain); } if(*rp->ii.rootpath) stringopt(rp, OBrootpath, rp->ii.rootpath); /* figure out what we need to lookup */ na = 0; a = attr; if(*rp->ii.domain == 0) a[na++] = "dom"; for(i = 0; i < sizeof(rp->requested); i++) switch(rp->requested[i]){ case OBrouter: a[na++] = "@ipgw"; break; case OBdnserver: a[na++] = "@dns"; break; case OBnetbiosns: a[na++] = "@wins"; break; case OBsmtpserver: a[na++] = "@smtp"; break; case OBpop3server: a[na++] = "@pop3"; break; case OBwwwserver: a[na++] = "@www"; break; case OBntpserver: a[na++] = "@ntp"; break; case OBtimeserver: a[na++] = "@time"; break; } if(strncmp((char*)rp->vendorclass, "plan9_", 6) == 0 || strncmp((char*)rp->vendorclass, "p9-", 3) == 0){ a[na++] = "@fs"; a[na++] = "@auth"; } t = lookupinfo(ip, a, na); /* lookup anything we might be missing */ if(*rp->ii.domain == 0) lookupname(rp->ii.domain, t); /* add any requested ones that we know about */ for(i = 0; i < sizeof(rp->requested); i++) switch(rp->requested[i]){ case OBrouter: j = lookupserver("ipgw", addrs, t); addrsopt(rp, OBrouter, addrs, j); break; case OBdnserver: j = lookupserver("dns", addrs, t); addrsopt(rp, OBdnserver, addrs, j); break; case OBhostname: if(*rp->ii.domain) stringopt(rp, OBhostname, rp->ii.domain); break; case OBdomainname: p = strchr(rp->ii.domain, '.'); if(p) stringopt(rp, OBdomainname, p+1); break; case OBnetbiosns: j = lookupserver("wins", addrs, t); addrsopt(rp, OBnetbiosns, addrs, j); break; case OBnetbiostype: /* p-node: peer to peer WINS queries */ byteopt(rp, OBnetbiostype, 0x2); break; case OBsmtpserver: j = lookupserver("smtp", addrs, t); addrsopt(rp, OBsmtpserver, addrs, j); break; case OBpop3server: j = lookupserver("pop3", addrs, t); addrsopt(rp, OBpop3server, addrs, j); break; case OBwwwserver: j = lookupserver("www", addrs, t); addrsopt(rp, OBwwwserver, addrs, j); break; case OBntpserver: j = lookupserver("ntp", addrs, t); addrsopt(rp, OBntpserver, addrs, j); break; case OBtimeserver: j = lookupserver("time", addrs, t); addrsopt(rp, OBtimeserver, addrs, j); break; case OBttl: byteopt(rp, OBttl, 255); break; } // add plan9 specific options if(strncmp((char*)rp->vendorclass, "plan9_", 6) == 0 || strncmp((char*)rp->vendorclass, "p9-", 3) == 0){ // point to temporary area op = rp->p; omax = rp->max; rp->p = vopts; rp->max = vopts + sizeof(vopts) - 1; j = lookupserver("fs", addrs, t); addrsopt(rp, OP9fs, addrs, j); j = lookupserver("auth", addrs, t); addrsopt(rp, OP9auth, addrs, j); // point back j = rp->p - vopts; rp->p = op; rp->max = omax; vectoropt(rp, OBvendorinfo, vopts, j); } ndbfree(t);}intopenlisten(char *net){ int fd, cfd; char data[128]; char devdir[40]; sprint(data, "%s/udp!*!bootp", net); cfd = announce(data, devdir); if(cfd < 0) fatal(1, "can't announce"); if(fprint(cfd, "headers") < 0) fatal(1, "can't set header mode"); fprint(cfd, "oldheaders"); sprint(data, "%s/data", devdir); fd = open(data, ORDWR); if(fd < 0) fatal(1, "open udp data"); return fd;}voidfatal(int syserr, char *fmt, ...){ char buf[ERRMAX]; va_list arg; va_start(arg, fmt); vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); if(syserr) syslog(1, blog, "%s: %r", buf); else syslog(1, blog, "%s", buf); exits(buf);}extern voidwarning(int syserr, char *fmt, ...){ char buf[256]; va_list arg; va_start(arg, fmt); vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); if(syserr){ syslog(0, blog, "%s: %r", buf); if(debug) fprint(2, "%s: %r\n", buf); } else { syslog(0, blog, "%s", buf); if(debug) fprint(2, "%s\n", buf); }}char*readsysname(void){ static char name[128]; char *p; int n, fd; fd = open("/dev/sysname", OREAD); if(fd >= 0){ n = read(fd, name, sizeof(name)-1); close(fd); if(n > 0){ name[n] = 0; return name; } } p = getenv("sysname"); if(p == nil || *p == 0) return "unknown"; return p;}extern intvalidip(uchar *ip){ if(ipcmp(ip, IPnoaddr) == 0) return 0; if(ipcmp(ip, v4prefix) == 0) return 0; return 1;}voidlongopt(Req *rp, int t, long v){ if(rp->p + 6 > rp->max) return; *rp->p++ = t; *rp->p++ = 4; hnputl(rp->p, v); rp->p += 4; op = seprint(op, oe, "%s(%ld)", optname[t], v);}voidaddropt(Req *rp, int t, uchar *ip){ if(rp->p + 6 > rp->max) return; *rp->p++ = t; *rp->p++ = 4; memmove(rp->p, ip+IPv4off, 4); rp->p += 4; op = seprint(op, oe, "%s(%I)", optname[t], ip);}voidmaskopt(Req *rp, int t, uchar *ip){ if(rp->p + 6 > rp->max) return; *rp->p++ = t; *rp->p++ = 4; memmove(rp->p, ip+IPv4off, 4); rp->p += 4; op = seprint(op, oe, "%s(%M)", optname[t], ip);}voidaddrsopt(Req *rp, int t, uchar **ip, int i){ if(i <= 0) return; if(rp->p + 2 + 4*i > rp->max) return; *rp->p++ = t; *rp->p++ = 4*i; op = seprint(op, oe, "%s(", optname[t]); while(i-- > 0){ v6tov4(rp->p, *ip); rp->p += 4; op = seprint(op, oe, "%I", *ip); ip++; if(i > 0) op = seprint(op, oe, " "); } op = seprint(op, oe, ")");}voidbyteopt(Req *rp, int t, uchar v){ if(rp->p + 3 > rp->max) return; *rp->p++ = t; *rp->p++ = 1; *rp->p++ = v; op = seprint(op, oe, "%s(%d)", optname[t], v);}voidtermopt(Req *rp){ if(rp->p + 1 > rp->max) return; *rp->p++ = OBend;}voidstringopt(Req *rp, int t, char *str){ int n; n = strlen(str); if(n > 255) n = 255; if(rp->p+n+2 > rp->max) return; *rp->p++ = t; *rp->p++ = n; memmove(rp->p, str, n); rp->p += n; op = seprint(op, oe, "%s(%s)", optname[t], str);}voidvectoropt(Req *rp, int t, uchar *v, int n){ int i; if(n > 255) n = 255; if(rp->p+n+2 > rp->max) return; *rp->p++ = t; *rp->p++ = n; memmove(rp->p, v, n); rp->p += n; op = seprint(op, oe, "%s(", optname[t]); if(n > 0) op = seprint(op, oe, "%ud", 0); for(i = 1; i < n; i++) op = seprint(op, oe, " %ud", v[i]);}intfromhex(int x){ if(x >= '0' && x <= '9') return x - '0'; return x - 'a';}voidhexopt(Req *rp, int t, char *str){ int n; n = strlen(str); n /= 2; if(n > 255) n = 255; if(rp->p+n+2 > rp->max) return; *rp->p++ = t; *rp->p++ = n; while(n-- > 0){ *rp->p++ = (fromhex(str[0])<<4)|fromhex(str[1]); str += 2; } op = seprint(op, oe, "%s(%s)", optname[t], str);}voidarpenter(uchar *ip, uchar *ether){ int f; char buf[256]; /* brazil */ sprint(buf, "%s/arp", net); f = open(buf, OWRITE); if(f < 0){ syslog(debug, blog, "open %s: %r", buf); return; } fprint(f, "add ether %I %E", ip, ether); close(f);}char *dhcpmsgname[] ={ [Discover] "Discover", [Offer] "Offer", [Request] "Request", [Decline] "Decline", [Ack] "Ack", [Nak] "Nak", [Release] "Release", [Inform] "Inform",};voidlogdhcp(Req *rp){ char buf[4096]; char *p, *e; int i; p = buf; e = buf + sizeof(buf); if(rp->dhcptype > 0 && rp->dhcptype <= Inform) p = seprint(p, e, "%s(", dhcpmsgname[rp->dhcptype]); else p = seprint(p, e, "%d(", rp->dhcptype); p = seprint(p, e, "%I->%I) xid(%ux)flag(%ux)", rp->up->raddr, rp->up->laddr, nhgetl(rp->bp->xid), nhgets(rp->bp->flags)); if(rp->bp->htype == 1) p = seprint(p, e, "ea(%E)", rp->bp->chaddr); if(validip(rp->ciaddr)) p = seprint(p, e, "ci(%I)", rp->ciaddr); if(validip(rp->giaddr)) p = seprint(p, e, "gi(%I)", rp->giaddr); if(validip(rp->ip)) p = seprint(p, e, "ip(%I)", rp->ip); if(rp->id != nil) p = seprint(p, e, "id(%s)", rp->id); if(rp->leasetime) p = seprint(p, e, "leas(%d)", rp->leasetime); if(validip(rp->server)) p = seprint(p, e, "sid(%I)", rp->server); p = seprint(p, e, "need("); for(i = 0; i < sizeof(rp->requested); i++) if(rp->requested[i] != 0) p = seprint(p, e, "%s ", optname[rp->requested[i]]); p = seprint(p, e, ")"); USED(p); syslog(0, blog, "%s", buf);}voidlogdhcpout(Req *rp, char *type){ syslog(0, blog, "%s(%I-%I)id(%s)ci(%V)gi(%V)yi(%V)si(%V) %s", type, rp->up->laddr, rp->up->raddr, rp->id, rp->bp->ciaddr, rp->bp->giaddr, rp->bp->yiaddr, rp->bp->siaddr, optbuf);}/* * if we get behind, it's useless to try answering since the sender * will probably have retransmitted with a differnt sequence number. * So dump all the last message in the queue. */void ding(void*, char *msg){ if(strstr(msg, "alarm")) noted(NCONT); else noted(NDFLT);}intreadlast(int fd, uchar *buf, int len){ int lastn, n; notify(ding); lastn = 0; for(;;){ alarm(20); n = read(fd, buf, len); alarm(0); if(n < 0){ if(lastn > 0) return lastn; break; } lastn = n; } return read(fd, buf, len);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -