unsigned *ip, /* O - Address value */
unsigned *mask) /* O - Mask value */
{
- int i, /* Looping var */
+ int i, j, /* Looping vars */
family, /* Address family */
ipcount; /* Count of fields in address */
+ unsigned ipval; /* Value */
const char *maskval, /* Pointer to start of mask value */
- *ptr; /* Pointer into value */
- static unsigned netmasks[4][4] = /* Standard netmasks... */
+ *ptr, /* Pointer into value */
+ *ptr2; /* ... */
+ static unsigned netmasks[4][4] = /* Standard IPv4 netmasks... */
{
+ { 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000 },
+ { 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000 },
+ { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00 },
+ { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
+ };
+#ifdef AF_INET6
+ static unsigned netmasks6[8][4] = /* Standard IPv6 netmasks... */
+ {
+ { 0xffff0000, 0x00000000, 0x00000000, 0x00000000 },
{ 0xffffffff, 0x00000000, 0x00000000, 0x00000000 },
+ { 0xffffffff, 0xffff0000, 0x00000000, 0x00000000 },
{ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000 },
+ { 0xffffffff, 0xffffffff, 0xffff0000, 0x00000000 },
{ 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000 },
+ { 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000 },
{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
};
+#endif /* AF_INET6 */
/*
family = AF_INET6;
- for (i = 0, ptr = value + 1; *ptr && i < 4; i ++)
+ for (i = 0, ptr = value + 1; *ptr && i < 8; i ++)
{
if (*ptr == ']')
break;
- else if (*ptr == ':')
- ip[i] = 0;
+ else if (!strncmp(ptr, "::", 2))
+ {
+ for (ptr2 = strchr(ptr + 2, ':'), j = 0;
+ ptr2;
+ ptr2 = strchr(ptr2 + 1, ':'), j ++);
+
+ i = 7 - j;
+ }
+ else if (isxdigit(*ptr & 255))
+ {
+ ipval = strtoul(ptr, (char **)&ptr, 16);
+
+ if (ipval > 0xffff)
+ return (0);
+
+ if (i & 1)
+ ip[i] |= ipval;
+ else
+ ip[i] |= ipval << 16;
+ }
else
- ip[i] = strtoul(ptr, (char **)&ptr, 16);
+ return (0);
- if (*ptr == ':' || *ptr == ']')
+ while (*ptr == ':')
ptr ++;
}
memset(mask, 0, sizeof(unsigned) * 4);
#ifdef AF_INET6
- if (maskval[1] == '[')
+ if (*maskval == '[')
{
/*
* Get hexadecimal mask value...
*/
- for (i = 0, ptr = maskval + 1; *ptr && i < 4; i ++)
+ for (i = 0, ptr = maskval + 1; *ptr && i < 8; i ++)
{
if (*ptr == ']')
break;
- else if (*ptr == ':')
- mask[i] = 0;
+ else if (!strncmp(ptr, "::", 2))
+ {
+ for (ptr2 = strchr(ptr + 2, ':'), j = 0;
+ ptr2;
+ ptr2 = strchr(ptr2 + 1, ':'), j ++);
+
+ i = 7 - j;
+ }
+ else if (isxdigit(*ptr & 255))
+ {
+ ipval = strtoul(ptr, (char **)&ptr, 16);
+
+ if (ipval > 0xffff)
+ return (0);
+
+ if (i & 1)
+ mask[i] |= ipval;
+ else
+ mask[i] |= ipval << 16;
+ }
else
- mask[i] = strtoul(ptr, (char **)&ptr, 16);
+ return (0);
- if (*ptr == ':' || *ptr == ']')
+ while (*ptr == ':')
ptr ++;
}
}
}
}
+#ifdef AF_INET6
+ else if (family == AF_INET6)
+ memcpy(mask, netmasks6[ipcount - 1], sizeof(unsigned) * 4);
+#endif /* AF_INET6 */
else
memcpy(mask, netmasks[ipcount - 1], sizeof(unsigned) * 4);