OpENer - Open Source EtherNet/IP(TM) I/O Target Stack  2.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
networkconfig.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (c) 2009, Rockwell Automation, Inc.
3  * All rights reserved.
4  *
5  ******************************************************************************/
6 #define WIN32_LEAN_AND_MEAN
7 #include "ciptcpipinterface.h"
8 #include "networkconfig.h"
9 #include "cipcommon.h"
10 #include "ciperror.h"
11 #include "opener_api.h"
12 #include "trace.h"
13 #include <string.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <winsock2.h>
18 #include <windows.h>
19 #include <iphlpapi.h>
20 #include <Ws2tcpip.h>
21 
22 #define WORKING_BUFFER_SIZE 15000
23 #define MAX_TRIES 3
24 
25 #pragma comment(lib, "IPHLPAPI.lib")
26 #pragma comment(lib, "Ws2_32.lib")
27 
28 
29 void ConfigureIpMacAddress(const CipUint interface_index) {
30 
31  PIP_ADAPTER_INFO pAdapterInfo;
32  PIP_ADAPTER_INFO pAdapter = NULL;
33  CipDword dwRetVal = 0;
34 
35  CipUdint ulOutBufLen = sizeof(IP_ADAPTER_INFO);
36  pAdapterInfo = (IP_ADAPTER_INFO *)CipCalloc(1,sizeof(IP_ADAPTER_INFO) );
37  if (pAdapterInfo == NULL) {
38  printf("Error allocating memory needed to call GetAdaptersinfo\n");
39  return 1;
40  }
41  // Make an initial call to GetAdaptersInfo to get
42  // the necessary size into the ulOutBufLen variable
43  if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
44  CipFree(pAdapterInfo);
45  pAdapterInfo = (IP_ADAPTER_INFO *)CipCalloc(ulOutBufLen,sizeof(CipUdint) );
46  if (pAdapterInfo == NULL) {
47  printf("Error allocating memory needed to call GetAdaptersinfo\n");
48  return 1;
49  }
50  }
51 
52 
53  if ( (dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) ) == NO_ERROR ) {
54  pAdapter = pAdapterInfo;
55  while (pAdapter) {
56  if (pAdapter->Index == interface_index) {
57  for (int i = 0; i < 6; i++) {
58  memcpy(&g_ethernet_link.physical_address, pAdapter->Address,
59  6 * sizeof(CipUsint) );
60  }
61 
63  pAdapter->IpAddressList.IpAddress.String);
65  pAdapter->IpAddressList.IpMask.String);
67  pAdapter->GatewayList.IpAddress.String);
68 
70  & ~ntohl(interface_configuration_.network_mask); /* see CIP spec 3-5.3 for multicast address algorithm*/
71  host_id -= 1;
72  host_id &= 0x3ff;
73 
75  ntohl(inet_addr("239.192.1.0") ) + (host_id << 5) );
76  }
77  pAdapter = pAdapter->Next;
78  }
79  }
80  else {
81  printf("GetAdaptersInfo failed with error: %d\n", dwRetVal);
82 
83  }
84  CipFree(pAdapterInfo);
85  CipFree(pAdapter);
86 }
87 
88 void ConfigureDomainName(const CipUint interface_index) {
89 
90  CipDword dwSize = 0;
91  int i = 0;
92  // Set the flags to pass to GetAdaptersAddresses
93  CipUdint flags = GAA_FLAG_INCLUDE_PREFIX;
94  CipDword dwRetVal = 0;
95  // default to unspecified address family (both)
96  CipUdint family = AF_UNSPEC;
97 
98  LPVOID lpMsgBuf = NULL;
99 
100  PIP_ADAPTER_ADDRESSES pAddresses = NULL;
101  PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
102  IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
103  CipUdint outBufLen = 0;
104  CipUdint tries = 0;
105 
106  family = AF_INET;
107  // Allocate a 15 KB buffer to start with.
108  outBufLen = WORKING_BUFFER_SIZE;
109 
110  do {
111 
112  pAddresses = (IP_ADAPTER_ADDRESSES *)CipCalloc(1,outBufLen);
113  if (pAddresses == NULL) {
114  printf
115  ("Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n");
116  exit(1);
117  }
118 
119  dwRetVal =
120  GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);
121 
122  if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
123  CipFree(pAddresses);
124  pAddresses = NULL;
125  }
126  else {
127  break;
128  }
129 
130  tries++;
131 
132  } while ( (dwRetVal == ERROR_BUFFER_OVERFLOW) && (tries < MAX_TRIES) );
133 
134  if (dwRetVal == NO_ERROR) {
135  // If successful, output some information from the data we received
136  pCurrAddresses = pAddresses;
137  while (pCurrAddresses) {
138  if (interface_index == pCurrAddresses->IfIndex) {
139  pDnServer = pCurrAddresses->FirstDnsServerAddress;
140  if (pDnServer) {
141  for (i = 0; pDnServer != NULL; i++) {
142  pDnServer = pDnServer->Next;
143  }
144  }
145 
146  char pStringBuf[INET_ADDRSTRLEN];
147  if (i != 0) {
148 
150  /* if the string is already set to a value we have to free the resources
151  * before we can set the new value in order to avoid memory leaks.
152  */
154  }
156  pCurrAddresses->DnsSuffix);
160  sizeof(CipUsint) );
162  pCurrAddresses->DnsSuffix);
163  }
164  else {
166  }
167 
168  InetNtop(AF_INET,
169  pCurrAddresses->FirstDnsServerAddress->Address.lpSockaddr->sa_data + 2,
172  InetNtop(AF_INET,
173  pCurrAddresses->FirstDnsServerAddress->Next->Address.lpSockaddr->sa_data + 2,
176  }
178 
179  }
180  pCurrAddresses = pCurrAddresses->Next;
181  }
182  }
183  else {
184  OPENER_TRACE_INFO("Call to GetAdaptersAddresses failed with error: %d\n",
185  dwRetVal);
186  if (dwRetVal == ERROR_NO_DATA) {
188  "\tNo addresses were found for the requested parameters\n");
189  }
190  else {
191 
192  if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
193  FORMAT_MESSAGE_FROM_SYSTEM |
194  FORMAT_MESSAGE_IGNORE_INSERTS,
195  NULL, dwRetVal,
196  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
197  // Default language
198  (LPTSTR)&lpMsgBuf, 0, NULL) ) {
199  OPENER_TRACE_INFO("\tError: %s", lpMsgBuf);
200  CipFree(lpMsgBuf);
201  if (pAddresses) {
202  CipFree(pAddresses);
203  }
204  exit(1);
205  }
206  }
207  }
208 
209  if (pAddresses) {
210  CipFree(pAddresses);
211  }
212 
213 
214 }
215 
216 void ConfigureHostName(const CipUint interface_index) {
217  CipWord wVersionRequested;
218  WSADATA wsaData;
219  int err;
220 
221  /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
222  wVersionRequested = MAKEWORD(2, 2);
223 
224  err = WSAStartup(wVersionRequested, &wsaData);
225  if (err != 0) {
226  /* Tell the user that we could not find a usable */
227  /* Winsock DLL. */
228  printf("WSAStartup failed with error: %d\n", err);
229  return 1;
230  }
231 
232  char hostname[256] = "";
233  int status = 0;
234  status = gethostname(hostname, sizeof(hostname) );
235 
236  WSACleanup();
237 
238 
239 
240 
241  if (NULL != hostname_.string) {
242  /* if the string is already set to a value we have to free the resources
243  * before we can set the new value in order to avoid memory leaks.
244  */
246  }
247  hostname_.length = strlen(hostname);
248  if (hostname_.length) {
250  sizeof(CipByte) );
251  strcpy(hostname_.string, hostname);
252  } else {
253  hostname_.string = NULL;
254  }
255 }
#define WORKING_BUFFER_SIZE
Definition: networkconfig.c:22
Tracing infrastructure for OpENer.
EipUint8 physical_address[6]
MulticastAddressConfiguration g_multicast_configuration
#9 The multicast configuration for this device
void ConfigureIpMacAddress(const CipUint interface_index)
Definition: networkconfig.c:29
void * CipCalloc(size_t number_of_elements, size_t size_of_element)
Allocate memory for the CIP stack.
EipUint16 length
Definition: ciptypes.h:139
uint8_t CipByte
Definition: typedefs.h:43
#define OPENER_TRACE_INFO(...)
Definition: trace.h:89
void CipFree(void *data)
Free memory allocated by the OpENer.
EipByte * string
Definition: ciptypes.h:140
uint8_t CipUsint
Definition: typedefs.h:46
Public interface of the TCP/IP Interface Object.
CipTcpIpNetworkInterfaceConfiguration interface_configuration_
CipString hostname_
uint32_t CipUdint
Definition: typedefs.h:48
void ConfigureDomainName()
Configure the domain name of the device.
Definition: networkconfig.c:87
uint16_t CipUint
Definition: typedefs.h:47
#define MAX_TRIES
Definition: networkconfig.c:23
uint32_t CipDword
Definition: typedefs.h:45
uint16_t CipWord
Definition: typedefs.h:44
void ConfigureHostName(void)
Configure the host name of the device.