From: mike Date: Sun, 9 Oct 2005 02:38:15 +0000 (+0000) Subject: Fix parsing of address masks, more of STR #1313. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d0844fb25dc75cafc4c2aac7fb259c35586fb9eb;p=thirdparty%2Fcups.git Fix parsing of address masks, more of STR #1313. scheduler/conf.c: - get_addr_and_mask(): Fix parsing of IPv6 addresses, and separate IPv4 and IPv6 default masks. git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@4761 7a7537e8-13f0-0310-91df-b6672ffda945 --- diff --git a/scheduler/conf.c b/scheduler/conf.c index a20a592d1..9b60f018c 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -1199,18 +1199,33 @@ get_addr_and_mask(const char *value, /* I - String from config file */ 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 */ /* @@ -1237,16 +1252,34 @@ get_addr_and_mask(const char *value, /* I - String from config file */ 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 ++; } @@ -1278,22 +1311,40 @@ get_addr_and_mask(const char *value, /* I - String from config file */ 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 ++; } @@ -1369,6 +1420,10 @@ get_addr_and_mask(const char *value, /* I - String from config file */ } } } +#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);