ttestlook.c - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       ttestlook.c (4639B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <ip.h>
            4 #include <bio.h>
            5 #include <ndb.h>
            6 
            7 static uchar noether[6];
            8 
            9 /*
           10  *  Look for a pair with the given attribute.  look first on the same line,
           11  *  then in the whole entry.
           12  */
           13 static Ndbtuple*
           14 lookval(Ndbtuple *entry, Ndbtuple *line, char *attr, char *to)
           15 {
           16         Ndbtuple *nt;
           17 
           18         /* first look on same line (closer binding) */
           19         for(nt = line;;){
           20                 if(strcmp(attr, nt->attr) == 0){
           21                         strncpy(to, nt->val, Ndbvlen);
           22                         return nt;
           23                 }
           24                 nt = nt->line;
           25                 if(nt == line)
           26                         break;
           27         }
           28         /* search whole tuple */
           29         for(nt = entry; nt; nt = nt->entry)
           30                 if(strcmp(attr, nt->attr) == 0){
           31                         strncpy(to, nt->val, Ndbvlen);
           32                         return nt;
           33                 }
           34         return 0;
           35 }
           36 
           37 /*
           38  *  lookup an ip address
           39  */
           40 static uchar*
           41 lookupip(Ndb *db, char *name, uchar *to, Ipinfo *iip)
           42 {
           43         Ndbtuple *t, *nt;
           44         char buf[Ndbvlen];
           45         uchar subnet[IPaddrlen];
           46         Ndbs s;
           47         char *attr;
           48 
           49         attr = ipattr(name);
           50         if(strcmp(attr, "ip") == 0){
           51                 parseip(to, name);
           52                 return to;
           53         }
           54 
           55         t = ndbgetval(db, &s, attr, name, "ip", buf);
           56         if(t){
           57                 /* first look for match on same subnet */
           58                 for(nt = t; nt; nt = nt->entry){
           59                         if(strcmp(nt->attr, "ip") != 0)
           60                                 continue;
           61                         parseip(to, nt->val);
           62                         maskip(to, iip->ipmask, subnet);
           63                         if(memcmp(subnet, iip->ipnet, sizeof(subnet)) == 0)
           64                                 return to;
           65                 }
           66 
           67                 /* otherwise, just take what we have */
           68                 ndbfree(t);
           69                 parseip(to, buf);
           70                 return to;
           71         }
           72         return 0;
           73 }
           74 
           75 /*
           76  *  lookup a subnet and fill in anything we can
           77  */
           78 static void
           79 recursesubnet(Ndb *db, uchar *mask, Ipinfo *iip, char *fs, char *gw, char *au)
           80 {
           81         Ndbs s;
           82         Ndbtuple *t;
           83         uchar submask[IPaddrlen];
           84         char ip[Ndbvlen];
           85 
           86         memmove(iip->ipmask, mask, 4);
           87         maskip(iip->ipaddr, iip->ipmask, iip->ipnet);
           88         sprint(ip, "%I", iip->ipnet);
           89         t = ndbsearch(db, &s, "ip", ip);
           90 print("%s->", ip);
           91         if(t){
           92                 /* look for a further subnet */
           93                 if(lookval(t, s.t, "ipmask", ip)){
           94                         parseip(submask, ip);
           95 
           96                         /* recurse only if it has changed */
           97                         if(!equivip(submask, mask))
           98                                 recursesubnet(db, submask, iip, fs, gw, au);
           99 
          100                 }
          101 
          102                 /* fill in what we don't have */
          103                 if(gw[0] == 0)
          104                         lookval(t, s.t, "ipgw", gw);
          105                 if(fs[0] == 0)
          106                         lookval(t, s.t, "fs", fs);
          107                 if(au[0] == 0)
          108                         lookval(t, s.t, "auth", au);
          109 
          110                 ndbfree(t);
          111         }
          112 }
          113 #ifdef foo
          114 /*
          115  *  find out everything we can about a system from what has been
          116  *  specified.
          117  */
          118 int
          119 ipinfo(Ndb *db, char *etherin, char *ipin, char *name, Ipinfo *iip)
          120 {
          121         Ndbtuple *t;
          122         Ndbs s;
          123         char ether[Ndbvlen];
          124         char ip[Ndbvlen];
          125         char fsname[Ndbvlen];
          126         char gwname[Ndbvlen];
          127         char auname[Ndbvlen];
          128 
          129         memset(iip, 0, sizeof(Ipinfo));
          130         fsname[0] = 0;
          131         gwname[0] = 0;
          132         auname[0] = 0;
          133 
          134         /*
          135          *  look for a matching entry
          136          */
          137         t = 0;
          138         if(etherin)
          139                 t = ndbgetval(db, &s, "ether", etherin, "ip", ip);
          140         if(t == 0 && ipin)
          141                 t = ndbsearch(db, &s, "ip", ipin);
          142         if(t == 0 && name)
          143                 t = ndbgetval(db, &s, ipattr(name), name, "ip", ip);
          144         if(t){
          145                 /*
          146                  *  copy in addresses and name
          147                  */
          148                 if(lookval(t, s.t, "ip", ip))
          149                         parseip(iip->ipaddr, ip);
          150                 if(lookval(t, s.t, "ether", ether))
          151                         parseether(iip->etheraddr, ether);
          152                 lookval(t, s.t, "dom", iip->domain);
          153 
          154                 /*
          155                  *  Look for bootfile, fs, and gateway.
          156                  *  If necessary, search through all entries for
          157                  *  this ip address.
          158                  */
          159                 while(t){
          160                         if(iip->bootf[0] == 0)
          161                                 lookval(t, s.t, "bootf", iip->bootf);
          162                         if(fsname[0] == 0)
          163                                 lookval(t, s.t, "fs", fsname);
          164                         if(gwname[0] == 0)
          165                                 lookval(t, s.t, "ipgw", gwname);
          166                         if(auname[0] == 0)
          167                                 lookval(t, s.t, "auth", auname);
          168                         ndbfree(t);
          169                         if(iip->bootf[0] && fsname[0] && gwname[0] && auname[0])
          170                                 break;
          171                         t = ndbsnext(&s, "ether", ether);
          172                 }
          173         } else if(ipin) {
          174                 /*
          175                  *  copy in addresses (all we know)
          176                  */
          177                 parseip(iip->ipaddr, ipin);
          178                 if(etherin)
          179                         parseether(iip->etheraddr, etherin);
          180         } else
          181                 return -1;
          182 
          183         /*
          184          *  Look up the client's network and find a subnet mask for it.
          185          *  Fill in from the subnet (or net) entry anything we can't figure
          186          *  out from the client record.
          187          */
          188         recursesubnet(db, classmask[CLASS(iip->ipaddr)], iip, fsname, gwname, auname);
          189 
          190         /* lookup fs's and gw's ip addresses */
          191 
          192         if(fsname[0])
          193                 lookupip(db, fsname, iip->fsip, iip);
          194         if(gwname[0])
          195                 lookupip(db, gwname, iip->gwip, iip);
          196         if(auname[0])
          197                 lookupip(db, auname, iip->auip, iip);
          198         return 0;
          199 }
          200 #endif
          201 void
          202 main(int argc, char **argv)
          203 {
          204         Ipinfo ii;
          205         Ndb *db;
          206 
          207         db = ndbopen(0);
          208 
          209         fmtinstall('E', eipconv);
          210         fmtinstall('I', eipconv);
          211         if(argc < 2)
          212                 exits(0);
          213         if(strchr(argv[1], '.')){
          214                 if(ipinfo(db, 0, argv[1], 0, &ii) < 0)
          215                         exits(0);
          216         } else {
          217                 if(ipinfo(db, argv[1], 0, 0, &ii) < 0)
          218                         exits(0);
          219         }
          220         fprint(2, "a %I m %I n %I f %s e %E\n", ii.ipaddr,
          221                 ii.ipmask, ii.ipnet, ii.bootf, ii.etheraddr);
          222 }