slirp.c revision b895bb5ba480cbdcd7abe96183427d61bd56a3d0
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync polls[so->so_poll_index].events |= N_(fdset ## _poll); \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync break; /* out of this loop */ \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertRelease(poll_index >= 0 && poll_index < (nfds)); \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_ENGAGE_EVENT2(so, fdset1, fdset2, label) \
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync break; /* out of this loop */ \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_POLL_EVENTS(rc, error, so, events, label) do {} while (0)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_CHECK_FD_SET(so, events, fdset) ( ((so)->so_poll_index != -1) \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync && (polls[(so)->so_poll_index].revents & N_(fdset ## _poll)))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_UNIX_CHECK_FD_SET(so, events, fdset ) DO_CHECK_FD_SET((so), (events), fdset) /*specific for Unix API */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_WIN_CHECK_FD_SET(so, events, fdset ) 0 /* specific for Windows Winsock API */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync } while (0)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# else /* !RT_OS_WINDOWS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_WIN_CHECK_FD_SET(so, events, fdset ) DO_CHECK_FD_SET((so), (events), fdset)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define ICMP_ENGAGE_EVENT(so, fdset) do {} while(0)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#endif /* RT_OS_WINDOWS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#else /* defined(RT_OS_WINDOWS) */
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync * On Windows, we will be notified by IcmpSendEcho2() when the response arrives.
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * So no call to WSAEventSelect necessary.
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define ICMP_ENGAGE_EVENT(so, fdset) do {} while(0)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync rc = WSAEventSelect((so)->s, VBOX_SOCKET_EVENT, FD_ALL_EVENTS); \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* This should not happen */ \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync LogRel(("WSAEventSelect (" #label ") error %d (so=%x, socket=%s, event=%x)\n", \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync } while(0); \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_ENGAGE_EVENT2(so, fdset1, fdset2, label) \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_POLL_EVENTS(rc, error, so, events, label) \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync (rc) = WSAEnumNetworkEvents((so)->s, VBOX_SOCKET_EVENT, (events)); \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync LogRel(("WSAEnumNetworkEvents " #label " error %d\n", (error))); \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync (((events).lNetworkEvents & fdset ## _win) && ((events).iErrorCode[fdset ## _win_bit] == 0))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_WIN_CHECK_FD_SET(so, events, fdset ) DO_CHECK_FD_SET((so), (events), fdset)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_UNIX_CHECK_FD_SET(so, events, fdset ) 1 /*specific for Unix API */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#endif /* defined(RT_OS_WINDOWS) */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Loging macros
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_LOG_NAT_SOCK(so, proto, winevent, r_fdset, w_fdset, x_fdset) \
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync LogRel((" " #proto " %R[natsock] %R[natwinnetevents]\n", (so), (winevent))); \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync } while (0)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# else /* RT_OS_WINDOWS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_LOG_NAT_SOCK(so, proto, winevent, r_fdset, w_fdset, x_fdset) \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync LogRel((" " #proto " %R[natsock] %s %s %s er: %s, %s, %s\n", (so), \
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync } while (0)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# endif /* !RT_OS_WINDOWS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#else /* VBOX_WITH_DEBUG_NAT_SOCKETS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define DO_LOG_NAT_SOCK(so, proto, winevent, r_fdset, w_fdset, x_fdset) do {} while (0)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#endif /* !VBOX_WITH_DEBUG_NAT_SOCKETS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#define LOG_NAT_SOCK(so, proto, winevent, r_fdset, w_fdset, x_fdset) DO_LOG_NAT_SOCK((so), proto, (winevent), r_fdset, w_fdset, x_fdset)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic void acivate_port_forwarding(PNATState, struct ethhdr *);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic uint32_t find_guest_ip(PNATState, uint8_t *);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncstatic int get_dns_addr_domain(PNATState pData, bool fVerbose,
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync const char **ppszDomain)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* Get amount of memory required for operation */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync ULONG flags = GAA_FLAG_INCLUDE_PREFIX; /*GAA_FLAG_INCLUDE_ALL_INTERFACES;*/ /* all interfaces registered in NDIS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* @todo add SKIPing flags to get only required information */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync ret = pData->pfGetAdaptersAddresses(AF_INET, 0, NULL /* reserved */, addresses, &size);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync LogRel(("NAT: error %lu occurred on capacity detection operation\n", ret));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync LogRel(("NAT: Win socket API returns non capacity\n"));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync ret = pData->pfGetAdaptersAddresses(AF_INET, 0, NULL /* reserved */, addresses, &size);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync LogRel(("NAT: error %lu occurred on fetching adapters info\n", ret));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* add dns server to list */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync LogRel(("NAT: Can't allocate buffer for DNS entry\n"));
822e11c896dd36c9dc3609dff676059576b7d3devboxsync LogRel(("NAT: adding %R[IP4] to DNS server list\n", &((struct sockaddr_in *)saddr)->sin_addr));
82391de567696f10b21a762fde6a06fe3c266d28vboxsync if ((((struct sockaddr_in *)saddr)->sin_addr.s_addr & htonl(IN_CLASSA_NET)) == ntohl(INADDR_LOOPBACK & IN_CLASSA_NET)) {
82391de567696f10b21a762fde6a06fe3c266d28vboxsync da->de_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync da->de_addr.s_addr = ((struct sockaddr_in *)saddr)->sin_addr.s_addr;
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync TAILQ_INSERT_HEAD(&pData->dns_list_head, da, de_list);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync LIST_FOREACH(dd, &pData->dns_domain_list_head, dd_list)
822e11c896dd36c9dc3609dff676059576b7d3devboxsync LogRel(("NAT: adding domain name %s to search list\n", dd->dd_pszDomain));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync LIST_INSERT_HEAD(&pData->dns_domain_list_head, dd, dd_list);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync#else /* !RT_OS_WINDOWS */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsyncstatic int get_dns_addr_domain(PNATState pData, bool fVerbose,
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync const char **ppszDomain)
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync /* Try various locations. */
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync snprintf(buff, sizeof(buff), "%s/RESOLV2", _PATH_ETC);
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync snprintf(buff, sizeof(buff), "%s/resolv.conf", _PATH_ETC);
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync snprintf(buff, sizeof(buff), "%s/resolv.conf", home);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1)
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync /*localhost mask */
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if ((da->de_addr.s_addr & htonl(IN_CLASSA_NET)) == ntohl(INADDR_LOOPBACK & IN_CLASSA_NET)) {
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync da->de_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync TAILQ_INSERT_HEAD(&pData->dns_list_head, da, de_list);
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if ((!strncmp(buff, "domain", 6) || !strncmp(buff, "search", 6)))
a597f00ac8a71003621fe61c58fe32706ca941b3vboxsync LIST_FOREACH(dd, &pData->dns_domain_list_head, dd_list)
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync LogRel(("NAT: not enought memory to add domain list\n"));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync LogRel(("NAT: adding domain name %s to search list\n", dd->dd_pszDomain));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync LIST_INSERT_HEAD(&pData->dns_domain_list_head, dd, dd_list);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return get_dns_addr_domain(pData, true, NULL, NULL);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncint get_dns_addr(PNATState pData, struct in_addr *pdns_addr)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return get_dns_addr_domain(pData, false, pdns_addr, NULL);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncint slirp_init(PNATState *ppData, const char *pszNetAddr, uint32_t u32Netmask,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncint slirp_init(PNATState *ppData, uint32_t u32NetAddr, uint32_t u32Netmask,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* CTL is x.x.x.15, bootp passes up to 16 IPs (15..31) */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* sockets & TCP defaults */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync pData->phEvents[VBOX_SOCKET_EVENT_INDEX] = CreateEvent(NULL, FALSE, FALSE, NULL);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* Initialise mbufs *after* setting the MTU */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* @todo: add ability to configure this staff */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* set default addresses */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync LogRel(("NAT: LibAlias default rule wasn't initialized\n"));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync AssertMsgFailed(("NAT: LibAlias default rule wasn't initialized\n"));
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync flags = LibAliasSetMode(pData->proxy_alias, flags, ~0);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync proxy_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync LibAliasSetAddress(pData->proxy_alias, proxy_addr);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Register statistics.
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncvoid slirp_register_statistics(PNATState pData, PPDMDRVINS pDrvIns)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync } while (0)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define PROFILE_COUNTER(name, dsc) COUNTER(name, STAMTYPE_PROFILE, STAMUNIT_TICKS_PER_CALL, dsc)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define COUNTING_COUNTER(name, dsc) COUNTER(name, STAMTYPE_COUNTER, STAMUNIT_COUNT, dsc)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync/** @todo register statistics for the variables dumped by:
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * ipstats(pData); tcpstats(pData); udpstats(pData); icmpstats(pData);
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * mbufstats(pData); sockstats(pData); */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#endif /* VBOX_WITH_STATISTICS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Deregister statistics.
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncvoid slirp_deregister_statistics(PNATState pData, PPDMDRVINS pDrvIns)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define PROFILE_COUNTER(name, dsc) PDMDrvHlpSTAMDeregister(pDrvIns, &pData->Stat ## name)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync# define COUNTING_COUNTER(name, dsc) PDMDrvHlpSTAMDeregister(pDrvIns, &pData->Stat ## name)
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync#endif /* VBOX_WITH_STATISTICS */
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync * Marks the link as up, making it possible to establish new connections.
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync * Marks the link as down and cleans up the current connections.
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Terminates the slirp component.
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync /* libalias do all clean up */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync "NAT statistics\n"
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync "--------------\n"
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * curtime kept to an accuracy of 1ms
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#else /* RT_OS_WINDOWS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncvoid slirp_select_fill(PNATState pData, int *pnfds, struct pollfd *polls)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#endif /* !RT_OS_WINDOWS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * First, TCP sockets
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * *_slowtimo needs calling if there are IP fragments
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * in the fragment queue, or there are TCP connections active
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * triggering of fragment expiration should be the same but use new macroses
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync for (i = 0; i < IPREASS_NHASH; i++)
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync * See if we need a tcp_fasttimo
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync time_fasttimo = curtime; /* Flag when we want a fasttimo */
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync * NOFDREF can include still connecting to local-host,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * newly socreated() sockets etc. Don't want to select these.
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Set for reading sockets which are accepting
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Set for writing sockets which are connecting
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync * Set for writing if we are connected, can send more, and
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync * we have something to send
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync * Set for reading (and urgent data) if we are connected, can
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync * receive more, and we have room for it XXX /2 ?
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2)))
2ad9f8a731c73f6ac74044d42d47bbaf6f44a566vboxsync * UDP sockets
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * See if it's timed out
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync /* we need so_next for continue our cycle*/
82391de567696f10b21a762fde6a06fe3c266d28vboxsync * When UDP packets are received from over the link, they're
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * sendto()'d straight away, so no need for setting for writing
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Limit the number of packets queued by this session to 4.
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync * Note that even though we try and limit this to 4 packets,
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * the session could have more queued if the packets needed
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * to be fragmented.
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync * (XXX <= 4 ?)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#else /* RT_OS_WINDOWS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#endif /* !RT_OS_WINDOWS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncvoid slirp_select_poll(PNATState pData, int fTimeout, int fIcmp)
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync#else /* RT_OS_WINDOWS */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsyncvoid slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs)
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync#endif /* !RT_OS_WINDOWS */
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync /* Update time */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * See if anything has timed out
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync if (time_fasttimo && ((curtime - time_fasttimo) >= 2))
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync if (do_slowtimo && ((curtime - last_slowtimo) >= 499))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync return; /* only timer update */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Check sockets
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /*XXX: before renaming please make see define
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync && CHECK_FD_SET(&pData->icmp_socket, ignored, readfds))
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync * Check TCP sockets
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * FD_ISSET is meaningless on these sockets
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * (and they can crash the program)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync LOG_NAT_SOCK(so, TCP, &NetworkEvents, readfds, writefds, xfds);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * Check for URG data
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * This will soread as well, so no need to
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * test for readfds below if this succeeds
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* out-of-band data */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * Check sockets for reading
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * Check for incoming connections
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* Output it if we read something */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * Check for FD_CLOSE events.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * in some cases once FD_CLOSE engaged on socket it could be flashed latter (for some reasons)
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * drain the socket
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * Check sockets for writing
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * Check for non-blocking, still-connecting sockets
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* Connected */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * This should be probably guarded by PROBE_CONN too. Anyway,
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * we disable it on OS/2 because the below send call returns
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * EFAULT which causes the opened TCP socket to close right
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * after it has been opened and connected.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* XXXXX Must fix, zero bytes is a NOP */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* else failed */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* else so->so_state &= ~SS_ISFCONNECTING; */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * Continue tcp_input
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync TCP_INPUT(pData, (struct mbuf *)NULL, sizeof(struct ip), so);
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* continue; */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * XXX If we wrote something (a lot), there could be the need
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * for a window update. In the worst case, the remote will send
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * a window probe to get things going again.
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * Probe a still-connecting, non-blocking socket
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync * to check if it's still alive
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* else failed */
7b4c4bb29760b28b5727231ad446462a5b0cc01avboxsync /* tcp_input will take care of it */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync /* else failed */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync TCP_INPUT((struct mbuf *)NULL, sizeof(struct ip),so);
99f33ab590a3a65e0cd082dd8d67779efb9cc6c9vboxsync } /* SS_ISFCONNECTING */
2a171646d32f8a15e9820d6fb3bf3f9b9990ca3fvboxsync status = getsockopt(so->s, SOL_SOCKET, SO_ERROR, &err, &optlen);
00331fbaff118e6a5077fe96327aca51a70459dbvboxsync Log(("NAT: can't get error status from %R[natsock]\n", so));
#ifndef RT_OS_SOLARIS
if (status != 0)
goto tcp_input_close;
goto tcp_input_close;
so->so_state = SS_NOFDREF; /*cause connection valid tcp connection termination and socket closing */
#ifdef VBOX_WITH_SLIRP_MT
NSOCK_DEC();
done:
#ifndef VBOX_WITH_SLIRP_MT
struct arphdr
int ar_op;
switch(ar_op)
case ARPOP_REQUEST:
#ifdef VBOX_WITH_NAT_SERVICE
goto arp_ok;
goto arp_ok;
case CTL_DNS:
case CTL_ALIAS:
struct mbuf *m;
int proto;
static bool fWarnedIpv6;
/* @todo vasily: add ether logging routine in debug.c */
switch(proto)
case ETH_P_ARP:
case ETH_P_IP:
case ETH_P_IPV6:
if (!fWarnedIpv6)
fWarnedIpv6 = true;
goto done;
done:
goto done;
for (i = 0; i < NB_ADDR; i++)
done:
return INADDR_ANY;
int flags;
int rc;
#ifdef VBOX_WITH_NAT_SERVICE
goto remove_port_forwarding;
goto remove_port_forwarding;
goto remove_port_forwarding;
#ifndef VBOX_WITH_NAT_SERVICE
int guest_port)
#ifndef VBOX_WITH_NAT_SERVICE
#if defined(RT_OS_WINDOWS)
if (link_up)
if (time_fasttimo)
if (do_slowtimo)
#ifndef RT_OS_WINDOWS
#ifdef VBOX_WITH_SLIRP_MT