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

Reply via email to