/*
* winstub.c - MS-Windows compatiblity hacks
* $Id: winstub.c,v 1.10 2005/06/16 20:08:53 rdenisc Exp $
*/
/***********************************************************************
* 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 (PF_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;
}
syntax highlighted by Code2HTML, v. 0.9.1