1 /*
2  * winstub.c - MS-Windows compatiblity hacks
3  * $Id: winstub.c 175 2005-07-01 18:07:39Z rdenisc $
4  */
5 
6 /***********************************************************************
7  *  Copyright (C) 2002-2003 Remi Denis-Courmont.                       *
8  *  This program is free software; you can redistribute and/or modify  *
9  *  it under the terms of the GNU General Public License as published  *
10  *  by the Free Software Foundation; version 2 of the license.         *
11  *                                                                     *
12  *  This program is distributed in the hope that it will be useful,    *
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of     *
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               *
15  *  See the GNU General Public License for more details.               *
16  *                                                                     *
17  *  You should have received a copy of the GNU General Public License  *
18  *  along with this program; if not, you can get it from:              *
19  *  http://www.gnu.org/copyleft/gpl.html                               *
20  ***********************************************************************/
21 
22 # if HAVE_CONFIG_H
23 #  include <config.h>
24 # endif
25 
26 #include <stddef.h> /* size_t */
27 #include <secstdio.h>
28 #include <errno.h>
29 #include <stdint.h>
30 
31 #include <windows.h>
32 #include <wincon.h> /* SetConsoleTitle() */
33 #include <winsock2.h>
34 #include <ws2tcpip.h>
35 #ifndef WINSOCK_VERSION
36 # define WINSOCK_VERSION 0x0202
37 #endif
38 
39 #undef main
40 int winstub_main (int argc, char *argv[]);
41 
42 static SOCKET mysocket = INVALID_SOCKET;
43 
main(int argc,char * argv[])44 int main (int argc, char *argv[])
45 {
46 	WSADATA wsaData;
47 	int retval;
48 
49 	SetConsoleTitle ("TCP re-engineering tool v" PACKAGE_VERSION
50 			" for Windows");
51 
52 	if (!WSAStartup (WINSOCK_VERSION, &wsaData))
53 	{
54 		if (wsaData.wVersion == WINSOCK_VERSION)
55 		{
56 			mysocket = WSASocket (AF_INET, SOCK_DGRAM,
57 						IPPROTO_UDP, NULL, 0, 0);
58 			if (mysocket != INVALID_SOCKET)
59 			{
60 				retval = winstub_main (argc, argv);
61 				closesocket (mysocket);
62 				WSACleanup ();
63 				return retval;
64 			}
65 		}
66 		WSACleanup ();
67 	}
68 
69 	fputs ("Winsock unavailable or unsupported version. Aborting.\n",
70 		stderr);
71 	return 1;
72 }
73 
74 
75 /*
76  * Unreliable socket-enabled perror() replacement for Winsock.
77  */
78 #undef perror
winsock_perror(const char * str)79 void winsock_perror (const char *str)
80 {
81 	int num;
82 	num = WSAGetLastError ();
83 
84 	if ((num == 0) && (errno >= WSABASEERR))
85 	{
86 		num = errno;
87 		errno = 0;
88 	}
89 
90 	if (num)
91 		fprintf (stderr, "%s: Winsock error %d.\n", str, num);
92 	else
93 	{
94 		if (errno)
95 			perror (str);
96 		else
97 			fprintf (stderr, "%s: unable to trace error.\n", str);
98 	}
99 }
100 
101 /*
102  * Unreliable socket-enabled strerror() replacement for Winsock.
103  * (NOT THREAD-SAFE)
104  */
105 #undef strerror
winsock_strerror(int errnum)106 const char *winsock_strerror (int errnum)
107 {
108 	static char buf[32];
109 
110 	if (errnum >= WSABASEERR)
111 	{
112 		snprintf (buf, sizeof (buf), "Windows socket error %u",
113 				errnum);
114 		return buf;
115 	}
116 	else
117 		return strerror (errnum);
118 }
119 
120 
winsock_close(int fd)121 int winsock_close (int fd)
122 {
123 	int errnum;
124 
125 	errnum = WSAGetLastError ();
126 	if (closesocket ((SOCKET)fd) != SOCKET_ERROR);
127 	{
128 		WSASetLastError (errnum);
129 		return 0;
130 	}
131 	errno = WSAGetLastError ();
132 	return -1;
133 }
134 
135 
winsock_recvfrom(int fd,void * buf,size_t len,int flags,struct sockaddr * addr,socklen_t * addrlen)136 size_t winsock_recvfrom (int fd, void *buf, size_t len, int flags,
137 			 struct sockaddr *addr, socklen_t *addrlen)
138 {
139 	int errnum;
140 	WSABUF buffer;
141 	DWORD count, dwFlags = flags;
142 
143 	errnum = WSAGetLastError ();
144 	buffer.len = (unsigned long)len;
145 	buffer.buf = (char *)buf;
146 
147 	if (WSARecvFrom ((SOCKET)fd, &buffer, 1, &count, &dwFlags,
148 			 addr, addrlen, NULL, NULL) == 0)
149 	{
150 		WSASetLastError (errnum);
151 		return (size_t)count;
152 	}
153 	errno = WSAGetLastError ();
154 	return -1;
155 }
156 
157 
winsock_sendto(int fd,const void * buf,size_t len,int flags,const struct sockaddr * addr,socklen_t addrlen)158 size_t winsock_sendto (int fd, const void *buf, size_t len, int flags,
159 			const struct sockaddr *addr, socklen_t addrlen)
160 {
161 	int errnum;
162 	WSABUF buffer;
163 	DWORD count;
164 
165 	errnum = WSAGetLastError ();
166 	buffer.len = (unsigned long)len;
167 	buffer.buf = (char *)buf;
168 
169 	if (WSASendTo ((SOCKET)fd, &buffer, 1, &count, (DWORD)flags,
170 			addr, addrlen, NULL, NULL) == 0)
171 	{
172 		if (!WSAGetLastError ())
173 			WSASetLastError (errnum);
174 		return (size_t)count;
175 	}
176 	errno = WSAGetLastError ();
177 	return -1;
178 }
179 
180 
winsock_read(int fd,void * buf,size_t len)181 size_t winsock_read (int fd, void *buf, size_t len)
182 {
183 	return winsock_recv (fd, buf, len, 0);
184 }
185 
186 
winsock_write(int fd,const void * buf,size_t len)187 size_t winsock_write (int fd, const void *buf, size_t len)
188 {
189 	return winsock_send (fd, buf, len, 0);
190 }
191 
192 
winsock_recv(int fd,void * buf,size_t len,int flags)193 size_t winsock_recv (int fd, void *buf, size_t len, int flags)
194 {
195 	return winsock_recvfrom (fd, buf, len, flags, NULL, 0);
196 }
197 
198 
winsock_send(int fd,const void * buf,size_t len,int flags)199 size_t winsock_send (int fd, const void *buf, size_t len, int flags)
200 {
201 	return winsock_sendto (fd, buf, len, flags, NULL, 0);
202 }
203 
204 
winsock_socket(int pf,int type,int proto)205 int winsock_socket (int pf, int type, int proto)
206 {
207 	int errnum;
208 	SOCKET fd;
209 
210 	errnum = WSAGetLastError ();
211 
212 	fd = WSASocket (pf, type, proto, NULL, 0, 0);
213 	if (fd != INVALID_SOCKET)
214 	{
215 		WSASetLastError (errnum);
216 		return (int)fd;
217 	}
218 	errno = WSAGetLastError ();
219 	return -1;
220 }
221 
222 
223 #undef bind
winsock_bind(int fd,struct sockaddr * addr,socklen_t addrlen)224 int winsock_bind (int fd, struct sockaddr *addr, socklen_t addrlen)
225 {
226 	int errnum;
227 
228 	errnum = WSAGetLastError ();
229 	if (bind ((SOCKET)fd, (LPSOCKADDR)addr, addrlen) != SOCKET_ERROR)
230 	{
231 		WSASetLastError (errnum);
232 		return 0;
233 	}
234 	errno = WSAGetLastError ();
235 	return -1;
236 }
237 
238 
239 #undef listen
winsock_listen(int fd,int max)240 int winsock_listen (int fd, int max)
241 {
242 	int errnum;
243 
244 	errnum = WSAGetLastError ();
245 	if (listen ((SOCKET)fd, max) != SOCKET_ERROR)
246 	{
247 		WSASetLastError (errnum);
248 		return 0;
249 	}
250 	errno = WSAGetLastError ();
251 	return -1;
252 }
253 
254 
winsock_accept(int fd,struct sockaddr * addr,socklen_t * len)255 int winsock_accept (int fd, struct sockaddr *addr, socklen_t *len)
256 {
257 	int errnum;
258 	SOCKET newfd;
259 
260 	errnum = WSAGetLastError ();
261 	newfd = WSAAccept ((SOCKET)fd, addr, len, NULL, 0);
262 	if (newfd != INVALID_SOCKET)
263 	{
264 		WSASetLastError (errnum);
265 		return (int)newfd;
266 	}
267 	errno = WSAGetLastError ();
268 	return -1;
269 }
270 
271 
winsock_connect(int fd,struct sockaddr * addr,socklen_t len)272 int winsock_connect (int fd, struct sockaddr *addr, socklen_t len)
273 {
274 	int errnum;
275 
276 	errnum = WSAGetLastError ();
277 	if (WSAConnect ((SOCKET)fd, addr, len, NULL, NULL, NULL, NULL)
278 			!= SOCKET_ERROR)
279 	{
280 		WSASetLastError (errnum);
281 		return 0;
282 	}
283 	errno = WSAGetLastError ();
284 	return -1;
285 }
286 
287 
288 #undef shutdown
winsock_shutdown(int fd,int how)289 int winsock_shutdown (int fd, int how)
290 {
291 	int errnum;
292 
293 	errnum = WSAGetLastError ();
294 	if (shutdown ((SOCKET)fd, how) != SOCKET_ERROR)
295 	{
296 		WSASetLastError (errnum);
297 		return 0;
298 	}
299 	errno = WSAGetLastError ();
300 	return -1;
301 }
302 
303 
304 #undef setsockopt
winsock_setsockopt(int fd,int lvl,int opt,const void * data,socklen_t len)305 int winsock_setsockopt (int fd, int lvl, int opt, const void *data,
306 			socklen_t len)
307 {
308 	int errnum;
309 
310 	errnum = WSAGetLastError ();
311 	if (setsockopt ((SOCKET)fd, lvl, opt, (const char *)data, len)
312 			!= SOCKET_ERROR)
313 	{
314 		WSASetLastError (errnum);
315 		return 0;
316 	}
317 	errno = WSAGetLastError ();
318 	return -1;
319 }
320 
321 
322 #undef getsockopt
winsock_getsockopt(int fd,int lvl,int opt,void * data,socklen_t * len)323 int winsock_getsockopt (int fd, int lvl, int opt, void *data, socklen_t *len)
324 {
325 	int errnum;
326 
327 	errnum = WSAGetLastError ();
328 	if (getsockopt ((SOCKET)fd, lvl, opt, (char *)data, len)
329 			!= SOCKET_ERROR)
330 	{
331 		WSASetLastError (errnum);
332 		return 0;
333 	}
334 	errno = WSAGetLastError ();
335 	return -1;
336 }
337 
338 
339 #undef getpeername
winsock_getpeername(int fd,struct sockaddr * addr,socklen_t * len)340 int winsock_getpeername (int fd, struct sockaddr *addr, socklen_t *len)
341 {
342 	int errnum;
343 
344 	errnum = WSAGetLastError ();
345 	if (getpeername ((SOCKET)fd, addr, len) != SOCKET_ERROR)
346 	{
347 		WSASetLastError (errnum);
348 		return 0;
349 	}
350 	errno = WSAGetLastError ();
351 	return -1;
352 }
353 
354 
355 #undef getsockname
winsock_getsockname(int fd,struct sockaddr * addr,socklen_t * len)356 int winsock_getsockname (int fd, struct sockaddr *addr, socklen_t *len)
357 {
358 	int errnum;
359 
360 	errnum = WSAGetLastError ();
361 	if (getsockname ((SOCKET)fd, addr, len) != SOCKET_ERROR)
362 	{
363 		WSASetLastError (errnum);
364 		return 0;
365 	}
366 	errno = WSAGetLastError ();
367 	return -1;
368 }
369 
370 
371 #undef gethostbyaddr
winsock_gethostbyaddr(const char * addr,int len,int type)372 struct hostent *winsock_gethostbyaddr (const char *addr, int len,
373 						int type)
374 {
375 	int errnum;
376 	struct hostent *retval;
377 
378 	errnum = WSAGetLastError ();
379 	retval = gethostbyaddr (addr, len, type);
380 	if (retval != NULL)
381 		WSASetLastError (errnum);
382 	else
383 		errno = WSAGetLastError ();
384 
385 	return retval;
386 }
387 
388 
389 #undef gethostbyname
winsock_gethostbyname(const char * name)390 struct hostent *winsock_gethostbyname (const char *name)
391 {
392 	int errnum;
393 	struct hostent *retval;
394 
395 	errnum = WSAGetLastError ();
396 	retval = gethostbyname (name);
397 	if (retval != NULL)
398 		WSASetLastError (errnum);
399 	else
400 		errno = WSAGetLastError ();
401 
402 	return retval;
403 }
404 
405 
406 #undef inet_ntoa
winsock_inet_ntoa(struct in_addr in)407 char *winsock_inet_ntoa (struct in_addr in)
408 {
409 	int errnum;
410 	char *retval;
411 
412 	errnum = WSAGetLastError ();
413 	retval = inet_ntoa (in);
414 	WSASetLastError (errnum);
415 
416 	return retval;
417 }
418 
419 
420 #undef inet_addr
winsock_inet_addr(const char * dotip)421 unsigned long winsock_inet_addr (const char *dotip)
422 {
423 	int errnum;
424 	unsigned long retval;
425 
426 	errnum = WSAGetLastError ();
427 	retval = inet_addr (dotip);
428 	WSASetLastError (errnum);
429 
430 	return retval;
431 }
432 
433 
434 #undef getservbyport
winsock_getservbyport(int port,const char * proto)435 struct servent *winsock_getservbyport (int port, const char *proto)
436 {
437 	int errnum;
438 	struct servent *retval;
439 
440 	errnum = WSAGetLastError ();
441 	retval = getservbyport (port, proto);
442 	if (retval != NULL)
443 		WSASetLastError (errnum);
444 	else
445 		errno = WSAGetLastError ();
446 
447 	return retval;
448 }
449 
450 
451 #undef getservbyname
winsock_getservbyname(const char * name,const char * proto)452 struct servent *winsock_getservbyname (const char *name, const char *proto)
453 {
454 	int errnum;
455 	struct servent *retval;
456 
457 	errnum = WSAGetLastError ();
458 	retval = getservbyname (name, proto);
459 	if (retval != NULL)
460 		WSASetLastError (errnum);
461 	else
462 		errno = WSAGetLastError ();
463 
464 	return retval;
465 }
466 
467 
winsock_ntohs(uint16_t s)468 uint16_t winsock_ntohs (uint16_t s)
469 {
470 	int errnum;
471 	u_short retval;
472 
473 	errnum = WSAGetLastError ();
474 	WSANtohs (mysocket, (u_short)s, &retval);
475 	WSASetLastError (errnum);
476 
477 	return (uint16_t)retval;
478 }
479 
480 
winsock_htons(uint16_t s)481 uint16_t winsock_htons (uint16_t s)
482 {
483 	int errnum;
484 	u_short retval;
485 
486 	errnum = WSAGetLastError ();
487 	WSAHtons (mysocket, (u_short)s, &retval);
488 	WSASetLastError (errnum);
489 
490 	return (uint16_t)retval;
491 }
492 
493 
winsock_ntohl(uint32_t l)494 uint32_t winsock_ntohl (uint32_t l)
495 {
496 	int errnum;
497 	u_long retval;
498 
499 	errnum = WSAGetLastError ();
500 	WSANtohl (mysocket, (u_long)l, &retval);
501 	WSASetLastError (errnum);
502 
503 	return (uint32_t)retval;
504 }
505 
506 
winsock_htonl(uint32_t l)507 uint32_t winsock_htonl (uint32_t l)
508 {
509 	int errnum;
510 	u_long retval;
511 
512 	errnum = WSAGetLastError ();
513 	WSAHtonl (mysocket, (u_long)l, &retval);
514 	WSASetLastError (errnum);
515 
516 	return (uint32_t)retval;
517 }
518 
519 
winsock_getaddrinfo(const char * node,const char * service,const struct addrinfo * hints,struct addrinfo ** res)520 int winsock_getaddrinfo (const char *node, const char *service,
521                  const struct addrinfo *hints, struct addrinfo **res)
522 {
523 	typedef int (CALLBACK * GETADDRINFO) (const char *, const char *,
524 	                                      const struct addrinfo *,
525 	                                      struct addrinfo **);
526 	HINSTANCE wship6_module;
527 	GETADDRINFO ws2_getaddrinfo;
528 
529 	wship6_module = LoadLibrary ("wship6.dll");
530 	if (wship6_module != NULL)
531 	{
532 		ws2_getaddrinfo = (GETADDRINFO)GetProcAddress (wship6_module,
533 		                                               "getaddrinfo");
534 		if (ws2_getaddrinfo != NULL)
535 		{
536 			int ret;
537 
538 			ret = ws2_getaddrinfo (node, service, hints, res);
539 			FreeLibrary (wship6_module); /* is this wise ? */
540 			return ret;
541 		}
542 
543 		FreeLibrary (wship6_module);
544 	}
545 
546 	return stub_getaddrinfo (node, service, hints, res);
547 }
548 
549 
winsock_freeaddrinfo(struct addrinfo * infos)550 void winsock_freeaddrinfo (struct addrinfo *infos)
551 {
552 	typedef void (CALLBACK * FREEADDRINFO) (struct addrinfo *);
553 	HINSTANCE wship6_module;
554 	FREEADDRINFO ws2_freeaddrinfo;
555 
556 	wship6_module = LoadLibrary ("wship6.dll");
557 	if (wship6_module != NULL)
558 	{
559 		ws2_freeaddrinfo = (FREEADDRINFO)GetProcAddress (wship6_module,
560 		                                                 "freeaddrinfo");
561 
562 		/*
563 		 * NOTE: it is assumed that wship6.dll defines either both
564 		 * getaddrinfo and freeaddrinfo or none of them.
565 		 */
566 		if (ws2_freeaddrinfo != NULL)
567 		{
568 			ws2_freeaddrinfo (infos);
569 			FreeLibrary (wship6_module);
570 			return;
571         }
572 
573 		FreeLibrary (wship6_module);
574 	}
575 	stub_freeaddrinfo (infos);
576 }
577 
578 
winsock_getnameinfo(const struct sockaddr * sa,int salen,char * host,int hostlen,char * serv,int servlen,int flags)579 int winsock_getnameinfo (const struct sockaddr *sa, int salen, char *host,
580                          int hostlen, char *serv, int servlen, int flags)
581 {
582 	/*
583 	 * Here is the kind of kludge you need to keep binary compatibility among
584 	 * varying OS versions...
585 	 */
586 	typedef int (CALLBACK * GETNAMEINFO) (const struct sockaddr*, socklen_t,
587 	                                      char*, DWORD, char*, DWORD, int);
588 	HINSTANCE wship6_module;
589 	GETNAMEINFO ws2_getnameinfo;
590 
591 	wship6_module = LoadLibrary ("wship6.dll");
592 	if( wship6_module != NULL )
593 	{
594 		ws2_getnameinfo = (GETNAMEINFO)GetProcAddress (wship6_module,
595 		                                               "getnameinfo");
596 
597 		if (ws2_getnameinfo != NULL)
598 		{
599 			int ret;
600 
601 			ret = ws2_getnameinfo (sa, salen, host, hostlen, serv, servlen,
602 			                       flags);
603 			FreeLibrary (wship6_module);
604 			return ret;
605 		}
606 
607 		FreeLibrary (wship6_module);
608 	}
609 	return stub_getnameinfo (sa, salen, host, hostlen, serv, servlen, flags);
610 }
611 
612 static uid_t _uid = 1000; /* anything but 0, please */
613 
setuid(uid_t uid)614 int setuid (uid_t uid)
615 {
616 	_uid = uid;
617 	return 0;
618 }
619 
620 
getuid(void)621 uid_t getuid (void)
622 {
623 	return _uid;
624 }
625 
626 
627 static uid_t _euid = 0;
628 
seteuid(uid_t euid)629 int seteuid (uid_t euid)
630 {
631 	_euid = euid;
632 	return 0;
633 }
634 
geteuid(void)635 uid_t geteuid (void)
636 {
637 	return _euid;
638 }
639 
640 
getpwnam(const char * username)641 struct passwd *getpwnam (const char *username)
642 {
643 	return NULL;
644 }
645 
646 
getpwuid(uid_t uid)647 struct passwd *getpwuid (uid_t uid)
648 {
649 	return NULL;
650 }
651 
652 
openlog(const char * ident,int option,int facility)653 void openlog (const char *ident, int option, int facility)
654 {
655 	/* RegisterEventSource */
656 	fprintf (stderr,
657 		"WARNING: no system logging available for %s\n"
658 		"(requested facility number %d, option=0x%x)\n"
659 		"Any further logging information will be dropped.\n",
660 		ident, facility, option);
661 }
662 
663 
664 void
syslog(int priority,const char * fmt,...)665 syslog (int priority, const char *fmt, ... )
666 {
667 	/* ReportEvent */
668 }
669 
670 
closelog(void)671 void closelog (void)
672 {
673 	/* DeregisterEventSource */
674 }
675 
676 
677 # include <stdarg.h>
678 void
vsyslog(int priority,const char * fmt,va_list ap)679 vsyslog (int priority, const char *fmt, va_list ap)
680 {
681 	/* ReportEvent */
682 }
683 
684 
sleep(unsigned int sec)685 unsigned int sleep (unsigned int sec)
686 {
687 	Sleep (sec * 1000);
688 	return 0;
689 }
690