currently, i'm working on migrating a couple of large ip networks from one ip block to another. rather than a big flag day, we are overlaying the new network on the same segment as the old network, thus, ether0 has both ip networks assigned. this confuses dhcpd because it thinks addresses belonging to the second network are martians, and doesn't respond. here's one possible solution:
/n/sources/plan9//sys/src/cmd/ip/dhcpd/ndb.c:190,195 - ndb.c:170,214 return 0; } + static int + mksamenet(Info *ii, Info *gii) + { + uchar x[IPaddrlen]; + Ipifc *ifc; + Iplifc *lifc, *nexus; + + maskip(ii->ipaddr, gii->ipmask, x); + if(ipcmp(x, gii->ipnet) == 0) + return 0; + + /* find ii's interface */ + for(ifc = ipifcs;; ifc = ifc->next){ + if(ifc == nil) + return -1; + for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){ + maskip(ii->ipaddr, lifc->mask, x); + if(ipcmp(x, lifc->net) == 0) + goto found; + } + } + found: + nexus = lifc; + /* check to see that gii appears on same interface */ + for(lifc = ifc->lifc;; lifc = lifc->next){ + if(lifc == nil) + return -1; + if(ipcmp(lifc->net, gii->ipnet) == 0) + break; + } + + /* fixup incorrect gii information */ + if(lookupip(nexus->ip, gii, 1) < 0) + return -1; + syslog(1, blog, "nexus %I %I is %s:%I\n", + ii->ipaddr, gii->ipaddr, ifc->dev, nexus->net); + return 0; + } + static uchar zeroes[6]; /* /n/sources/plan9//sys/src/cmd/ip/dhcpd/ndb.c:263,269 - ndb.c:284,290 parseip(ciaddr, nt->val); if(lookupip(ciaddr, iip, 0) < 0) continue; - if(samenet(riip->ipaddr, iip)){ + if(mksamenet(iip, riip) == 0){ ndbfree(t); return 0; } - erik