typedef uint32_t ipaddr_t;
typedef uint8_t ipmask_t;
/*
static inline
ipaddr_t makemask(ipmask_t m) { return m?~((1<<(32-m))-1):0; }
simple, elegant. note that if 1<<32 was guaranteed to yield 0 I
wouldn't even need the ?:.
but that's no fun. let's do it in a table. a simple table would
take... 33*4=132 bytes, plus some code for the lookup:
ipaddr_t masktable[33] = { ... };
ipaddr_t tablemask(ipmast_t m) { returm masktable[m>32?0:m]; }
or we can stuff it in a compressed table:
*/
const unsigned char mmvaltab[] = {
0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
};
/* and now we need a lookuptable to find the correct entry.
and we need to extract the value bytewise. but!
it only takes 57+33=90 bytes of static data. */
unsigned char mmidxtab[] = {
53, 3, 10, 17, 24, 31, 38, 45, 52, 2, 9, 16, 23, 30, 37, 44,
51, 1, 8, 15, 22, 29, 36, 43, 50, 0, 7, 14, 21, 28, 35, 42, 49
};
static inline
ipaddr_t fetchmask(ipmask_t m) {
const unsigned char *t=mmvaltab+mmidxtab[m>32?0:m];
return t[0]<<24|t[1]<<16|t[2]<<8|t[3];
}