1 /*	$NetBSD: inet_pton.c,v 1.1.1.1 2011/04/13 18:15:41 elric Exp $	*/
2 
3 /*
4  * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
5  * (Royal Institute of Technology, Stockholm, Sweden).
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the Institute nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #include <config.h>
37 
38 #include <krb5/roken.h>
39 
40 #ifdef HAVE_WINSOCK
41 
42 ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
43 inet_pton(int af, const char *csrc, void *dst)
44 {
45     char * src;
46 
47     if (csrc == NULL || (src = strdup(csrc)) == NULL) {
48 	_set_errno( ENOMEM );
49 	return 0;
50     }
51 
52     switch (af) {
53     case AF_INET:
54 	{
55 	    struct sockaddr_in  si4;
56 	    INT r;
57 	    INT s = sizeof(si4);
58 
59 	    si4.sin_family = AF_INET;
60 	    r = WSAStringToAddress(src, AF_INET, NULL, (LPSOCKADDR) &si4, &s);
61 	    free(src);
62 	    src = NULL;
63 
64 	    if (r == 0) {
65 		memcpy(dst, &si4.sin_addr, sizeof(si4.sin_addr));
66 		return 1;
67 	    }
68 	}
69 	break;
70 
71     case AF_INET6:
72 	{
73 	    struct sockaddr_in6 si6;
74 	    INT r;
75 	    INT s = sizeof(si6);
76 
77 	    si6.sin6_family = AF_INET6;
78 	    r = WSAStringToAddress(src, AF_INET6, NULL, (LPSOCKADDR) &si6, &s);
79 	    free(src);
80 	    src = NULL;
81 
82 	    if (r == 0) {
83 		memcpy(dst, &si6.sin6_addr, sizeof(si6.sin6_addr));
84 		return 1;
85 	    }
86 	}
87 	break;
88 
89     default:
90 	_set_errno( EAFNOSUPPORT );
91 	return -1;
92     }
93 
94     /* the call failed */
95     {
96 	int le = WSAGetLastError();
97 
98 	if (le == WSAEINVAL)
99 	    return 0;
100 
101 	_set_errno(le);
102 	return -1;
103     }
104 }
105 
106 #else  /* !HAVE_WINSOCK */
107 
108 ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
109 inet_pton(int af, const char *src, void *dst)
110 {
111     if (af != AF_INET) {
112 	errno = EAFNOSUPPORT;
113 	return -1;
114     }
115     return inet_aton (src, dst);
116 }
117 
118 #endif
119