1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #include "addr.h"
26 #include <ctype.h>
27 #include <string.h>
28
|
29 krisbash 1.3 // #define ENABLE_TRACING 1
30
|
31 mike 1.1 /* Include network headers */
|
32 krisbash 1.3 #if defined CONFIG_OS_WINDOWS
33
|
34 mike 1.1 # include <winsock2.h>
|
35 krisbash 1.3 typedef unsigned long InAddr;
36
37 #else
38
|
39 mike 1.1 # include <unistd.h>
40 # include <errno.h>
41 # include <sys/socket.h>
42 # include <netinet/tcp.h>
43 # include <netinet/in.h>
44 # include <sys/time.h>
45 # include <sys/types.h>
46 # include <netdb.h>
47 # include <fcntl.h>
48 # include <arpa/inet.h>
|
49 krisbash 1.3 typedef in_addr_t InAddr;
|
50 mike 1.1
51 #endif
52
53 MI_Result Addr_Init(
|
54 krisbash 1.3 Addr* self,
|
55 mike 1.1 const char* host,
|
56 krisbash 1.3 unsigned short port,
57 MI_Boolean useSecondaryAddr)
|
58 mike 1.1 {
|
59 krisbash 1.3 #if defined CONFIG_OS_WINDOWS
60
61 /* disabling IPv6 OACR warnings - D3M bug 52 */
62
63 # ifdef _PREFAST_
64 # pragma prefast (push)
65 # pragma prefast (disable: 24001)
66 # pragma prefast (disable: 24002)
67 # pragma prefast (disable: 38026)
68 # endif
69 struct sockaddr_in* sockaddr = (struct sockaddr_in*)self;
70
71 /* Handle host name */
72 const struct hostent* p = gethostbyname((char*)host);
73 if (p == NULL)
74 return MI_RESULT_FAILED;
75
76 /* no support for IPv6 on Windows */
77 if (useSecondaryAddr)
78 return MI_RESULT_FAILED;
|
79 mike 1.1
80 /* Clear address */
|
81 krisbash 1.3 memset(self, 0, sizeof (Addr));
82
83 /* set up values */
84 sockaddr->sin_family = p->h_addrtype;
85 self->is_ipv6 = MI_FALSE;
86 self->sock_addr_size = sizeof (struct sockaddr_in);
87 memcpy(&sockaddr->sin_addr, p->h_addr, p->h_length);
88
89 /* Set the port */
90 sockaddr->sin_port = htons(port);
91 self->port_high_endian = htons(port);
92 return MI_RESULT_OK;
|
93 mike 1.1
|
94 krisbash 1.3 # ifdef _PREFAST_
95 # pragma prefast (pop)
96 # endif
97
98 #else /* defined CONFIG_OS_WINDOWS */
99
100 struct addrinfo hints;
101 struct addrinfo *addr_info, *rp;
102 int error_no;
103
104 /* set hints and get the primary address */
105 memset(&hints, 0, sizeof (struct addrinfo));
106 hints.ai_socktype = SOCK_STREAM;
107 hints.ai_family = AF_UNSPEC; /* AF_UNSPEC means use preferred protocol */
108 error_no = getaddrinfo(host, NULL, &hints, &addr_info);
109 if (error_no != 0)
110 return MI_RESULT_FAILED;
111
112 rp = addr_info;
113 if (useSecondaryAddr && NULL != addr_info->ai_next)
114 {
115 krisbash 1.3 // Advance to the next entry in the chain
116 rp = rp->ai_next;
117 }
118 else if (useSecondaryAddr)
|
119 mike 1.1 {
|
120 krisbash 1.3 // No secondary address exists.
121 return MI_RESULT_FAILED;
122 }
|
123 mike 1.1
|
124 krisbash 1.3 if (rp->ai_family == AF_INET6)
125 {
126 struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)(rp->ai_addr);
127 // struct sockaddr_in6* addr6 = (struct sockaddr_in6*)(addr_info->ai_addr->sa_data - sizeof (unsigned short));
128 addr6->sin6_port = htons(port);
|
129 mike 1.1 }
130 else
131 {
|
132 krisbash 1.3 struct sockaddr_in * addr4 = (struct sockaddr_in *)(rp->ai_addr);
133 // struct sockaddr_in* addr4 = (struct sockaddr_in*)(addr_info->ai_addr->sa_data - sizeof (unsigned short));
134 addr4->sin_port = htons(port);
135 }
136
137 memset(self->u.padding, 0, sizeof self->u.padding);
138 memcpy(&self->u.sock_addr, rp->ai_addr, (size_t)rp->ai_addrlen);
|
139 mike 1.1
|
140 krisbash 1.3 /* Set the duplicate copies of family, port and socket type */
141 self->sock_addr_size = rp->ai_addrlen;
142 self->port_high_endian = htons(port);
143 self->is_ipv6 = (rp->ai_family == AF_INET6);
|
144 mike 1.1
|
145 krisbash 1.3 #if defined ENABLE_TRACING
146 if (rp->ai_family == AF_INET6)
147 {
148 struct sockaddr_in6* addr6 = (struct sockaddr_in6*)&self->u.sock_addr;
149 fprintf(stderr, "Addr_Init - IPv6 address: %X:%X:%X:%X:%X:%X:%X:%X, port: %u\n",
150 (unsigned int)ntohs(*(unsigned short*)&addr6->sin6_addr),
151 (unsigned int)ntohs(*((unsigned short*)&addr6->sin6_addr + 1)),
152 (unsigned int)ntohs(*((unsigned short*)&addr6->sin6_addr + 2)),
153 (unsigned int)ntohs(*((unsigned short*)&addr6->sin6_addr + 3)),
154 (unsigned int)ntohs(*((unsigned short*)&addr6->sin6_addr + 4)),
155 (unsigned int)ntohs(*((unsigned short*)&addr6->sin6_addr + 5)),
156 (unsigned int)ntohs(*((unsigned short*)&addr6->sin6_addr + 6)),
157 (unsigned int)ntohs(*((unsigned short*)&addr6->sin6_addr + 7)),
158 (unsigned int)ntohs(addr6->sin6_port));
|
159 mike 1.1 }
|
160 krisbash 1.3 else
161 {
162 struct sockaddr_in* addr4 = (struct sockaddr_in*)&self->u.sock_addr;
|
163 mike 1.1
|
164 krisbash 1.3 fprintf(stderr, "Addr_Init - IPv4 address: %u.%u.%u.%u, port: %u\n",
165 (unsigned int)*((unsigned char*)&addr4->sin_addr.s_addr + 0),
166 (unsigned int)*((unsigned char*)&addr4->sin_addr.s_addr + 1),
167 (unsigned int)*((unsigned char*)&addr4->sin_addr.s_addr + 2),
168 (unsigned int)*((unsigned char*)&addr4->sin_addr.s_addr + 3),
169 (unsigned int)ntohs(addr4->sin_port));
170 }
171 #endif /* defined(ENABLE_TRACING) */
172 freeaddrinfo(addr_info);
|
173 mike 1.1 return MI_RESULT_OK;
|
174 krisbash 1.3
175 #endif /* defined CONFIG_OS_WINDOWS ... else */
|
176 mike 1.1 }
177
178 void Addr_InitAny(
|
179 krisbash 1.3 Addr* self,
|
180 mike 1.1 unsigned short port)
181 {
|
182 krisbash 1.3 #ifdef _PREFAST_
183 # pragma prefast (push)
184 # pragma prefast (disable: 24002)
185 #endif
186 struct sockaddr_in* addr4;
187 MI_Uint32 v4addr;
188
189 memset((char*)self, 0, sizeof (Addr));
|
190 mike 1.1
|
191 krisbash 1.3 /* set the fields in the header */
192 self->sock_addr_size = (MI_Uint16)sizeof (struct sockaddr_in);
193 self->port_high_endian = htons(port);
194 self->is_ipv6 = MI_FALSE;
195
196 /* set the fields in the bind address structure */
197 addr4 = (struct sockaddr_in*)&self->u.sock_addr;
198 addr4->sin_family = AF_INET;
199 addr4->sin_port = htons(port);
200 v4addr = htonl(INADDR_ANY);
201 memcpy(&addr4->sin_addr.s_addr, &v4addr, sizeof (MI_Uint32));
|
202 mike 1.1 }
|
203 krisbash 1.3
204 #ifdef _PREFAST_
205 #pragma prefast (pop)
206 #endif
|