/*====================================================================* * * size_t ipv6spec (char const * string, byte memory []); * * memory.h * * encode a 16-byte memory region with the binary equivalent of an * ipv6 address string; ipv6 addresses are defined as 8 16-bit hex * numbers separated with colons; two consecutive colons represent * one or more 0000 fields; * * Motley Tools by Charles Maier <cmaier@cmassoc.net>; * Copyright (c) 2001-2006 by Charles Maier Associates; * Licensed under the Internet Software Consortium License; * *--------------------------------------------------------------------*/ #ifndef IPV6SPEC_SOURCE #define IPV6SPEC_SOURCE #include <memory.h> #include <ctype.h> #include <errno.h> #include "../tools/memory.h" #include "../tools/number.h" #include "../tools/error.h" size_t ipv6spec (char const * string, void * memory) { char const * number = string; byte * origin = (byte *)(memory); byte * offset = (byte *)(memory); byte * extent = offset + IPv6_LEN; byte * marker = offset + IPv6_LEN; unsigned radix = RADIX_HEX; unsigned digit = 0; while ((*number) && (offset < extent)) { uint32_t value = 0; if (offset > origin) { if (*number == HEX_EXTENDER) { number++; } if (*number == HEX_EXTENDER) { marker = offset; } } while ((digit = todigit (*number)) < radix) { value *= radix; value += digit; if (value >> 16) { error (1, ERANGE, "IPv6 '%s' field %d exceeds 16 bits", string, 1 + ((unsigned)(offset - origin) >> 1)); } number++; } *offset++ = (byte)(value >> 8); *offset++ = (byte)(value >> 0); } #if defined (WIN32) while (isspace (*number)) { number++; } #endif if (*number) { error (1, EINVAL, "IPv6 '%s' includes trash '%s'", string, number); } if (offset < extent) { while (offset > marker) { *--extent = *--offset; } while (extent > offset) { *--extent = 0; } } if (offset < marker) { error (1, EINVAL, "IPv6 '%s' has only %d fields", string, (unsigned)(offset - origin) >> 1); } return (offset - origin); } /*====================================================================* * demo/test program; *--------------------------------------------------------------------*/ #if 0 #include <stdio.h> char const * program_name = "ipv6spec"; int main (int argc, char * argv []) { byte memory [16]; char string [48]; while (*++argv) { ipv6spec (* argv, memory); hexdecode (memory, sizeof (memory), string, sizeof (string)); printf ("%s %s\n", string, * argv); } return (0); } #endif /*====================================================================* * *--------------------------------------------------------------------*/ #endif