/** * @note This function will free m! */ int udp_output(PNATState pData, struct socket *so, struct mbuf *m, struct sockaddr_in *addr) { struct sockaddr_in saddr, daddr; Assert(so->so_type == IPPROTO_UDP); LogFlowFunc(("ENTER: so = %R[natsock], m = %p, saddr = %RTnaipv4\n", so, m, addr->sin_addr.s_addr)); if (so->so_laddr.s_addr == INADDR_ANY) { if (pData->guest_addr_guess.s_addr != INADDR_ANY) { LogRel2(("NAT: port-forward: using %RTnaipv4 for %R[natsock]\n", pData->guest_addr_guess.s_addr, so)); so->so_laddr = pData->guest_addr_guess; } else { LogRel2(("NAT: port-forward: guest address unknown for %R[natsock]\n", so)); m_freem(pData, m); return 0; } } saddr = *addr; if ((so->so_faddr.s_addr & RT_H2N_U32(pData->netmask)) == pData->special_addr.s_addr) { saddr.sin_addr.s_addr = so->so_faddr.s_addr; if (slirpIsWideCasting(pData, so->so_faddr.s_addr)) { /** * We haven't got real firewall but have got its submodule libalias. */ m->m_flags |= M_SKIP_FIREWALL; /** * udp/137 port is Name Service in NetBIOS protocol. for some reasons Windows guest rejects * accept data from non-aliased server. */ if ( (so->so_fport == so->so_lport) && (so->so_fport == RT_H2N_U16(137))) saddr.sin_addr.s_addr = alias_addr.s_addr; else saddr.sin_addr.s_addr = addr->sin_addr.s_addr; so->so_faddr.s_addr = addr->sin_addr.s_addr; } } /* Any UDP packet to the loopback address must be translated to be from * the forwarding address, i.e. 10.0.2.2. */ if ( (saddr.sin_addr.s_addr & RT_H2N_U32_C(IN_CLASSA_NET)) == RT_H2N_U32_C(INADDR_LOOPBACK & IN_CLASSA_NET)) saddr.sin_addr.s_addr = alias_addr.s_addr; daddr.sin_addr = so->so_laddr; daddr.sin_port = so->so_lport; return udp_output2(pData, so, m, &saddr, &daddr, so->so_iptos); }
/** * @note This function will free m! */ int udp_output(PNATState pData, struct socket *so, struct mbuf *m, struct sockaddr_in *addr) { struct sockaddr_in saddr, daddr; #ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE struct socket *pSocketClone = NULL; #endif Assert(so->so_type == IPPROTO_UDP); LogFlowFunc(("ENTER: so = %R[natsock], m = %p, saddr = %RTnaipv4\n", so, (long)m, addr->sin_addr.s_addr)); saddr = *addr; if ((so->so_faddr.s_addr & RT_H2N_U32(pData->netmask)) == pData->special_addr.s_addr) { saddr.sin_addr.s_addr = so->so_faddr.s_addr; if (slirpIsWideCasting(pData, so->so_faddr.s_addr)) { /** * We haven't got real firewall but have got its submodule libalias. */ m->m_flags |= M_SKIP_FIREWALL; /** * udp/137 port is Name Service in NetBIOS protocol. for some reasons Windows guest rejects * accept data from non-aliased server. */ if ( (so->so_fport == so->so_lport) && (so->so_fport == RT_H2N_U16(137))) saddr.sin_addr.s_addr = alias_addr.s_addr; else saddr.sin_addr.s_addr = addr->sin_addr.s_addr; /* we shouldn't override initial socket */ #ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE if (so->so_cCloneCounter) pSocketClone = soLookUpClonedUDPSocket(pData, so, addr->sin_addr.s_addr); if (!pSocketClone) pSocketClone = soCloneUDPSocketWithForegnAddr(pData, false, so, addr->sin_addr.s_addr); Assert((pSocketClone)); so = pSocketClone; #else so->so_faddr.s_addr = addr->sin_addr.s_addr; #endif } } /* Any UDP packet to the loopback address must be translated to be from * the forwarding address, i.e. 10.0.2.2. */ if ( (saddr.sin_addr.s_addr & RT_H2N_U32_C(IN_CLASSA_NET)) == RT_H2N_U32_C(INADDR_LOOPBACK & IN_CLASSA_NET)) saddr.sin_addr.s_addr = alias_addr.s_addr; daddr.sin_addr = so->so_laddr; daddr.sin_port = so->so_lport; return udp_output2(pData, so, m, &saddr, &daddr, so->so_iptos); }