+++ /dev/null
-/*
- Copyright 2004-2019 Chris Tallon
- Copyright 2003-2004 University Of Bradford
-
- This file is part of VOMP.
-
- VOMP is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- VOMP is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with VOMP; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*/
-
-#ifdef WIN32
-#include <WinSock2.h>
-#include <Iphlpapi.h>
-#else
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#endif
-
-#include "log.h"
-
-#include "tcpold.h"
-
-TCPOld::TCPOld()
-{
- sock = 0;
- connected = 0;
- timeoutEnabled = 1;
-}
-
-TCPOld::~TCPOld()
-{
- if (connected)
- {
- CLOSESOCKET(sock);
- Log::getInstance()->log("TCPOld", Log::DEBUG, "Have closed");
- }
-}
-
-void TCPOld::disableTimeout()
-{
- timeoutEnabled = 0;
-}
-
-void TCPOld::getMAC(UCHAR* dest)
-{
-#ifndef WIN32
- struct ifreq ifr;
- strcpy(ifr.ifr_name, "eth0");
- ioctl(sock, SIOCGIFHWADDR, &ifr);
- memcpy(dest, ifr.ifr_hwaddr.sa_data, 6);
-#else
- //TODO: Get MAC Address for windows
- PIP_ADAPTER_INFO daptinfo=NULL;
- DWORD size=0;
- GetAdaptersInfo(daptinfo,&size);
- daptinfo=(PIP_ADAPTER_INFO)new char[size+1];
- memcpy(dest,"ABCDEF", 6);//Dummy Address
- sockaddr_in sock_address;
- int sockname_len=sizeof(sock_address);
- getsockname(sock,(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(dest,daptinfo_it->Address, 6);
- break;
- }
- daptinfo_it=daptinfo_it->Next;
- if (daptinfo_it==daptinfo) break;
- }
- }
- else
- {
- // Marten?
- }
-
- delete [] daptinfo;
-#endif
-}
-
-int TCPOld::connectTo(char* host, unsigned short port)
-{
-#ifdef VOMP_PLATFORM_RASPBERRY
-#define IPV 6
-#else
-#define IPV 4
-#endif
-
-#if IPV == 4
-
- sock = socket(PF_INET, SOCK_STREAM, 0);
- if (sock == -1) return 0;
- struct sockaddr_in dest_addr;
- dest_addr.sin_family = AF_INET;
- dest_addr.sin_port = htons(port);
-
-#ifndef WIN32
- if (!inet_aton(host, &dest_addr.sin_addr))
-#else
- dest_addr.sin_addr.s_addr = inet_addr(host);
- if (dest_addr.sin_addr.s_addr == INADDR_NONE)
-#endif
- {
- CLOSESOCKET(sock);
- return 0;
- }
-
- memset(&(dest_addr.sin_zero), '\0', 8);
-
-#elif IPV == 6
-
- char portstring[10];
- snprintf(portstring, 10, "%u", port);
-
- struct addrinfo hints;
- struct addrinfo* res;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- if (getaddrinfo(host, portstring, &hints, &res))
- {
- //printf("[%s] [%s]\n", host, portstring);
- return 0;
- }
-
- sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (sock == -1) return 0;
-
-#endif
-
-
-
- // set non blocking
-#ifndef WIN32
- int oldflags = fcntl (sock, F_GETFL, 0);
- oldflags |= O_NONBLOCK;
- fcntl(sock, F_SETFL, oldflags);
-#else
- unsigned long flag=1;
- ioctlsocket(sock,FIONBIO,&flag);
-
-#endif
-
-// setReceiveWindow(2048);
-
- // ok, how to open a connection in non blocking mode (and therefore have a self set timeout!!)
-
-#if IPV == 4
- int success = connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
-#elif IPV == 6
- int success = connect(sock, res->ai_addr, res->ai_addrlen);
- freeaddrinfo(res);
-#endif
-
-
- if (success == 0) // if by some miracle the connection succeeded in no time flat, just return!
- {
- connected = 1;
- return 1;
- }
-
- // first check errno for EINPROGRESS, otherwise it's a fail
- // this doesn't work?
-#ifndef WIN32
- if (errno != EINPROGRESS)
-#else
- int wsalasterr = WSAGetLastError();
- if ((wsalasterr != WSAEWOULDBLOCK) && (wsalasterr != WSAEINPROGRESS))
-#endif
- {
- CLOSESOCKET(sock);
-
- return 0;
- }
-
- // now do a timeout wait on writability on the socket
-
- fd_set connectSet;
- struct timeval timeout;
- FD_ZERO(&connectSet);
- FD_SET(sock, &connectSet);
- timeout.tv_sec = 10;
- timeout.tv_usec = 0;
- success = select(sock + 1, NULL, &connectSet, NULL, &timeout);
- if (success < 1)
- {
- // timeout or error
- CLOSESOCKET(sock);
- return 0;
- }
-
- // so the socket became available for writing. Contrary to expectation, this doesn't actually
- // mean it connected...
-
- int soError; // SO_ERROR optval is int
- socklen_t soErrorSize = sizeof(soError);
-
-#ifdef WIN32
- int gso = getsockopt(sock, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&soError), &soErrorSize);
-#else
- int gso = getsockopt(sock, SOL_SOCKET, SO_ERROR, reinterpret_cast<void*>(&soError), &soErrorSize);
-#endif
-
- if ((gso == 0) && (soError == 0))
- {
- // success!
- connected = 1;
- return 1;
- }
- else
- {
- CLOSESOCKET(sock);
- return 0;
- }
-
-/*
-The full documentation:
-
- EINPROGRESS
- The socket is non-blocking and the connection canĀ
- not be completed immediately. It is possible to
- select(2) or poll(2) for completion by selecting
- the socket for writing. After select indicates
- writability, use getsockopt(2) to read the SO_ERROR
- option at level SOL_SOCKET to determine whether
- connect completed successfully (SO_ERROR is zero)
- or unsuccessfully (SO_ERROR is one of the usual
- error codes listed here, explaining the reason for
- the failure).
-*/
-}
-
-void TCPOld::setReceiveWindow(size_t rxBufferSize)
-{
- // Set receive window
- // According to docs, optval in setsockopt is a pointer to int unless otherwise noted
- int rxSize = rxBufferSize;
-#ifdef WIN32
- int r = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<char*>(&rxSize), sizeof(size_t));
-#else
- int r = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<void*>(&rxSize), sizeof(size_t));
-#endif
- Log::getInstance()->log("TCPOld", Log::DEBUG, "Set receive window to %i, success(=0): %i", rxBufferSize, r);
-}
-
-void TCPOld::assignSocket(int tsocket)
-{
- sock = tsocket;
-}
-
-int TCPOld::isConnected()
-{
- return connected;
-}
-
-int TCPOld::sendData(void* bufR, size_t count)
-{
- size_t bytes_sent = 0;
- int this_write;
-
- unsigned char* buf = static_cast<unsigned char*>(bufR);
-
- mutex.lock();
-
- while (bytes_sent < count)
- {
- do
- {
-#ifndef WIN32
- this_write = write(sock, buf, count - bytes_sent);
-// Log::getInstance()->log("TCPOld", Log::DEBUG, "TCPOld has written %i bytes", this_write);
- } while ( (this_write < 0) && (errno == EINTR) );
-#else
- this_write = send(sock,(char*) buf, count- bytes_sent,0);
- } while ( (this_write == SOCKET_ERROR) && (WSAGetLastError() == WSAEINTR) );
-#endif
- if (this_write <= 0)
- {
- mutex.unlock();
- return(this_write);
- }
- bytes_sent += this_write;
- buf += this_write;
- }
-
- mutex.unlock();
-
- return(count);
-}
-
-int TCPOld::readData(void* targetBuffer, int totalBytes)
-{
- UCHAR* buffer = reinterpret_cast<UCHAR*>(targetBuffer);
- int bytesRead = 0;
- int thisRead;
- int readTries = 0;
- int success;
- fd_set readSet;
- struct timeval timeout;
- struct timeval* passToSelect;
-
- if (timeoutEnabled) passToSelect = &timeout;
- else passToSelect = NULL;
-
- while(1)
- {
- FD_ZERO(&readSet);
- FD_SET(sock, &readSet);
- timeout.tv_sec = 2;
- timeout.tv_usec = 0;
- // Log::getInstance()->log("TCPOld", Log::DEBUG, "Going to select");
- success = select(sock + 1, &readSet, NULL, NULL, passToSelect);
- // Log::getInstance()->log("TCPOld", Log::DEBUG, "Back from select with success = %i", success);
- if (success < 1)
- {
- return 0; // error, or timeout
- }
-#ifndef WIN32
- thisRead = read(sock, &buffer[bytesRead], totalBytes - bytesRead);
-#else
- thisRead = recv(sock, (char*)&buffer[bytesRead], totalBytes - bytesRead, 0);
-#endif
- //Log::getInstance()->log("TCPOld", Log::DEBUG, "Read %i", thisRead);
- if (!thisRead)
- {
- // if read returns 0 then connection is closed
- // in non-blocking mode if read is called with no data available, it returns -1
- // and sets errno to EGAGAIN. but we use select so it wouldn't do that anyway.
- Log::getInstance()->log("TCPOld", Log::ERR, "Detected connection closed");
- CLOSESOCKET(sock);
- connected = 0;
- return 0;
- }
- bytesRead += thisRead;
- if (bytesRead == totalBytes)
- {
- return 1;
- }
- else
- {
- if (++readTries == 1000)
- {
- Log::getInstance()->log("TCPOld", Log::ERR, "Too many reads");
- return 0;
- }
- }
- }
-}
-
-void TCPOld::dump(unsigned char* data, ULONG size)
-{
- printf("Size = %lu\n", size);
-
- ULONG c = 0;
- while(c < size)
- {
- if ((size - c) > 15)
- {
- printf(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
- data[c+8], data[c+9], data[c+10], data[c+11], data[c+12], data[c+13], data[c+14], data[c+15],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
- dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]), dcc(data[c+12]), dcc(data[c+13]), dcc(data[c+14]), dcc(data[c+15]));
- c += 16;
- }
- else
- {
- switch (size - c)
- {
- case 15:
- printf(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
- data[c+8], data[c+9], data[c+10], data[c+11], data[c+12], data[c+13], data[c+14],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
- dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]), dcc(data[c+12]), dcc(data[c+13]), dcc(data[c+14]));
- c += 15;
- break;
- case 14:
- printf(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
- data[c+8], data[c+9], data[c+10], data[c+11], data[c+12], data[c+13],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
- dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]), dcc(data[c+12]), dcc(data[c+13]));
- c += 14;
- break;
- case 13:
- printf(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %c%c%c%c%c%c%c%c%c%c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
- data[c+8], data[c+9], data[c+10], data[c+11], data[c+12],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
- dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]), dcc(data[c+12]));
- c += 13;
- break;
- case 12:
- printf(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %c%c%c%c%c%c%c%c%c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
- data[c+8], data[c+9], data[c+10], data[c+11],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
- dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]));
- c += 12;
- break;
- case 11:
- printf(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %c%c%c%c%c%c%c%c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
- data[c+8], data[c+9], data[c+10],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
- dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]));
- c += 11;
- break;
- case 10:
- printf(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %c%c%c%c%c%c%c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
- data[c+8], data[c+9],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
- dcc(data[c+8]), dcc(data[c+9]));
- c += 10;
- break;
- case 9:
- printf(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %c%c%c%c%c%c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
- data[c+8],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
- dcc(data[c+8]));
- c += 9;
- break;
- case 8:
- printf(" %02X %02X %02X %02X %02X %02X %02X %02X %c%c%c%c%c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]));
- c += 8;
- break;
- case 7:
- printf(" %02X %02X %02X %02X %02X %02X %02X %c%c%c%c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]));
- c += 7;
- break;
- case 6:
- printf(" %02X %02X %02X %02X %02X %02X %c%c%c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]));
- c += 6;
- break;
- case 5:
- printf(" %02X %02X %02X %02X %02X %c%c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3], data[c+4],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]));
- c += 5;
- break;
- case 4:
- printf(" %02X %02X %02X %02X %c%c%c%c\n",
- data[c], data[c+1], data[c+2], data[c+3],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]));
- c += 4;
- break;
- case 3:
- printf(" %02X %02X %02X %c%c%c\n",
- data[c], data[c+1], data[c+2],
- dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]));
- c += 3;
- break;
- case 2:
- printf(" %02X %02X %c%c\n",
- data[c], data[c+1],
- dcc(data[c]), dcc(data[c+1]));
- c += 2;
- break;
- case 1:
- printf(" %02X %c\n",
- data[c],
- dcc(data[c]));
- c += 1;
- break;
- }
- }
- }
-}
-
-UCHAR TCPOld::dcc(UCHAR c)
-{
- if (isspace(c)) return ' ';
- if (isprint(c)) return c;
- return '.';
-}