1 /* $NetBSD: type_ipv6.c,v 1.6 2001/06/13 10:45:59 wiz Exp $ */ 2 3 /*- 4 * Copyright (c) 1998-1999 Brett Lymn 5 * (blymn@baea.com.au, brett_lymn@yahoo.com.au) 6 * All rights reserved. 7 * 8 * This code has been donated to The NetBSD Foundation by the Author. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * Many thanks to Jun-ichiro itojun Hagino <itojun@netbsd.org> for providing 30 * the sample code for the check field function, this function is 99.999% 31 * his code. 32 * 33 */ 34 35 #include <sys/types.h> 36 #include <sys/socket.h> 37 #include <ctype.h> 38 #include <netdb.h> 39 #include <string.h> 40 #include "form.h" 41 #include "internals.h" 42 43 /* 44 * The IP v6 address type handling. 45 */ 46 47 /* 48 * Check the contents of the field buffer are a valid Ipv6 address only. 49 */ 50 static int 51 ipv6_check_field(FIELD *field, char *args) 52 { 53 char cleaned[NI_MAXHOST]; 54 struct addrinfo hints, *res; 55 #ifdef NI_WITHSCOPEID /* KAME extension */ 56 const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID; 57 #else 58 const int niflags = NI_NUMERICHOST; 59 #endif 60 61 if (args == NULL) 62 return FALSE; 63 64 memset(&hints, 0, sizeof(hints)); 65 hints.ai_family = AF_INET6; 66 hints.ai_socktype = SOCK_DGRAM; /* dummy */ 67 hints.ai_flags = AI_NUMERICHOST; 68 69 if (getaddrinfo(args, "0", &hints, &res) != 0) { 70 /* no it is not an IPv6 address */ 71 return FALSE; 72 } 73 74 if (res->ai_next) { 75 /* somehow the address resolved to multiple 76 * addresses - strange 77 */ 78 freeaddrinfo(res); 79 return FALSE; 80 } 81 82 if (getnameinfo(res->ai_addr, res->ai_addrlen, cleaned, 83 sizeof(cleaned), NULL, 0, niflags) != 0) { 84 freeaddrinfo(res); 85 return FALSE; 86 } 87 88 freeaddrinfo(res); 89 90 /* 91 * now we are sure host is an IPv6 address literal, and "cleaned" 92 * has the uniformly-formatted IPv6 address literal. Re-set the 93 * field buffer to be the reformatted IPv6 address 94 */ 95 set_field_buffer(field, 0, cleaned); 96 97 return TRUE; 98 } 99 100 /* 101 * Check the given character is numeric, return TRUE if it is. 102 */ 103 static int 104 ipv6_check_char(/* ARGSUSED1 */ int c, char *args) 105 { 106 return (isxdigit(c) || (c == '.') || (c == ':')) ? TRUE : FALSE; 107 } 108 109 static FIELDTYPE builtin_ipv6 = { 110 _TYPE_IS_BUILTIN, /* flags */ 111 0, /* refcount */ 112 NULL, /* link */ 113 NULL, /* make_args */ 114 NULL, /* copy_args */ 115 NULL, /* free_args */ 116 ipv6_check_field, /* field_check */ 117 ipv6_check_char, /* char_check */ 118 NULL, /* next_choice */ 119 NULL /* prev_choice */ 120 }; 121 122 FIELDTYPE *TYPE_IPV6 = &builtin_ipv6; 123 124 125