xref: /minix3/lib/libform/type_ipv6.c (revision a0e6850f820f09a03a1da1b4d78f9fafb3b9782f)
1 /*	$NetBSD: type_ipv6.c,v 1.10 2004/11/24 11:57:09 blymn 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.10 2004/11/24 11:57:09 blymn 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  */
53 static int
ipv6_check_field(FIELD * field,char * args)54 ipv6_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  */
102 static int
ipv6_check_char(int c,char * args)103 ipv6_check_char(/* ARGSUSED1 */ int c, char *args)
104 {
105 	return (isxdigit(c) || (c == '.') || (c == ':')) ? TRUE : FALSE;
106 }
107 
108 static 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 
121 FIELDTYPE *TYPE_IPV6 = &builtin_ipv6;
122 
123 
124