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