From 20f8f9dd8dcdc4b5c68331c8015c18eaf1813360 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 21 Nov 2004 20:33:09 +0000 Subject: [PATCH] first cut of mask-map: skeleton --- base/chiark-tcl.h | 32 +++++++++++++++++++++++++--- base/hook.c | 6 ++++++ base/parse.c | 35 ++++++++++++++++++++----------- base/tables-examples.tct | 23 ++++++++++++++++++-- base/troglodyte-Makefile | 3 ++- hbytes/hbytes.h | 32 +++++++++++++++++++++++++--- hbytes/hook.c | 6 ++++++ hbytes/parse.c | 35 ++++++++++++++++++++----------- maskmap/maskmap.c | 45 ++++++++++++++++++++++++++++++++++++++++ 9 files changed, 184 insertions(+), 33 deletions(-) create mode 100644 maskmap/maskmap.c diff --git a/base/chiark-tcl.h b/base/chiark-tcl.h index 1014182..207e32a 100644 --- a/base/chiark-tcl.h +++ b/base/chiark-tcl.h @@ -65,6 +65,14 @@ * uint VARNAME/VALUE (VARNAME if ul2bitfields; * ulong VARNAME/VALUE VALUE if bitfields2ul) * + * hbytes mask-map lookup MAP-VAR ADDRESS [DEFAULT] => DATA + * error on missing default or if address too short + * 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 PREFIX + * each PREFIX is truncated to the shortest number of pairs of + * hex digits which can represent it + * * Error codes * * HBYTES BLOCKCIPHER CRYPTFAIL CRYPT block cipher mode failed somehow (!) @@ -105,7 +113,7 @@ #include #include -#include +#include typedef unsigned char Byte; @@ -234,12 +242,30 @@ void obj_updatestr_string(Tcl_Obj *o, const char *str); /* from parse.c */ typedef struct { - HBytes_Value *hb; Tcl_Obj *obj, *var; int copied; +} Something_Var; + +void init_somethingv(Something_Var *sth); +void fini_somethingv(Tcl_Interp *ip, int rc, Something_Var *sth); +int pat_somethingv(Tcl_Interp *ip, Tcl_Obj *var, + Something_Var *sth, Tcl_ObjType *type); + +typedef struct { + HBytes_Value *hb; + Something_Var sth; } HBytes_Var; -void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg); +/* from maskmap.c */ + +typedef struct MaskMap_Value MaskMap_Value; + +typedef struct { + MaskMap_Value *mm; + Something_Var sth; +} MaskMap_Var; + +extern Tcl_ObjType maskmap_type; /* from chop.c */ /* only do_... functions declared in tables.h */ diff --git a/base/hook.c b/base/hook.c index 32c604f..e067c94 100644 --- a/base/hook.c +++ b/base/hook.c @@ -380,6 +380,12 @@ int do_toplevel_ulong(ClientData cd, Tcl_Interp *ip, return subcmd->func(0,ip,objc,objv); } +int do_toplevel_mask_map(ClientData cd, Tcl_Interp *ip, + const MaskMap_SubCommand *subcmd, + int objc, Tcl_Obj *const *objv) { + return subcmd->func(0,ip,objc,objv); +} + #define URANDOM "/dev/urandom" int get_urandom(Tcl_Interp *ip, Byte *buffer, int l) { diff --git a/base/parse.c b/base/parse.c index 911cadd..1d91238 100644 --- a/base/parse.c +++ b/base/parse.c @@ -22,40 +22,51 @@ int pat_string(Tcl_Interp *ip, Tcl_Obj *obj, const char **val) { *val= Tcl_GetString(obj); return TCL_OK; } - -int pat_hbv(Tcl_Interp *ip, Tcl_Obj *var, HBytes_Var *agg) { + +void init_somethingv(Something_Var *sth) { + sth->obj=0; sth->var=0; sth->copied=0; +} + +int pat_somethingv(Tcl_Interp *ip, Tcl_Obj *var, + Something_Var *sth, Tcl_ObjType *type) { int rc; Tcl_Obj *val; - agg->var= var; + sth->var= var; val= Tcl_ObjGetVar2(ip,var,0,TCL_LEAVE_ERR_MSG); if (!val) return TCL_ERROR; - rc= Tcl_ConvertToType(ip,val,&hbytes_type); + rc= Tcl_ConvertToType(ip,val,type); if (rc) return rc; if (Tcl_IsShared(val)) { val= Tcl_DuplicateObj(val); - agg->copied= 1; + sth->copied= 1; } Tcl_InvalidateStringRep(val); - agg->obj= val; + sth->obj= val; - agg->hb= OBJ_HBYTES(val); return TCL_OK; } -void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg) { +int pat_hbv(Tcl_Interp *ip, Tcl_Obj *var, HBytes_Var *agg) { + int rc; + rc= pat_somethingv(ip,var,&agg->sth,&hbytes_type); if (rc) return rc; + agg->hb= OBJ_HBYTES(agg->sth.obj); + return TCL_OK; +} + +void fini_somethingv(Tcl_Interp *ip, int rc, Something_Var *sth) { Tcl_Obj *ro; if (!rc) { - assert(agg->obj); - ro= Tcl_ObjSetVar2(ip,agg->var,0,agg->obj,TCL_LEAVE_ERR_MSG); + assert(sth->obj); + ro= Tcl_ObjSetVar2(ip,sth->var,0,sth->obj,TCL_LEAVE_ERR_MSG); if (!ro) rc= TCL_ERROR; } - if (rc && agg->copied) - Tcl_DecrRefCount(agg->obj); + if (rc && sth->copied) + Tcl_DecrRefCount(sth->obj); } int pat_hb(Tcl_Interp *ip, Tcl_Obj *obj, HBytes_Value *val) { diff --git a/base/tables-examples.tct b/base/tables-examples.tct index 1042378..235f770 100644 --- a/base/tables-examples.tct +++ b/base/tables-examples.tct @@ -2,8 +2,12 @@ Type hb: HBytes_Value @ Init hb hbytes_sentinel(&@); Type hbv: HBytes_Var @ -Init hbv @.hb=0; @.obj=0; @.var=0; @.copied=0; -Fini hbv fini_hbv(ip, rc, &@); +Init hbv @.hb=0; init_somethingv(&@.sth); +Fini hbv fini_somethingv(ip, rc, &@.sth); + +Type maskmapv: MaskMap_Var @ +Init maskmapv @.mm=0; init_somethingv(&@.sth); +Fini maskmapv fini_somethingv(ip, rc, &@.sth); Type sockaddr: SockAddr_Value @ Init sockaddr sockaddr_clear(&@); @@ -30,6 +34,21 @@ Table toplevel TopLevel_Command ulong subcmd enum(ULong_SubCommand,"ulong subcommand") ... obj + mask-map + subcmd enum(MaskMap_SubCommand, "hbytes mask-map subcommand") + ... obj + +Table maskmap MaskMap_SubCommand + lookup + map maskmapv + addr hb + ?def obj + => obj + amend + map maskmapv + prefix hb + preflen int + data obj Table ulong ULong_SubCommand ul2int diff --git a/base/troglodyte-Makefile b/base/troglodyte-Makefile index 1819d87..b6009f8 100644 --- a/base/troglodyte-Makefile +++ b/base/troglodyte-Makefile @@ -14,7 +14,8 @@ OBJS= tables.o \ misc.o \ algtables.o \ crypto.o \ - parse.o + parse.o \ + maskmap.o HDRS= hbytes.h \ $(AUTO_HDRS) diff --git a/hbytes/hbytes.h b/hbytes/hbytes.h index 1014182..207e32a 100644 --- a/hbytes/hbytes.h +++ b/hbytes/hbytes.h @@ -65,6 +65,14 @@ * uint VARNAME/VALUE (VARNAME if ul2bitfields; * ulong VARNAME/VALUE VALUE if bitfields2ul) * + * hbytes mask-map lookup MAP-VAR ADDRESS [DEFAULT] => DATA + * error on missing default or if address too short + * 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 PREFIX + * each PREFIX is truncated to the shortest number of pairs of + * hex digits which can represent it + * * Error codes * * HBYTES BLOCKCIPHER CRYPTFAIL CRYPT block cipher mode failed somehow (!) @@ -105,7 +113,7 @@ #include #include -#include +#include typedef unsigned char Byte; @@ -234,12 +242,30 @@ void obj_updatestr_string(Tcl_Obj *o, const char *str); /* from parse.c */ typedef struct { - HBytes_Value *hb; Tcl_Obj *obj, *var; int copied; +} Something_Var; + +void init_somethingv(Something_Var *sth); +void fini_somethingv(Tcl_Interp *ip, int rc, Something_Var *sth); +int pat_somethingv(Tcl_Interp *ip, Tcl_Obj *var, + Something_Var *sth, Tcl_ObjType *type); + +typedef struct { + HBytes_Value *hb; + Something_Var sth; } HBytes_Var; -void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg); +/* from maskmap.c */ + +typedef struct MaskMap_Value MaskMap_Value; + +typedef struct { + MaskMap_Value *mm; + Something_Var sth; +} MaskMap_Var; + +extern Tcl_ObjType maskmap_type; /* from chop.c */ /* only do_... functions declared in tables.h */ diff --git a/hbytes/hook.c b/hbytes/hook.c index 32c604f..e067c94 100644 --- a/hbytes/hook.c +++ b/hbytes/hook.c @@ -380,6 +380,12 @@ int do_toplevel_ulong(ClientData cd, Tcl_Interp *ip, return subcmd->func(0,ip,objc,objv); } +int do_toplevel_mask_map(ClientData cd, Tcl_Interp *ip, + const MaskMap_SubCommand *subcmd, + int objc, Tcl_Obj *const *objv) { + return subcmd->func(0,ip,objc,objv); +} + #define URANDOM "/dev/urandom" int get_urandom(Tcl_Interp *ip, Byte *buffer, int l) { diff --git a/hbytes/parse.c b/hbytes/parse.c index 911cadd..1d91238 100644 --- a/hbytes/parse.c +++ b/hbytes/parse.c @@ -22,40 +22,51 @@ int pat_string(Tcl_Interp *ip, Tcl_Obj *obj, const char **val) { *val= Tcl_GetString(obj); return TCL_OK; } - -int pat_hbv(Tcl_Interp *ip, Tcl_Obj *var, HBytes_Var *agg) { + +void init_somethingv(Something_Var *sth) { + sth->obj=0; sth->var=0; sth->copied=0; +} + +int pat_somethingv(Tcl_Interp *ip, Tcl_Obj *var, + Something_Var *sth, Tcl_ObjType *type) { int rc; Tcl_Obj *val; - agg->var= var; + sth->var= var; val= Tcl_ObjGetVar2(ip,var,0,TCL_LEAVE_ERR_MSG); if (!val) return TCL_ERROR; - rc= Tcl_ConvertToType(ip,val,&hbytes_type); + rc= Tcl_ConvertToType(ip,val,type); if (rc) return rc; if (Tcl_IsShared(val)) { val= Tcl_DuplicateObj(val); - agg->copied= 1; + sth->copied= 1; } Tcl_InvalidateStringRep(val); - agg->obj= val; + sth->obj= val; - agg->hb= OBJ_HBYTES(val); return TCL_OK; } -void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg) { +int pat_hbv(Tcl_Interp *ip, Tcl_Obj *var, HBytes_Var *agg) { + int rc; + rc= pat_somethingv(ip,var,&agg->sth,&hbytes_type); if (rc) return rc; + agg->hb= OBJ_HBYTES(agg->sth.obj); + return TCL_OK; +} + +void fini_somethingv(Tcl_Interp *ip, int rc, Something_Var *sth) { Tcl_Obj *ro; if (!rc) { - assert(agg->obj); - ro= Tcl_ObjSetVar2(ip,agg->var,0,agg->obj,TCL_LEAVE_ERR_MSG); + assert(sth->obj); + ro= Tcl_ObjSetVar2(ip,sth->var,0,sth->obj,TCL_LEAVE_ERR_MSG); if (!ro) rc= TCL_ERROR; } - if (rc && agg->copied) - Tcl_DecrRefCount(agg->obj); + if (rc && sth->copied) + Tcl_DecrRefCount(sth->obj); } int pat_hb(Tcl_Interp *ip, Tcl_Obj *obj, HBytes_Value *val) { diff --git a/maskmap/maskmap.c b/maskmap/maskmap.c new file mode 100644 index 0000000..9968801 --- /dev/null +++ b/maskmap/maskmap.c @@ -0,0 +1,45 @@ +/* + */ + +#include "tables.h" +#include "hbytes.h" + +typedef struct { + int prefixlen; /* there may be some empty slots with prefixlen==-1 at end */ + Byte *prefix; /* ceil(prefixlen/8) bytes */ + Tcl_Obj *data; +} MaskMap_Entry; + +struct MaskMap_Value { + int allocd; + MaskMap_Entry *entries; +}; /* overlays internalRep */ + +int pat_maskmapv(Tcl_Interp *ip, Tcl_Obj *var, MaskMap_Var *agg) { + int rc; + rc= pat_somethingv(ip,var,&agg->sth,&maskmap_type); if (rc) return rc; + agg->mm= (void*)&agg->sth.obj->internalRep; + return TCL_OK; +} + +int do_maskmap_amend(ClientData cd, Tcl_Interp *ip, + MaskMap_Var map, HBytes_Value prefix, + int preflen, Tcl_Obj *data) { + return TCL_OK; +} + +int do_maskmap_lookup(ClientData cd, Tcl_Interp *ip, + MaskMap_Var map, HBytes_Value addr, Tcl_Obj *def, + Tcl_Obj **result) { + return TCL_OK; +} + +static void maskmap_t_free(Tcl_Obj *o) { } +static void maskmap_t_dup(Tcl_Obj *src, Tcl_Obj *dup) { } +static void maskmap_t_ustr(Tcl_Obj *o) { } +static int maskmap_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { return TCL_ERROR; } + +Tcl_ObjType maskmap_type = { + "mask-map", + maskmap_t_free, maskmap_t_dup, maskmap_t_ustr, maskmap_t_sfa +}; -- 2.30.2