1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2014 projectchrono.org
5 // All rights reserved.
6 //
7 // Use of this source code is governed by a BSD-style license that can be found
8 // in the LICENSE file at the top level of the distribution and at
9 // http://projectchrono.org/license-chrono.txt.
10 //
11 // =============================================================================
12 // Authors: Alessandro Tasora
13 // =============================================================================
14 
15 #define _WINSOCK_DEPRECATED_NO_WARNINGS
16 
17 #include "chrono_cosimulation/ChHostInfo.h"
18 #include "chrono_cosimulation/ChExceptionSocket.h"
19 
20 namespace chrono {
21 namespace cosimul {
22 
ChHostInfo()23 ChHostInfo::ChHostInfo() {
24 #ifdef UNIX
25     openHostDb();
26 // winLog<<"UNIX version ChHostInfo() is called...\n";
27 #endif
28 
29 #ifdef WINDOWS_XP
30 
31     char sName[HOST_NAME_LENGTH + 1];
32     memset(sName, 0, sizeof(sName));
33     gethostname(sName, HOST_NAME_LENGTH);
34 
35     try {
36         hostPtr = gethostbyname(sName);
37         if (hostPtr == NULL) {
38             int errorCode;
39             std::string errorMsg = "";
40             detectErrorGethostbyname(&errorCode, errorMsg);
41             ChExceptionSocket* gethostbynameException = new ChExceptionSocket(errorCode, errorMsg);
42             throw gethostbynameException;
43         }
44     } catch (ChExceptionSocket* excp) {
45         excp->response();
46         exit(1);
47     }
48 
49 #endif
50 }
51 
ChHostInfo(const std::string & hostName,hostType type)52 ChHostInfo::ChHostInfo(const std::string& hostName, hostType type) {
53 #ifdef UNIX
54     searchHostDB = 0;
55 #endif
56 
57     try {
58         if (type == NAME) {
59             // Retrieve host by name
60             hostPtr = gethostbyname(hostName.c_str());
61 
62             if (hostPtr == NULL) {
63 #ifdef WINDOWS_XP
64                 int errorCode;
65                 std::string errorMsg = "";
66                 detectErrorGethostbyname(&errorCode, errorMsg);
67                 ChExceptionSocket* gethostbynameException = new ChExceptionSocket(errorCode, errorMsg);
68                 throw gethostbynameException;
69 #endif
70 
71 #ifdef UNIX
72                 ChExceptionSocket* gethostbynameException =
73                     new ChExceptionSocket(0, "unix: error getting host by name");
74                 throw gethostbynameException;
75 #endif
76             }
77         } else if (type == ADDRESS) {
78             // Retrieve host by address
79             unsigned long netAddr = inet_addr(hostName.c_str());
80             if (netAddr == -1) {
81                 ChExceptionSocket* inet_addrException = new ChExceptionSocket(0, "Error calling inet_addr()");
82                 throw inet_addrException;
83             }
84 
85             hostPtr = gethostbyaddr((char*)&netAddr, sizeof(netAddr), AF_INET);
86             if (hostPtr == NULL) {
87 #ifdef WINDOWS_XP
88                 int errorCode;
89                 std::string errorMsg = "";
90                 detectErrorGethostbyaddr(&errorCode, errorMsg);
91                 ChExceptionSocket* gethostbyaddrException = new ChExceptionSocket(errorCode, errorMsg);
92                 throw gethostbyaddrException;
93 #endif
94 
95 #ifdef UNIX
96                 ChExceptionSocket* gethostbynameException =
97                     new ChExceptionSocket(0, "unix: error getting host by name");
98                 throw gethostbynameException;
99 #endif
100             }
101         } else {
102             ChExceptionSocket* unknownTypeException =
103                 new ChExceptionSocket(0, "unknown host type: host name/address has to be given ");
104             throw unknownTypeException;
105         }
106     } catch (ChExceptionSocket* excp) {
107         excp->response();
108         exit(1);
109     }
110 }
111 
getHostIPAddress()112 char* ChHostInfo::getHostIPAddress() {
113     struct in_addr* addr_ptr;
114     // the first address in the list of host addresses
115     addr_ptr = (struct in_addr*)*hostPtr->h_addr_list;
116     // changed the address format to the Internet address in standard dot notation
117     return inet_ntoa(*addr_ptr);
118 }
119 
120 #ifdef WINDOWS_XP
detectErrorGethostbyname(int * errCode,std::string & errorMsg)121 void ChHostInfo::detectErrorGethostbyname(int* errCode, std::string& errorMsg) {
122     *errCode = WSAGetLastError();
123 
124     if (*errCode == WSANOTINITIALISED)
125         errorMsg.append("need to call WSAStartup to initialize socket system on Window system.");
126     else if (*errCode == WSAENETDOWN)
127         errorMsg.append("The network subsystem has failed.");
128     else if (*errCode == WSAHOST_NOT_FOUND)
129         errorMsg.append("Authoritative Answer Host not found.");
130     else if (*errCode == WSATRY_AGAIN)
131         errorMsg.append("Non-Authoritative Host not found, or server failure.");
132     else if (*errCode == WSANO_RECOVERY)
133         errorMsg.append("Nonrecoverable error occurred.");
134     else if (*errCode == WSANO_DATA)
135         errorMsg.append("Valid name, no data record of requested type.");
136     else if (*errCode == WSAEINPROGRESS)
137         errorMsg.append(
138             "A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a "
139             "callback function.");
140     else if (*errCode == WSAEFAULT)
141         errorMsg.append("The name parameter is not a valid part of the user address space.");
142     else if (*errCode == WSAEINTR)
143         errorMsg.append("A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.");
144 }
145 #endif
146 
147 #ifdef WINDOWS_XP
detectErrorGethostbyaddr(int * errCode,std::string & errorMsg)148 void ChHostInfo::detectErrorGethostbyaddr(int* errCode, std::string& errorMsg) {
149     *errCode = WSAGetLastError();
150 
151     if (*errCode == WSANOTINITIALISED)
152         errorMsg.append("A successful WSAStartup must occur before using this function.");
153     if (*errCode == WSAENETDOWN)
154         errorMsg.append("The network subsystem has failed.");
155     if (*errCode == WSAHOST_NOT_FOUND)
156         errorMsg.append("Authoritative Answer Host not found.");
157     if (*errCode == WSATRY_AGAIN)
158         errorMsg.append("Non-Authoritative Host not found, or server failed.");
159     if (*errCode == WSANO_RECOVERY)
160         errorMsg.append("Nonrecoverable error occurred.");
161     if (*errCode == WSANO_DATA)
162         errorMsg.append("Valid name, no data record of requested type.");
163     if (*errCode == WSAEINPROGRESS)
164         errorMsg.append(
165             "A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a "
166             "callback function.");
167     if (*errCode == WSAEAFNOSUPPORT)
168         errorMsg.append("The type specified is not supported by the Windows Sockets implementation.");
169     if (*errCode == WSAEFAULT)
170         errorMsg.append(
171             "The addr parameter is not a valid part of the user address space, or the len parameter is too small.");
172     if (*errCode == WSAEINTR)
173         errorMsg.append("A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.");
174 }
175 #endif
176 
177 #ifdef UNIX
getNextHost()178 char ChHostInfo::getNextHost() {
179     // winLog<<"UNIX getNextHost() is called...\n";
180     // Get the next host from the database
181     if (searchHostDB == 1) {
182         if ((hostPtr = gethostent()) == NULL)
183             return 0;
184         else
185             return 1;
186     }
187     return 0;
188 }
189 #endif
190 
191 }  // end namespace cosimul
192 }  // end namespace chrono
193