(file) Return to addr.c CVS log (file) (dir) Up to [OMI] / omi / sock

  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

ViewCVS 0.9.2