Logo Search packages:      
Sourcecode: tcpreen version File versions  Download package

winstub.c

/*
 * winstub.c - MS-Windows compatiblity hacks
 * $Id: winstub.c 175 2005-07-01 18:07:39Z rdenisc $
 */

/***********************************************************************
 *  Copyright (C) 2002-2003 Remi Denis-Courmont.                       *
 *  This program is free software; you can redistribute and/or modify  *
 *  it under the terms of the GNU General Public License as published  *
 *  by the Free Software Foundation; version 2 of the license.         *
 *                                                                     *
 *  This program 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 this program; if not, you can get it from:              *
 *  http://www.gnu.org/copyleft/gpl.html                               *
 ***********************************************************************/

# if HAVE_CONFIG_H
#  include <config.h>
# endif

#include <stddef.h> /* size_t */
#include <secstdio.h>
#include <errno.h>
#include <stdint.h>

#include <windows.h>
#include <wincon.h> /* SetConsoleTitle() */
#include <winsock2.h>
#include <ws2tcpip.h>
#ifndef WINSOCK_VERSION
# define WINSOCK_VERSION 0x0202
#endif

#undef main
int winstub_main (int argc, char *argv[]);

static SOCKET mysocket = INVALID_SOCKET;

int main (int argc, char *argv[])
{
      WSADATA wsaData;
      int retval;

      SetConsoleTitle ("TCP re-engineering tool v" PACKAGE_VERSION
                  " for Windows");

      if (!WSAStartup (WINSOCK_VERSION, &wsaData))
      {
            if (wsaData.wVersion == WINSOCK_VERSION)
            {
                  mysocket = WSASocket (AF_INET, SOCK_DGRAM,
                                    IPPROTO_UDP, NULL, 0, 0);
                  if (mysocket != INVALID_SOCKET)
                  {
                        retval = winstub_main (argc, argv);
                        closesocket (mysocket);
                        WSACleanup ();
                        return retval;
                  }
            }
            WSACleanup ();
      }

      fputs ("Winsock unavailable or unsupported version. Aborting.\n",
            stderr);
      return 1;
}


/*
 * Unreliable socket-enabled perror() replacement for Winsock.
 */
#undef perror
void winsock_perror (const char *str)
{
      int num;
      num = WSAGetLastError ();

      if ((num == 0) && (errno >= WSABASEERR))
      {
            num = errno;
            errno = 0;
      }

      if (num)
            fprintf (stderr, "%s: Winsock error %d.\n", str, num);
      else
      {
            if (errno)
                  perror (str);
            else
                  fprintf (stderr, "%s: unable to trace error.\n", str);
      }
}

/*
 * Unreliable socket-enabled strerror() replacement for Winsock.
 * (NOT THREAD-SAFE)
 */
#undef strerror
const char *winsock_strerror (int errnum)
{
      static char buf[32];

      if (errnum >= WSABASEERR)
      {
            snprintf (buf, sizeof (buf), "Windows socket error %u",
                        errnum);
            return buf;
      }
      else
            return strerror (errnum);
}


int winsock_close (int fd)
{
      int errnum;

      errnum = WSAGetLastError ();
      if (closesocket ((SOCKET)fd) != SOCKET_ERROR);
      {
            WSASetLastError (errnum);
            return 0;
      }
      errno = WSAGetLastError ();
      return -1;
}


size_t winsock_recvfrom (int fd, void *buf, size_t len, int flags,
                   struct sockaddr *addr, socklen_t *addrlen)
{
      int errnum;
      WSABUF buffer;
      DWORD count, dwFlags = flags;

      errnum = WSAGetLastError ();
      buffer.len = (unsigned long)len;
      buffer.buf = (char *)buf;

      if (WSARecvFrom ((SOCKET)fd, &buffer, 1, &count, &dwFlags,
                   addr, addrlen, NULL, NULL) == 0)
      {
            WSASetLastError (errnum);
            return (size_t)count;
      }
      errno = WSAGetLastError ();
      return -1;
}


size_t winsock_sendto (int fd, const void *buf, size_t len, int flags,
                  const struct sockaddr *addr, socklen_t addrlen)
{
      int errnum;
      WSABUF buffer;
      DWORD count;

      errnum = WSAGetLastError ();
      buffer.len = (unsigned long)len;
      buffer.buf = (char *)buf;

      if (WSASendTo ((SOCKET)fd, &buffer, 1, &count, (DWORD)flags,
                  addr, addrlen, NULL, NULL) == 0)
      {
            if (!WSAGetLastError ())
                  WSASetLastError (errnum);
            return (size_t)count;
      }
      errno = WSAGetLastError ();
      return -1;
}


size_t winsock_read (int fd, void *buf, size_t len)
{
      return winsock_recv (fd, buf, len, 0);
}


size_t winsock_write (int fd, const void *buf, size_t len)
{
      return winsock_send (fd, buf, len, 0);
}


size_t winsock_recv (int fd, void *buf, size_t len, int flags)
{
      return winsock_recvfrom (fd, buf, len, flags, NULL, 0);
}


size_t winsock_send (int fd, const void *buf, size_t len, int flags)
{
      return winsock_sendto (fd, buf, len, flags, NULL, 0);
}


int winsock_socket (int pf, int type, int proto)
{
      int errnum;
      SOCKET fd;

      errnum = WSAGetLastError ();

      fd = WSASocket (pf, type, proto, NULL, 0, 0);
      if (fd != INVALID_SOCKET)
      {
            WSASetLastError (errnum);
            return (int)fd;
      }
      errno = WSAGetLastError ();
      return -1;
}


#undef bind
int winsock_bind (int fd, struct sockaddr *addr, socklen_t addrlen)
{
      int errnum;

      errnum = WSAGetLastError ();
      if (bind ((SOCKET)fd, (LPSOCKADDR)addr, addrlen) != SOCKET_ERROR)
      {
            WSASetLastError (errnum);
            return 0;
      }
      errno = WSAGetLastError ();
      return -1;
}


#undef listen
int winsock_listen (int fd, int max)
{
      int errnum;

      errnum = WSAGetLastError ();
      if (listen ((SOCKET)fd, max) != SOCKET_ERROR)
      {
            WSASetLastError (errnum);
            return 0;
      }
      errno = WSAGetLastError ();
      return -1;
}


int winsock_accept (int fd, struct sockaddr *addr, socklen_t *len)
{
      int errnum;
      SOCKET newfd;

      errnum = WSAGetLastError ();
      newfd = WSAAccept ((SOCKET)fd, addr, len, NULL, 0);
      if (newfd != INVALID_SOCKET)
      {
            WSASetLastError (errnum);
            return (int)newfd;
      }
      errno = WSAGetLastError ();
      return -1;
}


int winsock_connect (int fd, struct sockaddr *addr, socklen_t len)
{
      int errnum;

      errnum = WSAGetLastError ();
      if (WSAConnect ((SOCKET)fd, addr, len, NULL, NULL, NULL, NULL)
                  != SOCKET_ERROR)
      {
            WSASetLastError (errnum);
            return 0;
      }
      errno = WSAGetLastError ();
      return -1;
}


#undef shutdown
int winsock_shutdown (int fd, int how)
{
      int errnum;

      errnum = WSAGetLastError ();
      if (shutdown ((SOCKET)fd, how) != SOCKET_ERROR)
      {
            WSASetLastError (errnum);
            return 0;
      }
      errno = WSAGetLastError ();
      return -1;
}


#undef setsockopt
int winsock_setsockopt (int fd, int lvl, int opt, const void *data,
                  socklen_t len)
{
      int errnum;

      errnum = WSAGetLastError ();
      if (setsockopt ((SOCKET)fd, lvl, opt, (const char *)data, len)
                  != SOCKET_ERROR)
      {
            WSASetLastError (errnum);
            return 0;
      }
      errno = WSAGetLastError ();
      return -1;
}


#undef getsockopt
int winsock_getsockopt (int fd, int lvl, int opt, void *data, socklen_t *len)
{
      int errnum;

      errnum = WSAGetLastError ();
      if (getsockopt ((SOCKET)fd, lvl, opt, (char *)data, len)
                  != SOCKET_ERROR)
      {
            WSASetLastError (errnum);
            return 0;
      }
      errno = WSAGetLastError ();
      return -1;
}


#undef getpeername
int winsock_getpeername (int fd, struct sockaddr *addr, socklen_t *len)
{
      int errnum;

      errnum = WSAGetLastError ();
      if (getpeername ((SOCKET)fd, addr, len) != SOCKET_ERROR)
      {
            WSASetLastError (errnum);
            return 0;
      }
      errno = WSAGetLastError ();
      return -1;
}


#undef getsockname
int winsock_getsockname (int fd, struct sockaddr *addr, socklen_t *len)
{
      int errnum;

      errnum = WSAGetLastError ();
      if (getsockname ((SOCKET)fd, addr, len) != SOCKET_ERROR)
      {
            WSASetLastError (errnum);
            return 0;
      }
      errno = WSAGetLastError ();
      return -1;
}


#undef gethostbyaddr
struct hostent *winsock_gethostbyaddr (const char *addr, int len,
                                    int type)
{
      int errnum;
      struct hostent *retval;

      errnum = WSAGetLastError ();
      retval = gethostbyaddr (addr, len, type);
      if (retval != NULL)
            WSASetLastError (errnum);
      else
            errno = WSAGetLastError ();

      return retval;
}


#undef gethostbyname
struct hostent *winsock_gethostbyname (const char *name)
{
      int errnum;
      struct hostent *retval;

      errnum = WSAGetLastError ();
      retval = gethostbyname (name);
      if (retval != NULL)
            WSASetLastError (errnum);
      else
            errno = WSAGetLastError ();

      return retval;
}


#undef inet_ntoa
char *winsock_inet_ntoa (struct in_addr in)
{
      int errnum;
      char *retval;

      errnum = WSAGetLastError ();
      retval = inet_ntoa (in);
      WSASetLastError (errnum);

      return retval;
}


#undef inet_addr
unsigned long winsock_inet_addr (const char *dotip)
{
      int errnum;
      unsigned long retval;

      errnum = WSAGetLastError ();
      retval = inet_addr (dotip);
      WSASetLastError (errnum);

      return retval;
}


#undef getservbyport
struct servent *winsock_getservbyport (int port, const char *proto)
{
      int errnum;
      struct servent *retval;

      errnum = WSAGetLastError ();
      retval = getservbyport (port, proto);
      if (retval != NULL)
            WSASetLastError (errnum);
      else
            errno = WSAGetLastError ();

      return retval;
}


#undef getservbyname
struct servent *winsock_getservbyname (const char *name, const char *proto)
{
      int errnum;
      struct servent *retval;

      errnum = WSAGetLastError ();
      retval = getservbyname (name, proto);
      if (retval != NULL)
            WSASetLastError (errnum);
      else
            errno = WSAGetLastError ();

      return retval;
}


uint16_t winsock_ntohs (uint16_t s)
{
      int errnum;
      u_short retval;

      errnum = WSAGetLastError ();
      WSANtohs (mysocket, (u_short)s, &retval);
      WSASetLastError (errnum);

      return (uint16_t)retval;
}
      

uint16_t winsock_htons (uint16_t s)
{
      int errnum;
      u_short retval;

      errnum = WSAGetLastError ();
      WSAHtons (mysocket, (u_short)s, &retval);
      WSASetLastError (errnum);

      return (uint16_t)retval;
}


uint32_t winsock_ntohl (uint32_t l)
{
      int errnum;
      u_long retval;

      errnum = WSAGetLastError ();
      WSANtohl (mysocket, (u_long)l, &retval);
      WSASetLastError (errnum);

      return (uint32_t)retval;
}


uint32_t winsock_htonl (uint32_t l)
{
      int errnum;
      u_long retval;

      errnum = WSAGetLastError ();
      WSAHtonl (mysocket, (u_long)l, &retval);
      WSASetLastError (errnum);

      return (uint32_t)retval;
}


int winsock_getaddrinfo (const char *node, const char *service,
                 const struct addrinfo *hints, struct addrinfo **res)
{
      typedef int (CALLBACK * GETADDRINFO) (const char *, const char *,
                                            const struct addrinfo *,
                                            struct addrinfo **);
      HINSTANCE wship6_module;
      GETADDRINFO ws2_getaddrinfo;
         
      wship6_module = LoadLibrary ("wship6.dll");
      if (wship6_module != NULL)
      {
            ws2_getaddrinfo = (GETADDRINFO)GetProcAddress (wship6_module,
                                                           "getaddrinfo");
            if (ws2_getaddrinfo != NULL)
            {
                  int ret;

                  ret = ws2_getaddrinfo (node, service, hints, res);
                  FreeLibrary (wship6_module); /* is this wise ? */
                  return ret;
            }
            
            FreeLibrary (wship6_module);
      }

      return stub_getaddrinfo (node, service, hints, res);
}


void winsock_freeaddrinfo (struct addrinfo *infos)
{
      typedef void (CALLBACK * FREEADDRINFO) (struct addrinfo *);
      HINSTANCE wship6_module;
      FREEADDRINFO ws2_freeaddrinfo;
     
      wship6_module = LoadLibrary ("wship6.dll");
      if (wship6_module != NULL)
      {
            ws2_freeaddrinfo = (FREEADDRINFO)GetProcAddress (wship6_module,
                                                             "freeaddrinfo");

            /*
             * NOTE: it is assumed that wship6.dll defines either both
             * getaddrinfo and freeaddrinfo or none of them.
             */
            if (ws2_freeaddrinfo != NULL)
            {
                  ws2_freeaddrinfo (infos);
                  FreeLibrary (wship6_module);
                  return;
        }

            FreeLibrary (wship6_module);
      }
      stub_freeaddrinfo (infos);
}


int winsock_getnameinfo (const struct sockaddr *sa, int salen, char *host,
                         int hostlen, char *serv, int servlen, int flags)
{
      /*
       * Here is the kind of kludge you need to keep binary compatibility among
       * varying OS versions...
       */
      typedef int (CALLBACK * GETNAMEINFO) (const struct sockaddr*, socklen_t,
                                            char*, DWORD, char*, DWORD, int);
      HINSTANCE wship6_module;
      GETNAMEINFO ws2_getnameinfo;
     
      wship6_module = LoadLibrary ("wship6.dll");
      if( wship6_module != NULL )
      {
            ws2_getnameinfo = (GETNAMEINFO)GetProcAddress (wship6_module,
                                                           "getnameinfo");

            if (ws2_getnameinfo != NULL)
            {
                  int ret;

                  ret = ws2_getnameinfo (sa, salen, host, hostlen, serv, servlen, 
                                         flags);
                  FreeLibrary (wship6_module);
                  return ret;
            }

            FreeLibrary (wship6_module);
      }
      return stub_getnameinfo (sa, salen, host, hostlen, serv, servlen, flags);
}

static uid_t _uid = 1000; /* anything but 0, please */

int setuid (uid_t uid)
{
      _uid = uid;
      return 0;
}


uid_t getuid (void)
{
      return _uid;
}


static uid_t _euid = 0;

int seteuid (uid_t euid)
{
      _euid = euid;
      return 0;
}

uid_t geteuid (void)
{
      return _euid;
}


struct passwd *getpwnam (const char *username)
{
      return NULL;
}


struct passwd *getpwuid (uid_t uid)
{
      return NULL;
}


void openlog (const char *ident, int option, int facility)
{
      /* RegisterEventSource */
      fprintf (stderr,
            "WARNING: no system logging available for %s\n"
            "(requested facility number %d, option=0x%x)\n"
            "Any further logging information will be dropped.\n",
            ident, facility, option);
}


void
syslog (int priority, const char *fmt, ... )
{
      /* ReportEvent */
}


void closelog (void)
{
      /* DeregisterEventSource */
}


# include <stdarg.h>
void
vsyslog (int priority, const char *fmt, va_list ap)
{
      /* ReportEvent */
}


unsigned int sleep (unsigned int sec)
{
      Sleep (sec * 1000);
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index