From: ian Date: Thu, 25 Nov 2004 02:02:52 +0000 (+0000) Subject: mask-map lookup seems to work X-Git-Tag: debian/1.1.1~119 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=commitdiff_plain;h=d6fd8ff47e228354088d5be383a55d1d24099c36 mask-map lookup seems to work --- diff --git a/base/chiark-tcl.h b/base/chiark-tcl.h index 17a0594..4b4f4e8 100644 --- a/base/chiark-tcl.h +++ b/base/chiark-tcl.h @@ -66,7 +66,7 @@ * ulong VARNAME/VALUE VALUE if bitfields2ul) * * hbytes mask-map lookup MAP-VAR ADDRESS [DEFAULT] => DATA - * error on missing default or if address too short + * error on missing default or if any prefix longer than address * hbytes mask-map amend MAP-VAR PREFIX PREFIX-LENGTH DATA * a maskmap MAP is [list [list PREFIX PREFIX-LENGTH DATA]] sorted * first by descending PREFIX-LENGTH and then by ascending PREFIX @@ -86,6 +86,8 @@ * HBYTES LENGTH MISMATCH when blocks must be exactly same length * HBYTES SYNTAX supposed hex block had wrong syntax * HBYTES VALUE OVERFLOW value to be conv'd to hex too big/long + * HBYTES MASKMAP NOMATCH no addr/mask matches address for lookup + * HBYTES MASKMAP UNDERRUN addr value for lookup is too short * HBYTES MASKMAP SYNTAX LLENGTH value for mask-map entry not llength==3 * HBYTES MASKMAP SYNTAX UNDERRUN value for mask-map entry hex too short * HBYTES MASKMAP SYNTAX OVERRUN actual mask-map entry hex too short diff --git a/hbytes/hbytes.h b/hbytes/hbytes.h index 17a0594..4b4f4e8 100644 --- a/hbytes/hbytes.h +++ b/hbytes/hbytes.h @@ -66,7 +66,7 @@ * ulong VARNAME/VALUE VALUE if bitfields2ul) * * hbytes mask-map lookup MAP-VAR ADDRESS [DEFAULT] => DATA - * error on missing default or if address too short + * error on missing default or if any prefix longer than address * hbytes mask-map amend MAP-VAR PREFIX PREFIX-LENGTH DATA * a maskmap MAP is [list [list PREFIX PREFIX-LENGTH DATA]] sorted * first by descending PREFIX-LENGTH and then by ascending PREFIX @@ -86,6 +86,8 @@ * HBYTES LENGTH MISMATCH when blocks must be exactly same length * HBYTES SYNTAX supposed hex block had wrong syntax * HBYTES VALUE OVERFLOW value to be conv'd to hex too big/long + * HBYTES MASKMAP NOMATCH no addr/mask matches address for lookup + * HBYTES MASKMAP UNDERRUN addr value for lookup is too short * HBYTES MASKMAP SYNTAX LLENGTH value for mask-map entry not llength==3 * HBYTES MASKMAP SYNTAX UNDERRUN value for mask-map entry hex too short * HBYTES MASKMAP SYNTAX OVERRUN actual mask-map entry hex too short diff --git a/maskmap/maskmap.c b/maskmap/maskmap.c index 9c92810..f51dba4 100644 --- a/maskmap/maskmap.c +++ b/maskmap/maskmap.c @@ -171,11 +171,45 @@ int do_maskmap_amend(ClientData cd, Tcl_Interp *ip, } int do_maskmap_lookup(ClientData cd, Tcl_Interp *ip, - Tcl_Obj *mapo, HBytes_Value addr, Tcl_Obj *def, + Tcl_Obj *mapo, HBytes_Value addrhb, Tcl_Obj *def, Tcl_Obj **result) { - /*MaskMap_Var *map= (void*)&mapo->internalRep;*/ - *result= Tcl_NewIntObj(42); - return TCL_OK; /*fixme*/ + MaskMap_Value *mm= (void*)&mapo->internalRep; + MaskMap_Entry *search; + const Byte *addr= hbytes_data(&addrhb); + int addrbytes= hbytes_len(&addrhb); + int i, directbytes, leftoverbits; + + search= mm->entries; + if (!search || search->prefixlen==-1) goto not_found; + + /* longest masks are first, so we can test this once */ + if (addrbytes < prefix_bytes(search->prefixlen)) + return staticerr(ip, "address shorter than mask(s) in map", + "HBYTES MASKMAP UNDERRUN"); + + for (i=0; + i < mm->allocd && search->prefixlen != -1; + i++, search++) { + directbytes= search->prefixlen / 8; + if (memcmp(search->prefix, addr, directbytes)) continue; + + leftoverbits= search->prefixlen % 8; + if (leftoverbits) + if ((addr[directbytes] & (0xffu << leftoverbits)) + != search->prefix[directbytes]) + continue; + + /*found*/ + *result= search->data; + return TCL_OK; + } + + not_found: + if (!def) + return staticerr(ip, "address not found in mask-map", + "HBYTES MASKMAP NOMATCH"); + *result= def; + return TCL_OK; } /*---------- Tcl type and arg parsing functions ----------*/