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