Skip to content

Commit

Permalink
Merge pull request #135 from peda1337/readnetwork
Browse files Browse the repository at this point in the history
Read Network
  • Loading branch information
MartinMelikMerkumians authored Feb 6, 2018
2 parents 5128d35 + bc08f0d commit e64e11a
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 59 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ Compile for Windows XP/7/8:
2. Open Visual Studio solution in bin/win32
3. For invoking opener type in command line:

OpENer ipaddress subnetmask gateway domainname hostaddress macaddress
OpENer interface_index

e.g. OpENer 192.168.0.2 255.255.255.0 192.168.0.1 test.com testdevice 00 15 C5 BF D0 87
e.g. OpENer 3

Directory structure:
--------------------
Expand Down
2 changes: 1 addition & 1 deletion source/src/ports/WIN32/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ add_library( ${PLATFORMLIBNAME} ${PLATFORM_SPEC_SRC})

add_executable(OpENer main.c)

target_link_libraries( OpENer PLATFORM_GENERIC ${PLATFORMLIBNAME} CIP SAMPLE_APP ENET_ENCAP ws2_32 ${OpENer_CIP_OBJECTS} )
target_link_libraries( OpENer PLATFORM_GENERIC ${PLATFORMLIBNAME} CIP Utils SAMPLE_APP ENET_ENCAP ws2_32 ${OpENer_CIP_OBJECTS} )
24 changes: 9 additions & 15 deletions source/src/ports/WIN32/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,24 @@ int g_end_stack = 0;
/******************************************************************************/
int main(int argc,
char *arg[]) {
EipUint8 acMyMACAddress[6];
EipUint16 nUniqueConnectionID;

if (argc != 12) {
if (argc != 2) {
printf("Wrong number of command line parameters!\n");
printf("The correct command line parameters are:\n");
printf(
"./OpENer ipaddress subnetmask gateway domainname hostaddress macaddress\n");
"./OpENer index\n");
printf(
" e.g. ./OpENer 192.168.0.2 255.255.255.0 192.168.0.1 test.com testdevice 00 15 C5 BF D0 87\n");
" e.g. ./OpENer index\n");
exit(0);
} else {
DoublyLinkedListInitialize(&connection_list,
CipConnectionObjectListArrayAllocator,
CipConnectionObjectListArrayFree);
/* fetch Internet address info from the platform */
ConfigureNetworkInterface(arg[1], arg[2], arg[3]);
ConfigureDomainName(arg[4]);
ConfigureHostName(arg[5]);

acMyMACAddress[0] = (EipUint8) strtoul(arg[6], NULL, 16);
acMyMACAddress[1] = (EipUint8) strtoul(arg[7], NULL, 16);
acMyMACAddress[2] = (EipUint8) strtoul(arg[8], NULL, 16);
acMyMACAddress[3] = (EipUint8) strtoul(arg[9], NULL, 16);
acMyMACAddress[4] = (EipUint8) strtoul(arg[10], NULL, 16);
acMyMACAddress[5] = (EipUint8) strtoul(arg[11], NULL, 16);
ConfigureMacAddress(acMyMACAddress);
ConfigureDomainName(atoi(arg[1]));
ConfigureHostName(atoi(arg[1]));
ConfigureIpMacAddress(atoi(arg[1]));
}

/*for a real device the serial number should be unique per device */
Expand Down
240 changes: 202 additions & 38 deletions source/src/ports/WIN32/networkconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,69 +3,233 @@
* All rights reserved.
*
******************************************************************************/

#define WIN32_LEAN_AND_MEAN
#include "ciptcpipinterface.h"
#include "networkconfig.h"
#include "cipcommon.h"
#include "ciperror.h"
#include "opener_api.h"
#include "trace.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#include <iphlpapi.h>
#include <Ws2tcpip.h>

EipStatus ConfigureNetworkInterface(const char *ip_address,
const char *subnet_mask,
const char *gateway) {
#define WORKING_BUFFER_SIZE 15000
#define MAX_TRIES 3

interface_configuration_.ip_address = inet_addr(ip_address);
interface_configuration_.network_mask = inet_addr(subnet_mask);
interface_configuration_.gateway = inet_addr(gateway);
#pragma comment(lib, "IPHLPAPI.lib")
#pragma comment(lib, "Ws2_32.lib")

/* calculate the CIP multicast address. The multicast address is calculated, not input*/
EipUint32 host_id = ntohl(interface_configuration_.ip_address)
& ~ntohl(interface_configuration_.network_mask); /* see CIP spec 3-5.3 for multicast address algorithm*/
host_id -= 1;
host_id &= 0x3ff;

g_multicast_configuration.starting_multicast_address = htonl(
ntohl( inet_addr("239.192.1.0") ) + (host_id << 5) );
void ConfigureIpMacAddress(const CipUint interface_index) {

PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
CipDword dwRetVal = 0;

CipUdint ulOutBufLen = sizeof(IP_ADAPTER_INFO);
pAdapterInfo = (IP_ADAPTER_INFO *)CipCalloc(1,sizeof(IP_ADAPTER_INFO));
if (pAdapterInfo == NULL) {
printf("Error allocating memory needed to call GetAdaptersinfo\n");
return 1;
}
// Make an initial call to GetAdaptersInfo to get
// the necessary size into the ulOutBufLen variable
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
CipFree(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *)CipCalloc(ulOutBufLen,sizeof(CipUdint));
if (pAdapterInfo == NULL) {
printf("Error allocating memory needed to call GetAdaptersinfo\n");
return 1;
}
}

return kEipStatusOk;
}

void ConfigureMacAddress(const EipUint8 *const mac_address) {
memcpy( &g_ethernet_link.physical_address, mac_address,
sizeof(g_ethernet_link.physical_address) );
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
pAdapter = pAdapterInfo;
while (pAdapter) {
if (pAdapter->Index == interface_index) {
for (int i = 0; i < 6; i++) {
memcpy(&g_ethernet_link.physical_address, pAdapter->Address,
6*sizeof(CipUsint));
}

interface_configuration_.ip_address = inet_addr(pAdapter->IpAddressList.IpAddress.String);
interface_configuration_.network_mask = inet_addr(pAdapter->IpAddressList.IpMask.String);
interface_configuration_.gateway = inet_addr(pAdapter->GatewayList.IpAddress.String);

CipUdint host_id = ntohl(interface_configuration_.ip_address)
& ~ntohl(interface_configuration_.network_mask); /* see CIP spec 3-5.3 for multicast address algorithm*/
host_id -= 1;
host_id &= 0x3ff;

g_multicast_configuration.starting_multicast_address = htonl(
ntohl(inet_addr("239.192.1.0")) + (host_id << 5));
}
pAdapter = pAdapter->Next;
}
}
else {
printf("GetAdaptersInfo failed with error: %d\n", dwRetVal);

}
CipFree(pAdapterInfo);
CipFree(pAdapter);
}

void ConfigureDomainName(const char *domain_name) {
if (NULL != interface_configuration_.domain_name.string) {
/* if the string is already set to a value we have to free the resources
* before we can set the new value in order to avoid memory leaks.
*/
CipFree(interface_configuration_.domain_name.string);
}
interface_configuration_.domain_name.length = strlen(domain_name);
if (interface_configuration_.domain_name.length) {
interface_configuration_.domain_name.string = (EipByte *) CipCalloc(
interface_configuration_.domain_name.length + 1, sizeof(EipInt8) );
strcpy(interface_configuration_.domain_name.string, domain_name);
} else {
interface_configuration_.domain_name.string = NULL;
}
void ConfigureDomainName(const CipUint interface_index) {

CipDword dwSize = 0;
int i = 0;
// Set the flags to pass to GetAdaptersAddresses
CipUdint flags = GAA_FLAG_INCLUDE_PREFIX;
CipDword dwRetVal = 0;
// default to unspecified address family (both)
CipUdint family = AF_UNSPEC;

LPVOID lpMsgBuf = NULL;

PIP_ADAPTER_ADDRESSES pAddresses = NULL;
PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
CipUdint outBufLen = 0;
CipUdint tries = 0;

family = AF_INET;
// Allocate a 15 KB buffer to start with.
outBufLen = WORKING_BUFFER_SIZE;

do {

pAddresses = (IP_ADAPTER_ADDRESSES *)CipCalloc(1,outBufLen);
if (pAddresses == NULL) {
printf
("Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n");
exit(1);
}

dwRetVal =
GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);

if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
CipFree(pAddresses);
pAddresses = NULL;
}
else {
break;
}

tries++;

} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (tries < MAX_TRIES));

if (dwRetVal == NO_ERROR) {
// If successful, output some information from the data we received
pCurrAddresses = pAddresses;
while (pCurrAddresses) {
if (interface_index == pCurrAddresses->IfIndex) {
pDnServer = pCurrAddresses->FirstDnsServerAddress;
if (pDnServer) {
for (i = 0; pDnServer != NULL; i++)
pDnServer = pDnServer->Next;
}

char pStringBuf[INET_ADDRSTRLEN];
if (i != 0) {

if (NULL != interface_configuration_.domain_name.string) {
/* if the string is already set to a value we have to free the resources
* before we can set the new value in order to avoid memory leaks.
*/
CipFree(interface_configuration_.domain_name.string);
}
interface_configuration_.domain_name.length = strlen(pCurrAddresses->DnsSuffix);
if (interface_configuration_.domain_name.length) {
interface_configuration_.domain_name.string = (CipByte *)CipCalloc(
interface_configuration_.domain_name.length + 1, sizeof(CipUsint));
strcpy(interface_configuration_.domain_name.string, pCurrAddresses->DnsSuffix);
}
else {
interface_configuration_.domain_name.string = NULL;
}

InetNtop(AF_INET, pCurrAddresses->FirstDnsServerAddress->Address.lpSockaddr->sa_data + 2, interface_configuration_.name_server, sizeof(interface_configuration_.name_server));
InetNtop(AF_INET, pCurrAddresses->FirstDnsServerAddress->Next->Address.lpSockaddr->sa_data + 2, interface_configuration_.name_server_2, sizeof(interface_configuration_.name_server_2));
}
else interface_configuration_.domain_name.length = 0;

}
pCurrAddresses = pCurrAddresses->Next;
}
}
else {
OPENER_TRACE_INFO("Call to GetAdaptersAddresses failed with error: %d\n",
dwRetVal);
if (dwRetVal == ERROR_NO_DATA)
OPENER_TRACE_INFO("\tNo addresses were found for the requested parameters\n");
else {

if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
// Default language
(LPTSTR)& lpMsgBuf, 0, NULL)) {
OPENER_TRACE_INFO("\tError: %s", lpMsgBuf);
CipFree(lpMsgBuf);
if (pAddresses)
CipFree(pAddresses);
exit(1);
}
}
}

if (pAddresses) {
CipFree(pAddresses);
}


}

void ConfigureHostName(const char *const RESTRICT hostname) {
if (NULL != hostname_.string) {
void ConfigureHostName(const CipUint interface_index) {
CipWord wVersionRequested;
WSADATA wsaData;
int err;

/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
wVersionRequested = MAKEWORD(2, 2);

err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
printf("WSAStartup failed with error: %d\n", err);
return 1;
}

char hostname[256] = "";
int status = 0;
status = gethostname(hostname, sizeof(hostname));

WSACleanup();




if (NULL != hostname_.string) {
/* if the string is already set to a value we have to free the resources
* before we can set the new value in order to avoid memory leaks.
*/
CipFree(hostname_.string);
}
hostname_.length = strlen(hostname);
if (hostname_.length) {
hostname_.string = (EipByte *) CipCalloc( hostname_.length + 1,
sizeof(EipByte) );
hostname_.string = (CipByte *) CipCalloc( hostname_.length + 1,
sizeof(CipByte) );
strcpy(hostname_.string, hostname);
} else {
hostname_.string = NULL;
Expand Down
4 changes: 2 additions & 2 deletions source/src/ports/WIN32/networkhandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ int SetSocketToNonBlocking(int socket_handle) {
return ioctlsocket(socket_handle, FIONBIO, &iMode);
}

void SetQosOnSocket(int socket,
int SetQosOnSocket(int socket,
CipUsint qos_value) {
CipUsint set_tos = qos_value;
setsockopt(socket, IPPROTO_IP, IP_TOS, &set_tos, sizeof(set_tos) );
return setsockopt(socket, IPPROTO_IP, IP_TOS, &set_tos, sizeof(set_tos) );
}
2 changes: 1 addition & 1 deletion source/src/ports/WIN32/networkhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ MicroSeconds GetMicroSeconds(void);
*/
MilliSeconds GetMilliSeconds(void);

void SetQosOnSocket(int socket,
int SetQosOnSocket(int socket,
CipUsint qos_value);

#endif /*NETWORKHANDLER_H_*/

0 comments on commit e64e11a

Please sign in to comment.