*/
#include <string.h> // memcmp
-#include <unistd.h> // pipe2
-#include <fcntl.h> // pipe2-O_NONBLOCK fcntl
+
+#ifdef WIN32
+ #include <WS2tcpip.h>
+ #include <iphlpapi.h>
+#else
+ #include <unistd.h> // pipe2
+ #include <fcntl.h> // pipe2-O_NONBLOCK fcntl
+ #include <sys/socket.h> // socket connect getaddrinfo
+ #include <netdb.h> // getaddrinfo
+ #include <sys/select.h> // select
+ #include <linux/if_packet.h> // for getMAC
+ #include <net/ethernet.h> // for getMAC
+ #include <ifaddrs.h> // getifaddrs
+#endif
+
#include <sys/types.h> // socket connect getaddrinfo
-#include <sys/socket.h> // socket connect getaddrinfo
#include <string.h> // memset
-#include <netdb.h> // getaddrinfo
-#include <sys/select.h> // select
#include <errno.h> // errno var
-#include <ifaddrs.h> // getifaddrs
-#include <linux/if_packet.h> // for getMAC
-#include <net/ethernet.h> // for getMAC
+#include "defines.h"
#include "log.h"
#include "tcp.h"
{
shutdown();
+#ifdef WIN32
+ CLOSESOCKET(abortSocket);
+#else
if (abortPipe[0] != -1)
{
close(abortPipe[0]);
abortPipe[0] = -1;
abortPipe[1] = -1;
}
+#endif
}
bool TCP::init()
{
logger = Log::getInstance();
+ #ifdef WIN32
+ abortSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (abortSocket == INVALID_SOCKET)
+ {
+ logger->log("TCP", Log::CRIT, "socket error");
+ return false;
+ }
+ #else
if (pipe2(abortPipe, O_NONBLOCK) == -1)
{
logger->log("TCP", Log::CRIT, "pipe2 error");
return false;
}
+ #endif
return true;
}
struct addrinfo* aip;
char portString[10];
- std::snprintf(portString, 10, "%u", port);
+ SNPRINTF(portString, 10, "%u", port);
int gaiResult = getaddrinfo(ip.c_str(), portString, &hints, &aip);
if ((gaiResult != 0) || !aip)
sockfd = socket(aip->ai_family, SOCK_STREAM, 0);
if (sockfd == -1) { logger->log("TCP", Log::CRIT, "socket error"); return false; }
+#ifdef WIN32
+ ULONG param = 1;
+ ioctlsocket(sockfd, FIONBIO, ¶m);
+#else
fcntl(sockfd, F_SETFL, O_NONBLOCK);
+#endif
errno = 0;
// There should only be one aip result..
if (errno != EINPROGRESS)
{
- close(sockfd);
+ CLOSESOCKET(sockfd);
sockfd = -1;
logger->log("TCP", Log::CRIT, "connect error");
return false;
fd_set writefds;
struct timeval tv;
FD_ZERO(&writefds);
- FD_SET(abortPipe[0], &writefds);
FD_SET(sockfd, &writefds);
+ int maxfd = sockfd;
+
+#ifdef WIN32
+ FD_SET(abortSocket, &writefds);
+#else
+ FD_SET(abortPipe[0], &writefds);
+ if (abortPipe[0] > maxfd) maxfd = abortPipe[0];
+#endif
tv.tv_sec = 5; // Allow 5s for a connect
tv.tv_usec = 0;
- int selectResult = select((sockfd > abortPipe[0] ? sockfd : abortPipe[0]) + 1, NULL, &writefds, NULL, &tv);
+ int selectResult = select(maxfd + 1, NULL, &writefds, NULL, &tv);
if ((selectResult == 1) || FD_ISSET(sockfd, &writefds))
{
}
else
{
- close(sockfd);
+ CLOSESOCKET(sockfd);
sockfd = -1;
logger->log("TCP", Log::CRIT, "connect/select error");
return false;
{
if (!connected) return;
connected = false;
- close(sockfd);
+ CLOSESOCKET(sockfd);
sockfd = -1;
}
void TCP::abortCall()
{
+#ifdef WIN32
+ CLOSESOCKET(abortSocket);
+#else
::write(abortPipe[1], "X", 1);
+#endif
}
bool TCP::write(void* src, ULONG numBytes)
if (!connected) return false;
std::lock_guard<std::mutex> lg(writeMutex);
- int result = send(sockfd, src, numBytes, 0); // FIXME does send return < numBytes? Might need loop
+ int result = send(sockfd, reinterpret_cast<char*>(src), numBytes, 0); // FIXME does send return < numBytes? Might need loop
if (result < 0) return false;
if (static_cast<ULONG>(result) != numBytes) return false;
ULONG totalReceived = 0;
int abortCount = 0;
- UCHAR* pointer = static_cast<UCHAR*>(dst);
+ char* pointer = static_cast<char*>(dst); // WIN32 requires char*
do
{
}
FD_ZERO(&readfds);
- FD_SET(abortPipe[0], &readfds);
FD_SET(sockfd, &readfds);
+ int maxfd = sockfd; // WIN32 ignores
+
+#ifdef WIN32
+ FD_SET(abortSocket, &readfds);
+#else
+ FD_SET(abortPipe[0], &readfds);
+ if (abortPipe[0] > maxfd) maxfd = abortPipe[0];
+#endif
tv.tv_sec = 2;
tv.tv_usec = 0;
- int selectResult = select((sockfd > abortPipe[0] ? sockfd : abortPipe[0]) + 1, &readfds, NULL, NULL, &tv);
+ int selectResult = select(maxfd + 1, &readfds, NULL, NULL, &tv);
if (selectResult == -1) { shutdown(); return false; }
if (selectResult == 0) return false;
- if (FD_ISSET(abortPipe[0], &readfds)) { logger->log("TCP", Log::DEBUG, "aborting..."); return false; }
+#ifdef WIN32
+ if (FD_ISSET(abortSocket, &readfds)) { logger->log("TCP", Log::DEBUG, "aborting..."); return false; }
+#else
+ if (FD_ISSET(abortPipe[0], &readfds)) { logger->log("TCP", Log::DEBUG, "aborting..."); return false; }
+#endif
+
int recvResult = recv(sockfd, pointer, numBytes - totalReceived, 0);
if (recvResult == -1) { shutdown(); return false; }
totalReceived += recvResult;
MACAddress TCP::getMAC()
{
+#ifndef WIN32
MACAddress macerror{ 00, 00, 00, 00, 00, 00 };
-
if (!connected) return macerror;
/*
freeifaddrs(ifAddrs);
return toReturn;
+
+#else // WIN32
+ PIP_ADAPTER_INFO daptinfo = NULL;
+ DWORD size = 0;
+ GetAdaptersInfo(daptinfo, &size);
+ daptinfo = (PIP_ADAPTER_INFO)new char[size + 1];
+ MACAddress macresult;
+ memcpy(¯esult, "ABCDEF", 6);//Dummy Address
+ sockaddr_in sock_address;
+ int sockname_len = sizeof(sock_address);
+ getsockname(sockfd, (sockaddr*)&sock_address, &sockname_len);
+ ULONG sockip = sock_address.sin_addr.s_addr;
+ if (GetAdaptersInfo(daptinfo, &size) == ERROR_SUCCESS)
+ {
+ PIP_ADAPTER_INFO daptinfo_it = daptinfo;
+ while (daptinfo_it != NULL)
+ {
+ ULONG ipaddress = inet_addr(daptinfo_it->IpAddressList.IpAddress.String);
+ if (ipaddress == sockip)
+ { //Is it our MAC?
+ memcpy(¯esult, daptinfo_it->Address, 6);
+ break;
+ }
+ daptinfo_it = daptinfo_it->Next;
+ if (daptinfo_it == daptinfo) break;
+ }
+ }
+ delete[] daptinfo;
+ return macresult;
+#endif
}