VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/slirp/misc.c@ 9113

最後變更 在這個檔案從9113是 1824,由 vboxsync 提交於 18 年 前

Disable NAT UDP broadcast resend to local address. Removed the inline declarations and the useless _MSC_VER checks. And eliminated a few compiler warnings.

  • 屬性 svn:eol-style 設為 native
檔案大小: 14.3 KB
 
1/*
2 * Copyright (c) 1995 Danny Gasparovski.
3 *
4 * Please read the file COPYRIGHT for the
5 * terms and conditions of the copyright.
6 */
7
8#define WANT_SYS_IOCTL_H
9#include <slirp.h>
10
11
12#if 0
13int x_port = -1;
14int x_display = 0;
15int x_screen = 0;
16
17int
18show_x(buff, inso)
19 char *buff;
20 struct socket *inso;
21{
22 if (x_port < 0) {
23 lprint("X Redir: X not being redirected.\r\n");
24 } else {
25 lprint("X Redir: In sh/bash/zsh/etc. type: DISPLAY=%s:%d.%d; export DISPLAY\r\n",
26 inet_ntoa(our_addr), x_port, x_screen);
27 lprint("X Redir: In csh/tcsh/etc. type: setenv DISPLAY %s:%d.%d\r\n",
28 inet_ntoa(our_addr), x_port, x_screen);
29 if (x_display)
30 lprint("X Redir: Redirecting to display %d\r\n", x_display);
31 }
32
33 return CFG_OK;
34}
35
36
37/*
38 * XXX Allow more than one X redirection?
39 */
40void
41redir_x(inaddr, start_port, display, screen)
42 u_int32_t inaddr;
43 int start_port;
44 int display;
45 int screen;
46{
47 int i;
48
49 if (x_port >= 0) {
50 lprint("X Redir: X already being redirected.\r\n");
51 show_x(0, 0);
52 } else {
53 for (i = 6001 + (start_port-1); i <= 6100; i++) {
54 if (solisten(htons(i), inaddr, htons(6000 + display), 0)) {
55 /* Success */
56 x_port = i - 6000;
57 x_display = display;
58 x_screen = screen;
59 show_x(0, 0);
60 return;
61 }
62 }
63 lprint("X Redir: Error: Couldn't redirect a port for X. Weird.\r\n");
64 }
65}
66#endif
67
68#ifndef HAVE_INET_ATON
69int
70inet_aton(cp, ia)
71 const char *cp;
72 struct in_addr *ia;
73{
74 u_int32_t addr = inet_addr(cp);
75 if (addr == 0xffffffff)
76 return 0;
77 ia->s_addr = addr;
78 return 1;
79}
80#endif
81
82/*
83 * Get our IP address and put it in our_addr
84 */
85void
86getouraddr(PNATState pData)
87{
88 char buff[256];
89 struct hostent *he = NULL;
90
91 if (gethostname(buff,256) == 0)
92 he = gethostbyname(buff);
93 if (he)
94 our_addr = *(struct in_addr *)he->h_addr;
95 if (our_addr.s_addr == 0)
96 our_addr.s_addr = loopback_addr.s_addr;
97}
98
99#if SIZEOF_CHAR_P == 8
100
101struct quehead_32 {
102 u_int32_t qh_link;
103 u_int32_t qh_rlink;
104};
105
106void
107insque_32(PNATState pData, void *a, void *b)
108{
109 register struct quehead_32 *element = (struct quehead_32 *) a;
110 register struct quehead_32 *head = (struct quehead_32 *) b;
111 struct quehead_32 *link = u32_to_ptr(pData, head->qh_link, struct quehead_32 *);
112
113 element->qh_link = head->qh_link;
114 element->qh_rlink = ptr_to_u32(pData, head);
115 Assert(link->qh_rlink == element->qh_rlink);
116 link->qh_rlink = head->qh_link = ptr_to_u32(pData, element);
117}
118
119void
120remque_32(PNATState pData, void *a)
121{
122 register struct quehead_32 *element = (struct quehead_32 *) a;
123 struct quehead_32 *link = u32_to_ptr(pData, element->qh_link, struct quehead_32 *);
124 struct quehead_32 *rlink = u32_to_ptr(pData, element->qh_rlink, struct quehead_32 *);
125
126 u32ptr_done(pData, link->qh_rlink, element);
127 link->qh_rlink = element->qh_rlink;
128 rlink->qh_link = element->qh_link;
129 element->qh_rlink = 0;
130}
131
132#endif /* SIZEOF_CHAR_P == 8 */
133
134struct quehead {
135 struct quehead *qh_link;
136 struct quehead *qh_rlink;
137};
138
139void
140insque(PNATState pData, void *a, void *b)
141{
142 register struct quehead *element = (struct quehead *) a;
143 register struct quehead *head = (struct quehead *) b;
144 element->qh_link = head->qh_link;
145 head->qh_link = (struct quehead *)element;
146 element->qh_rlink = (struct quehead *)head;
147 ((struct quehead *)(element->qh_link))->qh_rlink
148 = (struct quehead *)element;
149}
150
151void
152remque(PNATState pData, void *a)
153{
154 register struct quehead *element = (struct quehead *) a;
155 ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
156 ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
157 element->qh_rlink = NULL;
158 /* element->qh_link = NULL; TCP FIN1 crashes if you do this. Why ? */
159}
160
161/* #endif */
162
163
164int
165add_exec(ex_ptr, do_pty, exec, addr, port)
166 struct ex_list **ex_ptr;
167 int do_pty;
168 char *exec;
169 int addr;
170 int port;
171{
172 struct ex_list *tmp_ptr;
173
174 /* First, check if the port is "bound" */
175 for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
176 if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr)
177 return -1;
178 }
179
180 tmp_ptr = *ex_ptr;
181 *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list));
182 (*ex_ptr)->ex_fport = port;
183 (*ex_ptr)->ex_addr = addr;
184 (*ex_ptr)->ex_pty = do_pty;
185 (*ex_ptr)->ex_exec = strdup(exec);
186 (*ex_ptr)->ex_next = tmp_ptr;
187 return 0;
188}
189
190#ifndef HAVE_STRERROR
191
192/*
193 * For systems with no strerror
194 */
195
196extern int sys_nerr;
197extern char *sys_errlist[];
198
199char *
200strerror(error)
201 int error;
202{
203 if (error < sys_nerr)
204 return sys_errlist[error];
205 else
206 return "Unknown error.";
207}
208
209#endif
210
211
212#ifdef _WIN32
213
214int
215fork_exec(PNATState pData, struct socket *so, char *ex, int do_pty)
216{
217 /* not implemented */
218 return 0;
219}
220
221#else
222
223/*
224 * XXX This is ugly
225 * We create and bind a socket, then fork off to another
226 * process, which connects to this socket, after which we
227 * exec the wanted program. If something (strange) happens,
228 * the accept() call could block us forever.
229 *
230 * do_pty = 0 Fork/exec inetd style
231 * do_pty = 1 Fork/exec using slirp.telnetd
232 * do_ptr = 2 Fork/exec using pty
233 */
234int
235fork_exec(PNATState pData, struct socket *so, char *ex, int do_pty)
236{
237 int s;
238 struct sockaddr_in addr;
239 socklen_t addrlen = sizeof(addr);
240 int opt;
241 int master;
242 char *argv[256];
243#if 0
244 char buff[256];
245#endif
246 /* don't want to clobber the original */
247 char *bptr;
248 char *curarg;
249 int c, i, ret;
250
251 DEBUG_CALL("fork_exec");
252 DEBUG_ARG("so = %lx", (long)so);
253 DEBUG_ARG("ex = %lx", (long)ex);
254 DEBUG_ARG("do_pty = %lx", (long)do_pty);
255
256 if (do_pty == 2) {
257 AssertRelease(do_pty != 2);
258 /* shut up gcc */
259 s = 0;
260 master = 0;
261 } else {
262 addr.sin_family = AF_INET;
263 addr.sin_port = 0;
264 addr.sin_addr.s_addr = INADDR_ANY;
265
266 if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
267 bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
268 listen(s, 1) < 0) {
269 lprint("Error: inet socket: %s\n", strerror(errno));
270 closesocket(s);
271
272 return 0;
273 }
274 }
275
276 switch(fork()) {
277 case -1:
278 lprint("Error: fork failed: %s\n", strerror(errno));
279 close(s);
280 if (do_pty == 2)
281 close(master);
282 return 0;
283
284 case 0:
285 /* Set the DISPLAY */
286 if (do_pty == 2) {
287 (void) close(master);
288#ifdef TIOCSCTTY /* XXXXX */
289 (void) setsid();
290 ioctl(s, TIOCSCTTY, (char *)NULL);
291#endif
292 } else {
293 getsockname(s, (struct sockaddr *)&addr, &addrlen);
294 close(s);
295 /*
296 * Connect to the socket
297 * XXX If any of these fail, we're in trouble!
298 */
299 s = socket(AF_INET, SOCK_STREAM, 0);
300 addr.sin_addr = loopback_addr;
301 do {
302 ret = connect(s, (struct sockaddr *)&addr, addrlen);
303 } while (ret < 0 && errno == EINTR);
304 }
305
306#if 0
307 if (x_port >= 0) {
308#ifdef HAVE_SETENV
309 sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
310 setenv("DISPLAY", buff, 1);
311#else
312 sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
313 putenv(buff);
314#endif
315 }
316#endif
317 dup2(s, 0);
318 dup2(s, 1);
319 dup2(s, 2);
320 for (s = 3; s <= 255; s++)
321 close(s);
322
323 i = 0;
324 bptr = strdup(ex); /* No need to free() this */
325 if (do_pty == 1) {
326 /* Setup "slirp.telnetd -x" */
327 argv[i++] = "slirp.telnetd";
328 argv[i++] = "-x";
329 argv[i++] = bptr;
330 } else
331 do {
332 /* Change the string into argv[] */
333 curarg = bptr;
334 while (*bptr != ' ' && *bptr != (char)0)
335 bptr++;
336 c = *bptr;
337 *bptr++ = (char)0;
338 argv[i++] = strdup(curarg);
339 } while (c);
340
341 argv[i] = 0;
342 execvp(argv[0], argv);
343
344 /* Ooops, failed, let's tell the user why */
345 {
346 char buff[256];
347
348 sprintf(buff, "Error: execvp of %s failed: %s\n",
349 argv[0], strerror(errno));
350 write(2, buff, strlen(buff)+1);
351 }
352 close(0); close(1); close(2); /* XXX */
353 exit(1);
354
355 default:
356 if (do_pty == 2) {
357 close(s);
358 so->s = master;
359 } else {
360 /*
361 * XXX this could block us...
362 * XXX Should set a timer here, and if accept() doesn't
363 * return after X seconds, declare it a failure
364 * The only reason this will block forever is if socket()
365 * of connect() fail in the child process
366 */
367 do {
368 so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
369 } while (so->s < 0 && errno == EINTR);
370 closesocket(s);
371 opt = 1;
372 setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
373 opt = 1;
374 setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
375 }
376 fd_nonblock(so->s);
377
378 /* Append the telnet options now */
379 if (so->so_m != 0 && do_pty == 1) {
380 sbappend(pData, so, so->so_m);
381 so->so_m = 0;
382 }
383
384 return 1;
385 }
386}
387#endif
388
389#ifndef HAVE_STRDUP
390char *
391strdup(str)
392 const char *str;
393{
394 char *bptr;
395
396 bptr = (char *)malloc(strlen(str)+1);
397 strcpy(bptr, str);
398
399 return bptr;
400}
401#endif
402
403#if 0
404void
405snooze_hup(num)
406 int num;
407{
408 int s, ret;
409#ifndef NO_UNIX_SOCKETS
410 struct sockaddr_un sock_un;
411#endif
412 struct sockaddr_in sock_in;
413 char buff[256];
414
415 ret = -1;
416 if (slirp_socket_passwd) {
417 s = socket(AF_INET, SOCK_STREAM, 0);
418 if (s < 0)
419 slirp_exit(1);
420 sock_in.sin_family = AF_INET;
421 sock_in.sin_addr.s_addr = slirp_socket_addr;
422 sock_in.sin_port = htons(slirp_socket_port);
423 if (connect(s, (struct sockaddr *)&sock_in, sizeof(sock_in)) != 0)
424 slirp_exit(1); /* just exit...*/
425 sprintf(buff, "kill %s:%d", slirp_socket_passwd, slirp_socket_unit);
426 write(s, buff, strlen(buff)+1);
427 }
428#ifndef NO_UNIX_SOCKETS
429 else {
430 s = socket(AF_UNIX, SOCK_STREAM, 0);
431 if (s < 0)
432 slirp_exit(1);
433 sock_un.sun_family = AF_UNIX;
434 strcpy(sock_un.sun_path, socket_path);
435 if (connect(s, (struct sockaddr *)&sock_un,
436 sizeof(sock_un.sun_family) + sizeof(sock_un.sun_path)) != 0)
437 slirp_exit(1);
438 sprintf(buff, "kill none:%d", slirp_socket_unit);
439 write(s, buff, strlen(buff)+1);
440 }
441#endif
442 slirp_exit(0);
443}
444
445
446void
447snooze()
448{
449 sigset_t s;
450 int i;
451
452 /* Don't need our data anymore */
453 /* XXX This makes SunOS barf */
454/* brk(0); */
455
456 /* Close all fd's */
457 for (i = 255; i >= 0; i--)
458 close(i);
459
460 signal(SIGQUIT, slirp_exit);
461 signal(SIGHUP, snooze_hup);
462 sigemptyset(&s);
463
464 /* Wait for any signal */
465 sigsuspend(&s);
466
467 /* Just in case ... */
468 exit(255);
469}
470
471void
472relay(s)
473 int s;
474{
475 char buf[8192];
476 int n;
477 fd_set readfds;
478 struct ttys *ttyp;
479
480 /* Don't need our data anymore */
481 /* XXX This makes SunOS barf */
482/* brk(0); */
483
484 signal(SIGQUIT, slirp_exit);
485 signal(SIGHUP, slirp_exit);
486 signal(SIGINT, slirp_exit);
487 signal(SIGTERM, slirp_exit);
488
489 /* Fudge to get term_raw and term_restore to work */
490 if (NULL == (ttyp = tty_attach (0, slirp_tty))) {
491 lprint ("Error: tty_attach failed in misc.c:relay()\r\n");
492 slirp_exit (1);
493 }
494 ttyp->fd = 0;
495 ttyp->flags |= TTY_CTTY;
496 term_raw(ttyp);
497
498 while (1) {
499 FD_ZERO(&readfds);
500
501 FD_SET(0, &readfds);
502 FD_SET(s, &readfds);
503
504 n = select(s+1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0);
505
506 if (n <= 0)
507 slirp_exit(0);
508
509 if (FD_ISSET(0, &readfds)) {
510 n = read(0, buf, 8192);
511 if (n <= 0)
512 slirp_exit(0);
513 n = writen(s, buf, n);
514 if (n <= 0)
515 slirp_exit(0);
516 }
517
518 if (FD_ISSET(s, &readfds)) {
519 n = read(s, buf, 8192);
520 if (n <= 0)
521 slirp_exit(0);
522 n = writen(0, buf, n);
523 if (n <= 0)
524 slirp_exit(0);
525 }
526 }
527
528 /* Just in case.... */
529 exit(1);
530}
531#endif
532
533#ifdef BAD_SPRINTF
534
535#undef vsprintf
536#undef sprintf
537
538/*
539 * Some BSD-derived systems have a sprintf which returns char *
540 */
541
542int
543vsprintf_len(string, format, args)
544 char *string;
545 const char *format;
546 va_list args;
547{
548 vsprintf(string, format, args);
549 return strlen(string);
550}
551
552int
553#ifdef __STDC__
554sprintf_len(char *string, const char *format, ...)
555#else
556sprintf_len(va_alist) va_dcl
557#endif
558{
559 va_list args;
560#ifdef __STDC__
561 va_start(args, format);
562#else
563 char *string;
564 char *format;
565 va_start(args);
566 string = va_arg(args, char *);
567 format = va_arg(args, char *);
568#endif
569 vsprintf(string, format, args);
570 return strlen(string);
571}
572
573#endif
574
575void
576u_sleep(usec)
577 int usec;
578{
579 struct timeval t;
580 fd_set fdset;
581
582 FD_ZERO(&fdset);
583
584 t.tv_sec = 0;
585 t.tv_usec = usec * 1000;
586
587 select(0, &fdset, &fdset, &fdset, &t);
588}
589
590/*
591 * Set fd blocking and non-blocking
592 */
593
594void
595fd_nonblock(fd)
596 int fd;
597{
598#ifdef FIONBIO
599 int opt = 1;
600
601 ioctlsocket(fd, FIONBIO, &opt);
602#else
603 int opt;
604
605 opt = fcntl(fd, F_GETFL, 0);
606 opt |= O_NONBLOCK;
607 fcntl(fd, F_SETFL, opt);
608#endif
609}
610
611void
612fd_block(fd)
613 int fd;
614{
615#ifdef FIONBIO
616 int opt = 0;
617
618 ioctlsocket(fd, FIONBIO, &opt);
619#else
620 int opt;
621
622 opt = fcntl(fd, F_GETFL, 0);
623 opt &= ~O_NONBLOCK;
624 fcntl(fd, F_SETFL, opt);
625#endif
626}
627
628
629#if 0
630/*
631 * invoke RSH
632 */
633int
634rsh_exec(so,ns, user, host, args)
635 struct socket *so;
636 struct socket *ns;
637 char *user;
638 char *host;
639 char *args;
640{
641 int fd[2];
642 int fd0[2];
643 int s;
644 char buff[256];
645
646 DEBUG_CALL("rsh_exec");
647 DEBUG_ARG("so = %lx", (long)so);
648
649 if (pipe(fd)<0) {
650 lprint("Error: pipe failed: %s\n", strerror(errno));
651 return 0;
652 }
653/* #ifdef HAVE_SOCKETPAIR */
654#if 1
655 if (socketpair(PF_UNIX,SOCK_STREAM,0, fd0) == -1) {
656 close(fd[0]);
657 close(fd[1]);
658 lprint("Error: openpty failed: %s\n", strerror(errno));
659 return 0;
660 }
661#else
662 if (slirp_openpty(&fd0[0], &fd0[1]) == -1) {
663 close(fd[0]);
664 close(fd[1]);
665 lprint("Error: openpty failed: %s\n", strerror(errno));
666 return 0;
667 }
668#endif
669
670 switch(fork()) {
671 case -1:
672 lprint("Error: fork failed: %s\n", strerror(errno));
673 close(fd[0]);
674 close(fd[1]);
675 close(fd0[0]);
676 close(fd0[1]);
677 return 0;
678
679 case 0:
680 close(fd[0]);
681 close(fd0[0]);
682
683 /* Set the DISPLAY */
684 if (x_port >= 0) {
685#ifdef HAVE_SETENV
686 sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
687 setenv("DISPLAY", buff, 1);
688#else
689 sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
690 putenv(buff);
691#endif
692 }
693
694 dup2(fd0[1], 0);
695 dup2(fd0[1], 1);
696 dup2(fd[1], 2);
697 for (s = 3; s <= 255; s++)
698 close(s);
699
700 execlp("rsh","rsh","-l", user, host, args, NULL);
701
702 /* Ooops, failed, let's tell the user why */
703
704 sprintf(buff, "Error: execlp of %s failed: %s\n",
705 "rsh", strerror(errno));
706 write(2, buff, strlen(buff)+1);
707 close(0); close(1); close(2); /* XXX */
708 exit(1);
709
710 default:
711 close(fd[1]);
712 close(fd0[1]);
713 ns->s=fd[0];
714 so->s=fd0[0];
715
716 return 1;
717 }
718}
719#endif
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette