net: always walk through filters in reverse if traffic is egress
[qemu/ar7.git] / slirp / socket.c
blobf7e596859febfce5c4a647088da50a7cc60ed6c4
1 /*
2 * Copyright (c) 1995 Danny Gasparovski.
4 * Please read the file COPYRIGHT for the
5 * terms and conditions of the copyright.
6 */
8 #include "qemu-common.h"
9 #include <slirp.h>
10 #include "ip_icmp.h"
11 #ifdef __sun__
12 #include <sys/filio.h>
13 #endif
15 static void sofcantrcvmore(struct socket *so);
16 static void sofcantsendmore(struct socket *so);
18 struct socket *solookup(struct socket **last, struct socket *head,
19 struct sockaddr_storage *lhost, struct sockaddr_storage *fhost)
21 struct socket *so = *last;
23 /* Optimisation */
24 if (so != head && sockaddr_equal(&(so->lhost.ss), lhost)
25 && (!fhost || sockaddr_equal(&so->fhost.ss, fhost))) {
26 return so;
29 for (so = head->so_next; so != head; so = so->so_next) {
30 if (sockaddr_equal(&(so->lhost.ss), lhost)
31 && (!fhost || sockaddr_equal(&so->fhost.ss, fhost))) {
32 *last = so;
33 return so;
37 return (struct socket *)NULL;
41 * Create a new socket, initialise the fields
42 * It is the responsibility of the caller to
43 * insque() it into the correct linked-list
45 struct socket *
46 socreate(Slirp *slirp)
48 struct socket *so;
50 so = (struct socket *)malloc(sizeof(struct socket));
51 if(so) {
52 memset(so, 0, sizeof(struct socket));
53 so->so_state = SS_NOFDREF;
54 so->s = -1;
55 so->slirp = slirp;
56 so->pollfds_idx = -1;
58 return(so);
62 * remque and free a socket, clobber cache
64 void
65 sofree(struct socket *so)
67 Slirp *slirp = so->slirp;
69 if (so->so_emu==EMU_RSH && so->extra) {
70 sofree(so->extra);
71 so->extra=NULL;
73 if (so == slirp->tcp_last_so) {
74 slirp->tcp_last_so = &slirp->tcb;
75 } else if (so == slirp->udp_last_so) {
76 slirp->udp_last_so = &slirp->udb;
77 } else if (so == slirp->icmp_last_so) {
78 slirp->icmp_last_so = &slirp->icmp;
80 m_free(so->so_m);
82 if(so->so_next && so->so_prev)
83 remque(so); /* crashes if so is not in a queue */
85 free(so);
88 size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np)
90 int n, lss, total;
91 struct sbuf *sb = &so->so_snd;
92 int len = sb->sb_datalen - sb->sb_cc;
93 int mss = so->so_tcpcb->t_maxseg;
95 DEBUG_CALL("sopreprbuf");
96 DEBUG_ARG("so = %p", so);
98 if (len <= 0)
99 return 0;
101 iov[0].iov_base = sb->sb_wptr;
102 iov[1].iov_base = NULL;
103 iov[1].iov_len = 0;
104 if (sb->sb_wptr < sb->sb_rptr) {
105 iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
106 /* Should never succeed, but... */
107 if (iov[0].iov_len > len)
108 iov[0].iov_len = len;
109 if (iov[0].iov_len > mss)
110 iov[0].iov_len -= iov[0].iov_len%mss;
111 n = 1;
112 } else {
113 iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
114 /* Should never succeed, but... */
115 if (iov[0].iov_len > len) iov[0].iov_len = len;
116 len -= iov[0].iov_len;
117 if (len) {
118 iov[1].iov_base = sb->sb_data;
119 iov[1].iov_len = sb->sb_rptr - sb->sb_data;
120 if(iov[1].iov_len > len)
121 iov[1].iov_len = len;
122 total = iov[0].iov_len + iov[1].iov_len;
123 if (total > mss) {
124 lss = total%mss;
125 if (iov[1].iov_len > lss) {
126 iov[1].iov_len -= lss;
127 n = 2;
128 } else {
129 lss -= iov[1].iov_len;
130 iov[0].iov_len -= lss;
131 n = 1;
133 } else
134 n = 2;
135 } else {
136 if (iov[0].iov_len > mss)
137 iov[0].iov_len -= iov[0].iov_len%mss;
138 n = 1;
141 if (np)
142 *np = n;
144 return iov[0].iov_len + (n - 1) * iov[1].iov_len;
148 * Read from so's socket into sb_snd, updating all relevant sbuf fields
149 * NOTE: This will only be called if it is select()ed for reading, so
150 * a read() of 0 (or less) means it's disconnected
153 soread(struct socket *so)
155 int n, nn;
156 struct sbuf *sb = &so->so_snd;
157 struct iovec iov[2];
159 DEBUG_CALL("soread");
160 DEBUG_ARG("so = %p", so);
163 * No need to check if there's enough room to read.
164 * soread wouldn't have been called if there weren't
166 sopreprbuf(so, iov, &n);
168 #ifdef HAVE_READV
169 nn = readv(so->s, (struct iovec *)iov, n);
170 DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
171 #else
172 nn = qemu_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
173 #endif
174 if (nn <= 0) {
175 if (nn < 0 && (errno == EINTR || errno == EAGAIN))
176 return 0;
177 else {
178 DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno)));
179 sofcantrcvmore(so);
180 tcp_sockclosed(sototcpcb(so));
181 return -1;
185 #ifndef HAVE_READV
187 * If there was no error, try and read the second time round
188 * We read again if n = 2 (ie, there's another part of the buffer)
189 * and we read as much as we could in the first read
190 * We don't test for <= 0 this time, because there legitimately
191 * might not be any more data (since the socket is non-blocking),
192 * a close will be detected on next iteration.
193 * A return of -1 wont (shouldn't) happen, since it didn't happen above
195 if (n == 2 && nn == iov[0].iov_len) {
196 int ret;
197 ret = qemu_recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
198 if (ret > 0)
199 nn += ret;
202 DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
203 #endif
205 /* Update fields */
206 sb->sb_cc += nn;
207 sb->sb_wptr += nn;
208 if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
209 sb->sb_wptr -= sb->sb_datalen;
210 return nn;
213 int soreadbuf(struct socket *so, const char *buf, int size)
215 int n, nn, copy = size;
216 struct sbuf *sb = &so->so_snd;
217 struct iovec iov[2];
219 DEBUG_CALL("soreadbuf");
220 DEBUG_ARG("so = %p", so);
223 * No need to check if there's enough room to read.
224 * soread wouldn't have been called if there weren't
226 if (sopreprbuf(so, iov, &n) < size)
227 goto err;
229 nn = MIN(iov[0].iov_len, copy);
230 memcpy(iov[0].iov_base, buf, nn);
232 copy -= nn;
233 buf += nn;
235 if (copy == 0)
236 goto done;
238 memcpy(iov[1].iov_base, buf, copy);
240 done:
241 /* Update fields */
242 sb->sb_cc += size;
243 sb->sb_wptr += size;
244 if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
245 sb->sb_wptr -= sb->sb_datalen;
246 return size;
247 err:
249 sofcantrcvmore(so);
250 tcp_sockclosed(sototcpcb(so));
251 fprintf(stderr, "soreadbuf buffer to small");
252 return -1;
256 * Get urgent data
258 * When the socket is created, we set it SO_OOBINLINE,
259 * so when OOB data arrives, we soread() it and everything
260 * in the send buffer is sent as urgent data
262 void
263 sorecvoob(struct socket *so)
265 struct tcpcb *tp = sototcpcb(so);
267 DEBUG_CALL("sorecvoob");
268 DEBUG_ARG("so = %p", so);
271 * We take a guess at how much urgent data has arrived.
272 * In most situations, when urgent data arrives, the next
273 * read() should get all the urgent data. This guess will
274 * be wrong however if more data arrives just after the
275 * urgent data, or the read() doesn't return all the
276 * urgent data.
278 soread(so);
279 tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
280 tp->t_force = 1;
281 tcp_output(tp);
282 tp->t_force = 0;
286 * Send urgent data
287 * There's a lot duplicated code here, but...
290 sosendoob(struct socket *so)
292 struct sbuf *sb = &so->so_rcv;
293 char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
295 int n, len;
297 DEBUG_CALL("sosendoob");
298 DEBUG_ARG("so = %p", so);
299 DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
301 if (so->so_urgc > 2048)
302 so->so_urgc = 2048; /* XXXX */
304 if (sb->sb_rptr < sb->sb_wptr) {
305 /* We can send it directly */
306 n = slirp_send(so, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
307 so->so_urgc -= n;
309 DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
310 } else {
312 * Since there's no sendv or sendtov like writev,
313 * we must copy all data to a linear buffer then
314 * send it all
316 len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
317 if (len > so->so_urgc) len = so->so_urgc;
318 memcpy(buff, sb->sb_rptr, len);
319 so->so_urgc -= len;
320 if (so->so_urgc) {
321 n = sb->sb_wptr - sb->sb_data;
322 if (n > so->so_urgc) n = so->so_urgc;
323 memcpy((buff + len), sb->sb_data, n);
324 so->so_urgc -= n;
325 len += n;
327 n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
328 #ifdef DEBUG
329 if (n != len)
330 DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
331 #endif
332 DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
335 sb->sb_cc -= n;
336 sb->sb_rptr += n;
337 if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
338 sb->sb_rptr -= sb->sb_datalen;
340 return n;
344 * Write data from so_rcv to so's socket,
345 * updating all sbuf field as necessary
348 sowrite(struct socket *so)
350 int n,nn;
351 struct sbuf *sb = &so->so_rcv;
352 int len = sb->sb_cc;
353 struct iovec iov[2];
355 DEBUG_CALL("sowrite");
356 DEBUG_ARG("so = %p", so);
358 if (so->so_urgc) {
359 sosendoob(so);
360 if (sb->sb_cc == 0)
361 return 0;
365 * No need to check if there's something to write,
366 * sowrite wouldn't have been called otherwise
369 iov[0].iov_base = sb->sb_rptr;
370 iov[1].iov_base = NULL;
371 iov[1].iov_len = 0;
372 if (sb->sb_rptr < sb->sb_wptr) {
373 iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
374 /* Should never succeed, but... */
375 if (iov[0].iov_len > len) iov[0].iov_len = len;
376 n = 1;
377 } else {
378 iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
379 if (iov[0].iov_len > len) iov[0].iov_len = len;
380 len -= iov[0].iov_len;
381 if (len) {
382 iov[1].iov_base = sb->sb_data;
383 iov[1].iov_len = sb->sb_wptr - sb->sb_data;
384 if (iov[1].iov_len > len) iov[1].iov_len = len;
385 n = 2;
386 } else
387 n = 1;
389 /* Check if there's urgent data to send, and if so, send it */
391 #ifdef HAVE_READV
392 nn = writev(so->s, (const struct iovec *)iov, n);
394 DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
395 #else
396 nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);
397 #endif
398 /* This should never happen, but people tell me it does *shrug* */
399 if (nn < 0 && (errno == EAGAIN || errno == EINTR))
400 return 0;
402 if (nn <= 0) {
403 DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
404 so->so_state, errno));
405 sofcantsendmore(so);
406 tcp_sockclosed(sototcpcb(so));
407 return -1;
410 #ifndef HAVE_READV
411 if (n == 2 && nn == iov[0].iov_len) {
412 int ret;
413 ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);
414 if (ret > 0)
415 nn += ret;
417 DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
418 #endif
420 /* Update sbuf */
421 sb->sb_cc -= nn;
422 sb->sb_rptr += nn;
423 if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
424 sb->sb_rptr -= sb->sb_datalen;
427 * If in DRAIN mode, and there's no more data, set
428 * it CANTSENDMORE
430 if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
431 sofcantsendmore(so);
433 return nn;
437 * recvfrom() a UDP socket
439 void
440 sorecvfrom(struct socket *so)
442 struct sockaddr_storage addr;
443 struct sockaddr_storage saddr, daddr;
444 socklen_t addrlen = sizeof(struct sockaddr_storage);
446 DEBUG_CALL("sorecvfrom");
447 DEBUG_ARG("so = %p", so);
449 if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */
450 char buff[256];
451 int len;
453 len = recvfrom(so->s, buff, 256, 0,
454 (struct sockaddr *)&addr, &addrlen);
455 /* XXX Check if reply is "correct"? */
457 if(len == -1 || len == 0) {
458 u_char code=ICMP_UNREACH_PORT;
460 if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
461 else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
463 DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
464 errno,strerror(errno)));
465 icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
466 } else {
467 icmp_reflect(so->so_m);
468 so->so_m = NULL; /* Don't m_free() it again! */
470 /* No need for this socket anymore, udp_detach it */
471 udp_detach(so);
472 } else { /* A "normal" UDP packet */
473 struct mbuf *m;
474 int len;
475 #ifdef _WIN32
476 unsigned long n;
477 #else
478 int n;
479 #endif
481 m = m_get(so->slirp);
482 if (!m) {
483 return;
485 m->m_data += IF_MAXLINKHDR;
488 * XXX Shouldn't FIONREAD packets destined for port 53,
489 * but I don't know the max packet size for DNS lookups
491 len = M_FREEROOM(m);
492 /* if (so->so_fport != htons(53)) { */
493 ioctlsocket(so->s, FIONREAD, &n);
495 if (n > len) {
496 n = (m->m_data - m->m_dat) + m->m_len + n + 1;
497 m_inc(m, n);
498 len = M_FREEROOM(m);
500 /* } */
502 m->m_len = recvfrom(so->s, m->m_data, len, 0,
503 (struct sockaddr *)&addr, &addrlen);
504 DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
505 m->m_len, errno,strerror(errno)));
506 if(m->m_len<0) {
507 u_char code=ICMP_UNREACH_PORT;
509 if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
510 else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
512 DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
513 icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
514 m_free(m);
515 } else {
517 * Hack: domain name lookup will be used the most for UDP,
518 * and since they'll only be used once there's no need
519 * for the 4 minute (or whatever) timeout... So we time them
520 * out much quicker (10 seconds for now...)
522 if (so->so_expire) {
523 if (so->so_fport == htons(53))
524 so->so_expire = curtime + SO_EXPIREFAST;
525 else
526 so->so_expire = curtime + SO_EXPIRE;
530 * If this packet was destined for CTL_ADDR,
531 * make it look like that's where it came from
533 saddr = addr;
534 sotranslate_in(so, &saddr);
535 daddr = so->lhost.ss;
537 switch (so->so_ffamily) {
538 case AF_INET:
539 udp_output(so, m, (struct sockaddr_in *) &saddr,
540 (struct sockaddr_in *) &daddr,
541 so->so_iptos);
542 break;
543 default:
544 break;
546 } /* rx error */
547 } /* if ping packet */
551 * sendto() a socket
554 sosendto(struct socket *so, struct mbuf *m)
556 int ret;
557 struct sockaddr_storage addr;
559 DEBUG_CALL("sosendto");
560 DEBUG_ARG("so = %p", so);
561 DEBUG_ARG("m = %p", m);
563 addr = so->fhost.ss;
564 DEBUG_CALL(" sendto()ing)");
565 sotranslate_out(so, &addr);
567 /* Don't care what port we get */
568 ret = sendto(so->s, m->m_data, m->m_len, 0,
569 (struct sockaddr *)&addr, sizeof(addr));
570 if (ret < 0)
571 return -1;
574 * Kill the socket if there's no reply in 4 minutes,
575 * but only if it's an expirable socket
577 if (so->so_expire)
578 so->so_expire = curtime + SO_EXPIRE;
579 so->so_state &= SS_PERSISTENT_MASK;
580 so->so_state |= SS_ISFCONNECTED; /* So that it gets select()ed */
581 return 0;
585 * Listen for incoming TCP connections
587 struct socket *
588 tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
589 u_int lport, int flags)
591 struct sockaddr_in addr;
592 struct socket *so;
593 int s, opt = 1;
594 socklen_t addrlen = sizeof(addr);
595 memset(&addr, 0, addrlen);
597 DEBUG_CALL("tcp_listen");
598 DEBUG_ARG("haddr = %x", haddr);
599 DEBUG_ARG("hport = %d", hport);
600 DEBUG_ARG("laddr = %x", laddr);
601 DEBUG_ARG("lport = %d", lport);
602 DEBUG_ARG("flags = %x", flags);
604 so = socreate(slirp);
605 if (!so) {
606 return NULL;
609 /* Don't tcp_attach... we don't need so_snd nor so_rcv */
610 if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
611 free(so);
612 return NULL;
614 insque(so, &slirp->tcb);
617 * SS_FACCEPTONCE sockets must time out.
619 if (flags & SS_FACCEPTONCE)
620 so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
622 so->so_state &= SS_PERSISTENT_MASK;
623 so->so_state |= (SS_FACCEPTCONN | flags);
624 so->so_lfamily = AF_INET;
625 so->so_lport = lport; /* Kept in network format */
626 so->so_laddr.s_addr = laddr; /* Ditto */
628 addr.sin_family = AF_INET;
629 addr.sin_addr.s_addr = haddr;
630 addr.sin_port = hport;
632 if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
633 (socket_set_fast_reuse(s) < 0) ||
634 (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
635 (listen(s,1) < 0)) {
636 int tmperrno = errno; /* Don't clobber the real reason we failed */
638 close(s);
639 sofree(so);
640 /* Restore the real errno */
641 #ifdef _WIN32
642 WSASetLastError(tmperrno);
643 #else
644 errno = tmperrno;
645 #endif
646 return NULL;
648 qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
650 getsockname(s,(struct sockaddr *)&addr,&addrlen);
651 so->so_ffamily = AF_INET;
652 so->so_fport = addr.sin_port;
653 if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
654 so->so_faddr = slirp->vhost_addr;
655 else
656 so->so_faddr = addr.sin_addr;
658 so->s = s;
659 return so;
663 * Various session state calls
664 * XXX Should be #define's
665 * The socket state stuff needs work, these often get call 2 or 3
666 * times each when only 1 was needed
668 void
669 soisfconnecting(struct socket *so)
671 so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE|
672 SS_FCANTSENDMORE|SS_FWDRAIN);
673 so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
676 void
677 soisfconnected(struct socket *so)
679 so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF);
680 so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
683 static void
684 sofcantrcvmore(struct socket *so)
686 if ((so->so_state & SS_NOFDREF) == 0) {
687 shutdown(so->s,0);
689 so->so_state &= ~(SS_ISFCONNECTING);
690 if (so->so_state & SS_FCANTSENDMORE) {
691 so->so_state &= SS_PERSISTENT_MASK;
692 so->so_state |= SS_NOFDREF; /* Don't select it */
693 } else {
694 so->so_state |= SS_FCANTRCVMORE;
698 static void
699 sofcantsendmore(struct socket *so)
701 if ((so->so_state & SS_NOFDREF) == 0) {
702 shutdown(so->s,1); /* send FIN to fhost */
704 so->so_state &= ~(SS_ISFCONNECTING);
705 if (so->so_state & SS_FCANTRCVMORE) {
706 so->so_state &= SS_PERSISTENT_MASK;
707 so->so_state |= SS_NOFDREF; /* as above */
708 } else {
709 so->so_state |= SS_FCANTSENDMORE;
714 * Set write drain mode
715 * Set CANTSENDMORE once all data has been write()n
717 void
718 sofwdrain(struct socket *so)
720 if (so->so_rcv.sb_cc)
721 so->so_state |= SS_FWDRAIN;
722 else
723 sofcantsendmore(so);
727 * Translate addr in host addr when it is a virtual address
729 void sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
731 Slirp *slirp = so->slirp;
732 struct sockaddr_in *sin = (struct sockaddr_in *)addr;
734 switch (addr->ss_family) {
735 case AF_INET:
736 if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
737 slirp->vnetwork_addr.s_addr) {
738 /* It's an alias */
739 if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
740 if (get_dns_addr(&sin->sin_addr) < 0) {
741 sin->sin_addr = loopback_addr;
743 } else {
744 sin->sin_addr = loopback_addr;
748 DEBUG_MISC((dfd, " addr.sin_port=%d, "
749 "addr.sin_addr.s_addr=%.16s\n",
750 ntohs(sin->sin_port), inet_ntoa(sin->sin_addr)));
751 break;
753 default:
754 break;
758 void sotranslate_in(struct socket *so, struct sockaddr_storage *addr)
760 Slirp *slirp = so->slirp;
761 struct sockaddr_in *sin = (struct sockaddr_in *)addr;
763 switch (addr->ss_family) {
764 case AF_INET:
765 if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
766 slirp->vnetwork_addr.s_addr) {
767 uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
769 if ((so->so_faddr.s_addr & inv_mask) == inv_mask) {
770 sin->sin_addr = slirp->vhost_addr;
771 } else if (sin->sin_addr.s_addr == loopback_addr.s_addr ||
772 so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
773 sin->sin_addr = so->so_faddr;
776 break;
778 default:
779 break;
784 * Translate connections from localhost to the real hostname
786 void sotranslate_accept(struct socket *so)
788 Slirp *slirp = so->slirp;
790 switch (so->so_ffamily) {
791 case AF_INET:
792 if (so->so_faddr.s_addr == INADDR_ANY ||
793 (so->so_faddr.s_addr & loopback_mask) ==
794 (loopback_addr.s_addr & loopback_mask)) {
795 so->so_faddr = slirp->vhost_addr;
797 break;
799 default:
800 break;