📄 inet.c
字号:
#line 88 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/modules/atoms/inet.mx"#include "mal_config.h"#include <gdk.h>#include "mal.h"#include "mal_exception.h"#include "inet.h"#line 99 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/modules/atoms/inet.mx"/** * Creates a new inet from the given string. * Warning: GDK function, does NOT pass a string by reference, and wants * a pointer to a pointer for the retval! * Returns the number of chars read */intINETfromString(str src, int *len, inet **retval){ int i, last, type; lng parse; char *endptr; char sep; last = 0; type = 0; if (*len < (int)sizeof(inet)) { if (*retval != NULL) GDKfree(*retval); *retval = GDKmalloc(sizeof(inet)); } /* handle the nil string */ if (strNil(src)) { in_setnil(*retval); return(0); } /* use the DIY technique to guarantee maximum cross-platform * portability */ for (i = 0; src[i] != '\0'; i++) { if (src[i] == '.' || src[i] == '/') { sep = src[i]; src[i] = '\0'; parse = strtol(src + last, &endptr, 10); if (*endptr != '\0') { /* this is for the cat his violin throw(PARSE, "inet.fromStr", "Error while parsing, unexpected string '%s'", endptr); */ goto error; /* yeah, I know, but I'm just simulating try-catch stuff in C now */ } if (parse > 255 || parse < 0) { /* this is for the cat his violin throw(PARSE, "inet.fromStr", "Illegal quad value: %d", parse); */ goto error; /* yeah, I know, but I'm just simulating try-catch stuff in C now */ } switch (type) { case 0: (*retval)->q1 = (unsigned char) parse; break; case 1: (*retval)->q2 = (unsigned char) parse; break; case 2: (*retval)->q3 = (unsigned char) parse; break; case 3: (*retval)->q4 = (unsigned char) parse; break; } last = i + 1; type++; if (sep == '/') { /* zero out (default) unused bytes */ switch (type) { case 1: (*retval)->q2 = (unsigned char) 0; case 2: (*retval)->q3 = (unsigned char) 0; case 3: (*retval)->q4 = (unsigned char) 0; break; } /* force evaluation of the mask below when we break * out of this loop */ type = 4; break; } } } /* parse the last quad * the contract is that the caller makes sure the string is * null-terminated here */ parse = strtol(src + last, &endptr, 10); if (*endptr != '\0') { /* this is for the cat his violin throw(PARSE, "inet.fromStr", "Error while parsing, unexpected string '%s'", endptr); */ goto error; /* yeah, I know, but I'm just simulating try-catch stuff in C now */ } if (type == 3) { if (parse > 255 || parse < 0) { /* this is for the cat his violin throw(PARSE, "inet.fromStr", "Illegal quad value: %d", parse); */ goto error; /* yeah, I know, but I'm just simulating try-catch stuff in C now */ } (*retval)->q4 = (unsigned char) parse; /* default to an exact match (all bits) */ (*retval)->mask = (unsigned char) 32; } else if (type == 4) { if (parse < 0 || parse > 32) { /* this is for the cat his violin throw(PARSE, "inet.fromStr", "Illegal mask value: %d", parse); */ goto error; /* yeah, I know, but I'm just simulating try-catch stuff in C now */ } (*retval)->mask = (unsigned char) parse; } else { /* this is for the cat his violin throw(PARSE, "inet.fromStr", "Error while parsing, unexpected string '%s'", endptr); */ goto error; /* yeah, I know, but I'm just simulating try-catch stuff in C now */ } return(i);error: /* catch exception: return NULL */ in_setnil(*retval); *len = 0; /* signal INETnew something went wrong */ return(i - 1);}#line 230 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/modules/atoms/inet.mx"/** * Returns the string representation of the given inet value. * Warning: GDK function * Returns the length of the string */intINETtoString(str *retval, int *len, inet *handle){ inet *value = (inet *)handle; if (*len < 19) { if (*retval != NULL) GDKfree(*retval); *retval = GDKmalloc(sizeof(str) * (*len = 19)); } if (in_isnil(value)) { *len = snprintf(*retval, *len, "(nil)"); } else if (value->mask == 32) { *len = snprintf(*retval, *len, "%d.%d.%d.%d", value->q1, value->q2, value->q3, value->q4); } else { *len = snprintf(*retval, *len, "%d.%d.%d.%d/%d", value->q1, value->q2, value->q3, value->q4, value->mask); } return(*len);}#line 261 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/modules/atoms/inet.mx"/** * Returns a inet, parsed from a string. The fromStr function is used * to parse the string. */strINETnew(inet *retval, str *in){ int pos; int len = sizeof(inet); pos = INETfromString(*in, &len, &retval); if (len == 0) throw(PARSE, "inet.new", "Error while parsing at char %d", pos + 1); return (MAL_SUCCEED);}/* === Operators === */#line 286 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/modules/atoms/inet.mx"/** * Returns whether val represents a nil inet value */strINET_isnil(bit *retval, inet * val){ *retval = in_isnil(val); return (MAL_SUCCEED);}#line 302 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/modules/atoms/inet.mx"/** * Returns whether val1 and val2 are equal. */strINET_comp_EQ(bit *retval, inet * val1, inet * val2){ if (in_isnil(val1) || in_isnil(val2)) { *retval = bit_nil; } else if (val1->q1 == val2->q1 && val1->q2 == val2->q2 && val1->q3 == val2->q3 && val1->q4 == val2->q4 && val1->mask == val2->mask) { *retval = 1; } else { *retval = 0; } return (MAL_SUCCEED);}#line 324 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/modules/atoms/inet.mx"/** * Returns whether val1 and val2 are not equal. */strINET_comp_NEQ(bit *retval, inet * val1, inet * val2){ if (in_isnil(val1) || in_isnil(val2)) { *retval = bit_nil; } else if (val1->q1 == val2->q1 && val1->q2 == val2->q2 && val1->q3 == val2->q3 && val1->q4 == val2->q4 && val1->mask == val2->mask) { *retval = 0; } else { *retval = 1; } return (MAL_SUCCEED);}#line 346 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/modules/atoms/inet.mx"/** * Returns whether val1 is smaller than val2. */strINET_comp_LT(bit *retval, inet * val1, inet * val2){ if (in_isnil(val1) || in_isnil(val2)) { *retval = bit_nil; } else if (val1->q1 < val2->q1) { *retval = 1; } else if (val1->q1 > val2->q1) { *retval = 0; } else if (val1->q2 < val2->q2) { *retval = 1; } else if (val1->q2 > val2->q2) { *retval = 0; } else if (val1->q3 < val2->q3) { *retval = 1; } else if (val1->q3 > val2->q3) { *retval = 0; } else if (val1->q4 < val2->q4) { *retval = 1; } else if (val1->q4 > val2->q4) { *retval = 0; } else if (val1->mask < val2->mask) { *retval = 1; } else { *retval = 0; } return (MAL_SUCCEED);}#line 384 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/modules/atoms/inet.mx"/** * Returns whether val1 is greater than val2. */strINET_comp_GT(bit *retval, inet * val1, inet * val2){ return (INET_comp_LT(retval, val2, val1));}#line 398 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/modules/atoms/inet.mx"/** * Returns whether val1 is smaller than or equal to val2. */strINET_comp_LE(bit *retval, inet * val1, inet * val2){ bit ret; INET_comp_LT(&ret, val1, val2); if (ret == 0) INET_comp_EQ(&ret, val1, val2); *retval = ret; return (MAL_SUCCEED);}#line 419 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/modules/atoms/inet.mx"/** * Returns whether val1 is smaller than or equal to val2. */strINET_comp_GE(bit *retval, inet * val1, inet * val2){ bit ret; /* warning: we use LT here with swapped arguments to avoid one * method invocation, since inet_comp_GT does the same */ INET_comp_LT(&ret, val2, val1); if (ret == 0) INET_comp_EQ(&ret, val1, val2); *retval = ret; return (MAL_SUCCEED);}#line 442 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/modules/atoms/inet.mx"/** * Returns whether val1 is contained within val2 */strINET_comp_CW(bit *retval, inet * val1, inet * val2){ if (in_isnil(val1) || in_isnil(val2)) { *retval = bit_nil; } else if (val1->mask <= val2->mask) { /* if the mask is bigger (less specific) or equal it can never * be contained within */ *retval = 0; } else { 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 - 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 */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -