| 1 | diff -ur include/VBox/err.h include/VBox/err.h
|
|---|
| 2 | --- include/VBox/err.h
|
|---|
| 3 | +++ include/VBox/err.h
|
|---|
| 4 | @@ -1042,6 +1042,9 @@
|
|---|
| 5 | * There probably is a conflict between the rule and some existing
|
|---|
| 6 | * service on the computer. */
|
|---|
| 7 | #define VERR_NAT_REDIR_SETUP (-3002)
|
|---|
| 8 | +/** Failed to convert the specified Host IP to a binary IP address.
|
|---|
| 9 | + * Malformed input. */
|
|---|
| 10 | +#define VERR_NAT_REDIR_HOST_IP (-3003)
|
|---|
| 11 | /** @} */
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 | diff -ur include/VBox/err.mac include/VBox/err.mac
|
|---|
| 15 | --- include/VBox/err.mac
|
|---|
| 16 | +++ include/VBox/err.mac
|
|---|
| 17 | @@ -346,6 +346,7 @@
|
|---|
| 18 | %define VINF_NAT_DNS 3000
|
|---|
| 19 | %define VERR_NAT_REDIR_GUEST_IP (-3001)
|
|---|
| 20 | %define VERR_NAT_REDIR_SETUP (-3002)
|
|---|
| 21 | +%define VERR_NAT_REDIR_HOST_IP (-3003)
|
|---|
| 22 | %define VERR_HOSTIF_INIT_FAILED (-3100)
|
|---|
| 23 | %define VERR_HOSTIF_DEVICE_NAME_TOO_LONG (-3101)
|
|---|
| 24 | %define VERR_HOSTIF_IOCTL (-3102)
|
|---|
| 25 | diff -ur src/VBox/Devices/Network/DrvNAT.cpp src/VBox/Devices/Network/DrvNAT.cpp
|
|---|
| 26 | --- src/VBox/Devices/Network/DrvNAT.cpp
|
|---|
| 27 | +++ src/VBox/Devices/Network/DrvNAT.cpp
|
|---|
| 28 | @@ -619,7 +619,7 @@
|
|---|
| 29 | /*
|
|---|
| 30 | * Validate the port forwarding config.
|
|---|
| 31 | */
|
|---|
| 32 | - if (!CFGMR3AreValuesValid(pNode, "Protocol\0UDP\0HostPort\0GuestPort\0GuestIP\0"))
|
|---|
| 33 | + if (!CFGMR3AreValuesValid(pNode, "Protocol\0UDP\0HostPort\0HostIP\0GuestPort\0GuestIP\0"))
|
|---|
| 34 | return PDMDRV_SET_ERROR(pThis->pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES, N_("Unknown configuration in port forwarding"));
|
|---|
| 35 |
|
|---|
| 36 | /* protocol type */
|
|---|
| 37 | @@ -652,6 +652,18 @@
|
|---|
| 38 | if (RT_FAILURE(rc))
|
|---|
| 39 | return PDMDrvHlpVMSetError(pThis->pDrvIns, rc, RT_SRC_POS, N_("NAT#%d: configuration query for \"HostPort\" integer failed"), iInstance);
|
|---|
| 40 |
|
|---|
| 41 | + /* host address */
|
|---|
| 42 | + char szHostIP[32];
|
|---|
| 43 | + rc = CFGMR3QueryString(pNode, "HostIP", &szHostIP[0], sizeof(szHostIP));
|
|---|
| 44 | + if (rc == VERR_CFGM_VALUE_NOT_FOUND)
|
|---|
| 45 | + RTStrPrintf(szHostIP, sizeof(szHostIP), "0.0.0.0");
|
|---|
| 46 | + else if (RT_FAILURE(rc))
|
|---|
| 47 | + return PDMDrvHlpVMSetError(pThis->pDrvIns, rc, RT_SRC_POS, N_("NAT#%d: configuration query for \"HostIP\" string failed"), iInstance);
|
|---|
| 48 | + struct in_addr HostIP;
|
|---|
| 49 | + if (!inet_aton(szHostIP, &HostIP))
|
|---|
| 50 | + return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_NAT_REDIR_HOST_IP, RT_SRC_POS,
|
|---|
| 51 | + N_("NAT#%d: configuration error: invalid \"HostIP\"=\"%s\", inet_aton failed"), iInstance, szHostIP);
|
|---|
| 52 | +
|
|---|
| 53 | /* guest port */
|
|---|
| 54 | int32_t iGuestPort;
|
|---|
| 55 | rc = CFGMR3QueryS32(pNode, "GuestPort", &iGuestPort);
|
|---|
| 56 | @@ -674,10 +686,10 @@
|
|---|
| 57 | /*
|
|---|
| 58 | * Call slirp about it.
|
|---|
| 59 | */
|
|---|
| 60 | - Log(("drvNATConstruct: Redir %d -> %s:%d\n", iHostPort, szGuestIP, iGuestPort));
|
|---|
| 61 | - if (slirp_redir(pThis->pNATState, fUDP, iHostPort, GuestIP, iGuestPort) < 0)
|
|---|
| 62 | + Log(("drvNATConstruct: Redir %s:%d -> %s:%d\n", szHostIP, iHostPort, szGuestIP, iGuestPort));
|
|---|
| 63 | + if (slirp_redir(pThis->pNATState, fUDP, HostIP, iHostPort, GuestIP, iGuestPort) < 0)
|
|---|
| 64 | return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_NAT_REDIR_SETUP, RT_SRC_POS,
|
|---|
| 65 | - N_("NAT#%d: configuration error: failed to set up redirection of %d to %s:%d. Probably a conflict with existing services or other rules"), iInstance, iHostPort, szGuestIP, iGuestPort);
|
|---|
| 66 | + N_("NAT#%d: configuration error: failed to set up redirection of %s:%d to %s:%d. Probably a conflict with existing services or other rules"), iInstance, szHostIP, iHostPort, szGuestIP, iGuestPort);
|
|---|
| 67 | } /* for each redir rule */
|
|---|
| 68 |
|
|---|
| 69 | return VINF_SUCCESS;
|
|---|
| 70 | diff -ur src/VBox/Devices/Network/slirp/libslirp.h src/VBox/Devices/Network/slirp/libslirp.h
|
|---|
| 71 | --- src/VBox/Devices/Network/slirp/libslirp.h
|
|---|
| 72 | +++ src/VBox/Devices/Network/slirp/libslirp.h
|
|---|
| 73 | @@ -54,7 +54,7 @@
|
|---|
| 74 | void slirp_output(void * pvUser, void *pvArg, const uint8_t *pkt, int pkt_len);
|
|---|
| 75 | void slirp_post_sent(PNATState pData, void *pvArg);
|
|---|
| 76 |
|
|---|
| 77 | -int slirp_redir(PNATState pData, int is_udp, int host_port,
|
|---|
| 78 | +int slirp_redir(PNATState pData, int is_udp, struct in_addr host_addr, int host_port,
|
|---|
| 79 | struct in_addr guest_addr, int guest_port);
|
|---|
| 80 | int slirp_add_exec(PNATState pData, int do_pty, const char *args, int addr_low_byte,
|
|---|
| 81 | int guest_port);
|
|---|
| 82 | diff -ur src/VBox/Devices/Network/slirp/slirp.c src/VBox/Devices/Network/slirp/slirp.c
|
|---|
| 83 | --- src/VBox/Devices/Network/slirp/slirp.c
|
|---|
| 84 | +++ src/VBox/Devices/Network/slirp/slirp.c
|
|---|
| 85 | @@ -1663,7 +1663,7 @@
|
|---|
| 86 | #endif
|
|---|
| 87 | }
|
|---|
| 88 |
|
|---|
| 89 | -int slirp_redir(PNATState pData, int is_udp, int host_port,
|
|---|
| 90 | +int slirp_redir(PNATState pData, int is_udp, struct in_addr host_addr, int host_port,
|
|---|
| 91 | struct in_addr guest_addr, int guest_port)
|
|---|
| 92 | {
|
|---|
| 93 | struct socket *so;
|
|---|
| 94 | @@ -1680,12 +1680,12 @@
|
|---|
| 95 | Log2(("NAT: set redirect %s hp:%d gp:%d\n", (is_udp?"UDP":"TCP"), host_port, guest_port));
|
|---|
| 96 | if (is_udp)
|
|---|
| 97 | {
|
|---|
| 98 | - so = udp_listen(pData, htons(host_port), guest_addr.s_addr,
|
|---|
| 99 | + so = udp_listen(pData, host_addr.s_addr, htons(host_port), guest_addr.s_addr,
|
|---|
| 100 | htons(guest_port), 0);
|
|---|
| 101 | }
|
|---|
| 102 | else
|
|---|
| 103 | {
|
|---|
| 104 | - so = solisten(pData, htons(host_port), guest_addr.s_addr,
|
|---|
| 105 | + so = solisten(pData, host_addr.s_addr, htons(host_port), guest_addr.s_addr,
|
|---|
| 106 | htons(guest_port), 0);
|
|---|
| 107 | }
|
|---|
| 108 | #ifndef VBOX_WITH_SLIRP_ALIAS
|
|---|
| 109 | diff -ur src/VBox/Devices/Network/slirp/socket.c src/VBox/Devices/Network/slirp/socket.c
|
|---|
| 110 | --- src/VBox/Devices/Network/slirp/socket.c
|
|---|
| 111 | +++ src/VBox/Devices/Network/slirp/socket.c
|
|---|
| 112 | @@ -746,7 +746,7 @@
|
|---|
| 113 | * XXX This should really be tcp_listen
|
|---|
| 114 | */
|
|---|
| 115 | struct socket *
|
|---|
| 116 | -solisten(PNATState pData, u_int port, u_int32_t laddr, u_int lport, int flags)
|
|---|
| 117 | +solisten(PNATState pData, u_int32_t haddr, u_int port, u_int32_t laddr, u_int lport, int flags)
|
|---|
| 118 | {
|
|---|
| 119 | struct sockaddr_in addr;
|
|---|
| 120 | struct socket *so;
|
|---|
| 121 | @@ -755,6 +755,7 @@
|
|---|
| 122 | int status;
|
|---|
| 123 |
|
|---|
| 124 | DEBUG_CALL("solisten");
|
|---|
| 125 | + DEBUG_ARG("addr = %d", haddr);
|
|---|
| 126 | DEBUG_ARG("port = %d", port);
|
|---|
| 127 | DEBUG_ARG("laddr = %x", laddr);
|
|---|
| 128 | DEBUG_ARG("lport = %d", lport);
|
|---|
| 129 | @@ -791,7 +792,7 @@
|
|---|
| 130 | so->so_laddr.s_addr = laddr; /* Ditto */
|
|---|
| 131 |
|
|---|
| 132 | addr.sin_family = AF_INET;
|
|---|
| 133 | - addr.sin_addr.s_addr = INADDR_ANY;
|
|---|
| 134 | + addr.sin_addr.s_addr = haddr;
|
|---|
| 135 | addr.sin_port = port;
|
|---|
| 136 |
|
|---|
| 137 | if ( ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
|---|
| 138 | diff -ur src/VBox/Devices/Network/slirp/socket.h src/VBox/Devices/Network/slirp/socket.h
|
|---|
| 139 | --- src/VBox/Devices/Network/slirp/socket.h
|
|---|
| 140 | +++ src/VBox/Devices/Network/slirp/socket.h
|
|---|
| 141 | @@ -166,7 +166,7 @@
|
|---|
| 142 | int sowrite (PNATState, struct socket *);
|
|---|
| 143 | void sorecvfrom (PNATState, struct socket *);
|
|---|
| 144 | int sosendto (PNATState, struct socket *, struct mbuf *);
|
|---|
| 145 | -struct socket * solisten (PNATState, u_int, u_int32_t, u_int, int);
|
|---|
| 146 | +struct socket * solisten (PNATState, u_int32_t, u_int, u_int32_t, u_int, int);
|
|---|
| 147 | void sorwakeup (struct socket *);
|
|---|
| 148 | void sowwakeup (struct socket *);
|
|---|
| 149 | void soisfconnecting (register struct socket *);
|
|---|
| 150 | diff -ur src/VBox/Devices/Network/slirp/tcp_subr.c src/VBox/Devices/Network/slirp/tcp_subr.c
|
|---|
| 151 | --- src/VBox/Devices/Network/slirp/tcp_subr.c
|
|---|
| 152 | +++ src/VBox/Devices/Network/slirp/tcp_subr.c
|
|---|
| 153 | @@ -742,7 +742,7 @@
|
|---|
| 154 | laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
|
|---|
| 155 | lport = htons((n5 << 8) | (n6));
|
|---|
| 156 |
|
|---|
| 157 | - if ((so = solisten(pData, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)
|
|---|
| 158 | + if ((so = solisten(pData, INADDR_ANY, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)
|
|---|
| 159 | return 1;
|
|---|
| 160 |
|
|---|
| 161 | n6 = ntohs(so->so_fport);
|
|---|
| 162 | @@ -781,7 +781,7 @@
|
|---|
| 163 | laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
|
|---|
| 164 | lport = htons((n5 << 8) | (n6));
|
|---|
| 165 |
|
|---|
| 166 | - if ((so = solisten(pData, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)
|
|---|
| 167 | + if ((so = solisten(pData, INADDR_ANY, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)
|
|---|
| 168 | return 1;
|
|---|
| 169 |
|
|---|
| 170 | n6 = ntohs(so->so_fport);
|
|---|
| 171 | @@ -821,7 +821,7 @@
|
|---|
| 172 | }
|
|---|
| 173 | if ( m->m_data[m->m_len-1] == '\0'
|
|---|
| 174 | && lport != 0
|
|---|
| 175 | - && (so = solisten(pData, 0, so->so_laddr.s_addr,
|
|---|
| 176 | + && (so = solisten(pData, INADDR_ANY, 0, so->so_laddr.s_addr,
|
|---|
| 177 | htons(lport), SS_FACCEPTONCE)) != NULL)
|
|---|
| 178 | m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1;
|
|---|
| 179 | return 1;
|
|---|
| 180 | @@ -837,7 +837,7 @@
|
|---|
| 181 | /* The %256s is for the broken mIRC */
|
|---|
| 182 | if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3)
|
|---|
| 183 | {
|
|---|
| 184 | - if ((so = solisten(pData, 0, htonl(laddr),
|
|---|
| 185 | + if ((so = solisten(pData, INADDR_ANY, 0, htonl(laddr),
|
|---|
| 186 | htons(lport), SS_FACCEPTONCE)) == NULL)
|
|---|
| 187 | return 1;
|
|---|
| 188 |
|
|---|
| 189 | @@ -848,7 +848,7 @@
|
|---|
| 190 | }
|
|---|
| 191 | else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4)
|
|---|
| 192 | {
|
|---|
| 193 | - if ((so = solisten(pData, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
|
|---|
| 194 | + if ((so = solisten(pData, INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
|
|---|
| 195 | return 1;
|
|---|
| 196 |
|
|---|
| 197 | m->m_len = bptr - m->m_data; /* Adjust length */
|
|---|
| 198 | @@ -858,7 +858,7 @@
|
|---|
| 199 | }
|
|---|
| 200 | else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4)
|
|---|
| 201 | {
|
|---|
| 202 | - if ((so = solisten(pData, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
|
|---|
| 203 | + if ((so = solisten(pData, INADDR_ANY, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
|
|---|
| 204 | return 1;
|
|---|
| 205 |
|
|---|
| 206 | m->m_len = bptr - m->m_data; /* Adjust length */
|
|---|
| 207 | @@ -983,7 +983,8 @@
|
|---|
| 208 | /* try to get udp port between 6970 - 7170 */
|
|---|
| 209 | for (p = 6970; p < 7071; p++)
|
|---|
| 210 | {
|
|---|
| 211 | - if (udp_listen(htons(p),
|
|---|
| 212 | + if (udp_listen(INADDR_ANY,
|
|---|
| 213 | + htons(p),
|
|---|
| 214 | so->so_laddr.s_addr,
|
|---|
| 215 | htons(lport),
|
|---|
| 216 | SS_FACCEPTONCE))
|
|---|
| 217 | diff -ur src/VBox/Devices/Network/slirp/udp.c src/VBox/Devices/Network/slirp/udp.c
|
|---|
| 218 | --- src/VBox/Devices/Network/slirp/udp.c
|
|---|
| 219 | +++ src/VBox/Devices/Network/slirp/udp.c
|
|---|
| 220 | @@ -716,7 +716,7 @@
|
|---|
| 221 | }
|
|---|
| 222 |
|
|---|
| 223 | struct socket *
|
|---|
| 224 | -udp_listen(PNATState pData, u_int port, u_int32_t laddr, u_int lport, int flags)
|
|---|
| 225 | +udp_listen(PNATState pData, u_int32_t haddr, u_int port, u_int32_t laddr, u_int lport, int flags)
|
|---|
| 226 | {
|
|---|
| 227 | struct sockaddr_in addr;
|
|---|
| 228 | struct socket *so;
|
|---|
| 229 | @@ -742,7 +742,7 @@
|
|---|
| 230 | QSOCKET_UNLOCK(udb);
|
|---|
| 231 |
|
|---|
| 232 | addr.sin_family = AF_INET;
|
|---|
| 233 | - addr.sin_addr.s_addr = INADDR_ANY;
|
|---|
| 234 | + addr.sin_addr.s_addr = haddr;
|
|---|
| 235 | addr.sin_port = port;
|
|---|
| 236 |
|
|---|
| 237 | if (bind(so->s,(struct sockaddr *)&addr, addrlen) < 0)
|
|---|
| 238 | diff -ur src/VBox/Devices/Network/slirp/udp.h src/VBox/Devices/Network/slirp/udp.h
|
|---|
| 239 | --- src/VBox/Devices/Network/slirp/udp.h
|
|---|
| 240 | +++ src/VBox/Devices/Network/slirp/udp.h
|
|---|
| 241 | @@ -108,7 +108,7 @@
|
|---|
| 242 | void udp_detach (PNATState, struct socket *);
|
|---|
| 243 | u_int8_t udp_tos (struct socket *);
|
|---|
| 244 | void udp_emu (PNATState, struct socket *, struct mbuf *);
|
|---|
| 245 | -struct socket * udp_listen (PNATState, u_int, u_int32_t, u_int, int);
|
|---|
| 246 | +struct socket * udp_listen (PNATState, u_int32_t, u_int, u_int32_t, u_int, int);
|
|---|
| 247 | int udp_output2(PNATState pData, struct socket *so, struct mbuf *m,
|
|---|
| 248 | struct sockaddr_in *saddr, struct sockaddr_in *daddr,
|
|---|
| 249 | int iptos);
|
|---|