plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

testlook.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 }