1/* $NetBSD: type_ipv6.c,v 1.9 2004/11/16 06:04:13 itojun 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/cdefs.h> 36__RCSID("$NetBSD: type_ipv6.c,v 1.9 2004/11/16 06:04:13 itojun Exp $"); 37 38#include <sys/types.h> 39#include <sys/socket.h> 40#include <ctype.h> 41#include <netdb.h> 42#include <string.h> 43#include "form.h" 44#include "internals.h" 45 46/* 47 * The IP v6 address type handling. 48 */ 49 50/* 51 * Check the contents of the field buffer are a valid Ipv6 address only. 52 */ 53static int 54ipv6_check_field(FIELD *field, char *args) 55{ 56 char cleaned[NI_MAXHOST]; 57 struct addrinfo hints, *res; 58 const int niflags = NI_NUMERICHOST; 59 60 if (args == NULL) 61 return FALSE; 62 63 memset(&hints, 0, sizeof(hints)); 64 hints.ai_family = AF_INET6; 65 hints.ai_socktype = SOCK_DGRAM; /* dummy */ 66 hints.ai_flags = AI_NUMERICHOST; 67 68 if (getaddrinfo(args, "0", &hints, &res) != 0) { 69 /* no it is not an IPv6 address */ 70 return FALSE; 71 } 72 73 if (res->ai_next) { 74 /* somehow the address resolved to multiple 75 * addresses - strange 76 */ 77 freeaddrinfo(res); 78 return FALSE; 79 } 80 81 if (getnameinfo(res->ai_addr, res->ai_addrlen, cleaned, 82 (socklen_t) sizeof(cleaned), NULL, 0, niflags) != 0) { 83 freeaddrinfo(res); 84 return FALSE; 85 } 86 87 freeaddrinfo(res); 88 89 /* 90 * now we are sure host is an IPv6 address literal, and "cleaned" 91 * has the uniformly-formatted IPv6 address literal. Re-set the 92 * field buffer to be the reformatted IPv6 address 93 */ 94 set_field_buffer(field, 0, cleaned); 95 96 return TRUE; 97} 98 99/* 100 * Check the given character is numeric, return TRUE if it is. 101 */ 102static int 103ipv6_check_char(/* ARGSUSED1 */ int c, char *args) 104{ 105 return (isxdigit(c) || (c == '.') || (c == ':')) ? TRUE : FALSE; 106} 107 108static FIELDTYPE builtin_ipv6 = { 109 _TYPE_IS_BUILTIN, /* flags */ 110 0, /* refcount */ 111 NULL, /* link */ 112 NULL, /* make_args */ 113 NULL, /* copy_args */ 114 NULL, /* free_args */ 115 ipv6_check_field, /* field_check */ 116 ipv6_check_char, /* char_check */ 117 NULL, /* next_choice */ 118 NULL /* prev_choice */ 119}; 120 121FIELDTYPE *TYPE_IPV6 = &builtin_ipv6; 122 123 124