📄 inet.mx
字号:
* problems */ /* adjust the mask such that it represents a bit string where * each 1 represents a bit that should match * this is not much clarifying, I know */ mask = 32 - val2->mask; if (mask > 0) m[3] <<= mask; mask -= 8; if (mask > 0) m[2] <<= mask; mask -= 8; if (mask > 0) m[1] <<= mask; mask -= 8; if (mask > 0) m[0] <<= mask; /* if you want to see some bytes, remove this comment fprintf(stderr, "%x %x %x %x => %x %x %x %x %x %x %x %x\n", m[0], m[1], m[2], m[3], val1->q1, val1->q2, val1->q3, val1->q4, val2->q1, val2->q2, val2->q3, val2->q4); */ if ((val1->q1 & m[0]) == (val2->q1 & m[0]) && (val1->q2 & m[1]) == (val2->q2 & m[1]) && (val1->q3 & m[2]) == (val2->q3 & m[2]) && (val1->q4 & m[3]) == (val2->q4 & m[3])) { *retval = 1; } else { *retval = 0; } /* example: (hex notation) * inet1: 10.0.0.0/24 * IP1: 10 00 00 00 * mask1: ff ff ff 00 * &1: 10 00 00 00 * inet2: 10.0.0.254 * IP2: 10 00 00 ef * mask1: ff ff ff 00 * &2: 10 00 00 00 * &1 and &2 are equal, so inet2 is within inet1 */ } return (MAL_SUCCEED);}@malcommand <<=(v:inet,w:inet):bitaddress INET_comp_CWEcomment "Whether v is contained within or is equal to w";@c/** * Returns whether val1 is contained within or equal to val2 */strINET_comp_CWE(bit *retval, inet * val1, inet * val2){ bit ret; /* use existing code, not fully optimal, but cheap enough */ INET_comp_CW(&ret, val1, val2); if (!ret) INET_comp_EQ(&ret, val1, val2); *retval = ret; return (MAL_SUCCEED);}@malcommand >>(v:inet,w:inet):bitaddress INET_comp_CScomment "Whether v contains w";@c/** * Returns whether val1 is contains val2 */strINET_comp_CS(bit *retval, inet * val1, inet * val2){ /* swap the input arguments and call the contained within function */ return (INET_comp_CW(retval, val2, val1));}@malcommand >>=(v:inet,w:inet):bitaddress INET_comp_CSEcomment "Whether v contains or is equal to w";@c/** * Returns whether val1 contains or is equal to val2 */strINET_comp_CSE(bit *retval, inet * val1, inet * val2){ /* swap the input arguments and call the contained within function */ return (INET_comp_CWE(retval, val2, val1));}/* === Functions === */@malcommand broadcast(:inet):inetaddress INETbroadcastcomment "Returns the broadcast address for network";@c/** * Returns the broadcast address for the network the inet represents. * If the subnet mask is 32, the given input inet is returned. */strINETbroadcast(inet * retval, inet * val){ *retval = *val; if (!in_isnil(val) && val->mask != 32) { int mask; unsigned char m[4] = { -1, -1, -1, -1 }; /* all operations here are done byte based, to avoid byte sex * problems */ /* adjust the mask such that it represents a bit string where * each 1 represents a bit that should match * this is not much clarifying, I know */ mask = val->mask; if (mask > 0) m[0] >>= mask; mask -= 8; if (mask > 0) m[1] >>= mask; mask -= 8; if (mask > 0) m[2] >>= mask; mask -= 8; if (mask > 0) m[3] >>= mask; /* if you want to see some bytes, remove this comment fprintf(stderr, "%x %x %x %x => %x %x %x %x\n", m[0], m[1], m[2], m[3], val->q1, val->q2, val->q3, val->q4); */ /* apply the inverted mask, so we get the broadcast */ retval->q1 |= m[0]; retval->q2 |= m[1]; retval->q3 |= m[2]; retval->q4 |= m[3]; /* example: (hex notation) * inet: 10.0.0.1/24 * IP: 10 00 00 01 * mask: 00 00 00 ff * &: 10 00 00 ff * results in 10.0.0.255 */ } return (MAL_SUCCEED);}@malcommand host(:inet):straddress INEThostcomment "Extract IP address as text";@c/** * Extract only the IP address as text. Unlike the toString function, * this function never returns the netmask length. */strINEThost(str *retval, inet * val){ str ip; if (in_isnil(val)) { *retval = GDKstrdup(str_nil); } else { ip = GDKmalloc(sizeof(char) * 16); sprintf(ip, "%d.%d.%d.%d", val->q1, val->q2, val->q3, val->q4); *retval = ip; } return (MAL_SUCCEED);}@malcommand masklen(:inet):intaddress INETmasklencomment "Extract netmask length";@c/** * Extract netmask length. */strINETmasklen(int *retval, inet * val){ if (in_isnil(val)) { *retval = int_nil; } else { *retval = val->mask; } return (MAL_SUCCEED);}@malcommand setmasklen(:inet,:int):inetaddress INETsetmasklencomment "Set netmask length for inet value";@c/** * Set netmask length for inet value. */strINETsetmasklen(inet * retval, inet * val, int *mask){ if (*mask < 0 || *mask > 32) throw(ILLARG, "inet.setmask", "Illegal netmask length value: %d", *mask); *retval = *val; if (!in_isnil(val)) retval->mask = *mask; return (MAL_SUCCEED);}@malcommand netmask(:inet):inetaddress INETnetmaskcomment "Construct netmask for network";@c/** * Construct netmask for network. */strINETnetmask(inet * retval, inet * val){ *retval = *val; if (!in_isnil(val)) { int mask; unsigned char m[4] = { -1, -1, -1, -1 }; /* all operations here are done byte based, to avoid byte sex * problems */ /* adjust the mask such that it represents a bit string where * each 1 represents a bit that should match * this is not much clarifying, I know */ mask = 32 - val->mask; if (mask > 0) m[3] <<= mask; mask -= 8; if (mask > 0) m[2] <<= mask; mask -= 8; if (mask > 0) m[1] <<= mask; mask -= 8; if (mask > 0) m[0] <<= mask; retval->q1 = m[0]; retval->q2 = m[1]; retval->q3 = m[2]; retval->q4 = m[3]; retval->mask = 32; /* example: (hex notation) * inet: 10.0.0.1/24 * mask: ff ff ff 00 * results in 255.255.255.0 */ } return (MAL_SUCCEED);}@malcommand hostmask(:inet):inetaddress INEThostmaskcomment "Construct host mask for network";@c/** * Construct host mask for network. */strINEThostmask(inet * retval, inet * val){ INETnetmask(retval, val); /* invert the netmask to obtain the host mask */ if (!in_isnil(retval)) { retval->q1 = ~retval->q1; retval->q2 = ~retval->q2; retval->q3 = ~retval->q3; retval->q4 = ~retval->q4; } /* example: (hex notation) * netmask: 255.255.255.0 * IP: ff ff ff 00 * ~: 00 00 00 ff * results in 0.0.0.255 */ return (MAL_SUCCEED);}@malcommand network(:inet):inetaddress INETnetworkcomment "Extract network part of address";@c/** * Extract network part of address, returns the same inet if the netmask * is equal to 32. This function basically zeros out values that are * not covered by the netmask. */strINETnetwork(inet * retval, inet * val){ *retval = *val; if (!in_isnil(val)) { int mask; unsigned char m[4] = { -1, -1, -1, -1 }; /* all operations here are done byte based, to avoid byte sex * problems */ /* adjust the mask such that it represents a bit string where * each 1 represents a bit that should match * this is not much clarifying, I know */ mask = 32 - val->mask; if (mask > 0) m[3] <<= mask; mask -= 8; if (mask > 0) m[2] <<= mask; mask -= 8; if (mask > 0) m[1] <<= mask; mask -= 8; if (mask > 0) m[0] <<= mask; retval->q1 &= m[0]; retval->q2 &= m[1]; retval->q3 &= m[2]; retval->q4 &= m[3]; /* example: (hex notation) * inet: 10.0.0.1/24 * IP: 10 00 00 01 * mask: ff ff ff 00 * &: 10 00 00 00 * results in 10.0.0.0/24 */ } return (MAL_SUCCEED);}@malcommand text(:inet):straddress INETtextcomment "Extract IP address and netmask length as text";@c/** * Extract IP address and netmask length as text. Unlike the toStr * function, this function always prints the netmask length. */strINETtext(str *retval, inet * val){ str ip; if (in_isnil(val)) { *retval = GDKstrdup(str_nil); } else { ip = GDKmalloc(sizeof(char) * 19); sprintf(ip, "%d.%d.%d.%d/%d", val->q1, val->q2, val->q3, val->q4, val->mask); *retval = ip; } return (MAL_SUCCEED);}@malcommand abbrev(:inet):straddress INETabbrevcomment "Abbreviated display format as text";@c/** * Abbreviated display format as text. The abbreviation is only made if * the value has no bits set to right of mask. Otherwise the return of * this function is equal to the function text. */strINETabbrev(str *retval, inet * val){ str ip; if (in_isnil(val)) { *retval = GDKstrdup(str_nil); } else { int mask = 32 - val->mask; unsigned char m[4] = { -1, -1, -1, -1 }; /* Zero all bits that are allowed to be in there according to * the netmask length. Afterwards it is easy to see if there * are bits set to the right of the mask, since then all four * quads are zero. */ mask = val->mask; if (mask > 0) m[0] >>= mask; mask -= 8; if (mask > 0) m[1] >>= mask; mask -= 8; if (mask > 0) m[2] >>= mask; mask -= 8; if (mask > 0) m[3] >>= mask; if ((val->q1 & m[0]) != 0 || (val->q2 & m[1]) != 0 || (val->q3 & m[2]) != 0 || (val->q4 & m[3]) != 0) { mask = 32; } else { mask = val->mask; } /* example: (hex notation) * inet: 10.1.0.0/16 * IP: 10 01 00 00 * mask: 00 00 ff ff * &: 00 00 00 00 * all zero, thus no bits on the right side of the mask */ ip = GDKmalloc(sizeof(char) * 19); if (mask > 24) { sprintf(ip, "%d.%d.%d.%d/%d", val->q1, val->q2, val->q3, val->q4, val->mask); } else if (mask > 16) { sprintf(ip, "%d.%d.%d/%d", val->q1, val->q2, val->q3, val->mask); } else if (mask > 8) { sprintf(ip, "%d.%d/%d", val->q1, val->q2, val->mask); } else if (mask > 0) { sprintf(ip, "%d/%d", val->q1, val->mask); } else { sprintf(ip, "/0"); } *retval = ip; } return (MAL_SUCCEED);}@}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -