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]; }