34
33
polls[poll_index].events = N_(fdset ## _poll); \
35
34
polls[poll_index].revents = 0; \
40
# define DO_ENGAGE_EVENT2(so, fdset1, fdset2, label) \
42
if ( so->so_poll_index != -1 \
43
&& so->s == polls[so->so_poll_index].fd) { \
44
polls[so->so_poll_index].events |= \
45
N_(fdset1 ## _poll) | N_(fdset1 ## _poll); \
46
break; /* out of this loop */ \
48
AssertRelease(poll_index < (nfds)); \
49
polls[poll_index].fd = (so)->s; \
50
(so)->so_poll_index = poll_index; \
51
polls[poll_index].events = \
52
N_(fdset1 ## _poll) | N_(fdset1 ## _poll); \
39
# define DO_ENGAGE_EVENT2(so, fdset1, fdset2, label) \
41
if ( so->so_poll_index != -1 \
42
&& so->s == polls[so->so_poll_index].fd) { \
43
polls[so->so_poll_index].events |= \
44
N_(fdset1 ## _poll) | N_(fdset1 ## _poll); \
45
break; /* out of this loop */ \
47
AssertRelease(poll_index < (nfds)); \
48
polls[poll_index].fd = (so)->s; \
49
(so)->so_poll_index = poll_index; \
50
polls[poll_index].events = \
51
N_(fdset1 ## _poll) | N_(fdset1 ## _poll); \
56
55
# define DO_POLL_EVENTS(rc, error, so, events, label) do {} while (0)
58
# define DO_CHECK_FD_SET(so, events, fdset) ( ((so)->so_poll_index != -1) \
59
&& ((so)->so_poll_index <= ndfs) \
60
&& ((so)->s == polls[so->so_poll_index].fd) \
61
&& (polls[(so)->so_poll_index].revents & N_(fdset ## _poll)))
62
# define DO_UNIX_CHECK_FD_SET(so, events, fdset ) DO_CHECK_FD_SET((so), (events), fdset) /*specific for Unix API */
63
# define DO_WIN_CHECK_FD_SET(so, events, fdset ) 0 /* specific for Windows Winsock API */
57
# define DO_CHECK_FD_SET(so, events, fdset) \
58
( ((so)->so_poll_index != -1) \
59
&& ((so)->so_poll_index <= ndfs) \
60
&& ((so)->s == polls[so->so_poll_index].fd) \
61
&& (polls[(so)->so_poll_index].revents & N_(fdset ## _poll)))
63
/* specific for Unix API */
64
# define DO_UNIX_CHECK_FD_SET(so, events, fdset ) DO_CHECK_FD_SET((so), (events), fdset)
65
/* specific for Windows Winsock API */
66
# define DO_WIN_CHECK_FD_SET(so, events, fdset ) 0
65
68
# ifndef RT_OS_WINDOWS
210
215
struct in_addr *pdns_addr,
211
216
const char **ppszDomain)
213
/* Get amount of memory required for operation */
214
218
ULONG flags = GAA_FLAG_INCLUDE_PREFIX; /*GAA_FLAG_INCLUDE_ALL_INTERFACES;*/ /* all interfaces registered in NDIS */
215
PIP_ADAPTER_ADDRESSES addresses = NULL;
216
PIP_ADAPTER_ADDRESSES addr = NULL;
217
PIP_ADAPTER_DNS_SERVER_ADDRESS dns = NULL;
219
PIP_ADAPTER_ADDRESSES pAdapterAddr = NULL;
220
PIP_ADAPTER_ADDRESSES pAddr = NULL;
221
PIP_ADAPTER_DNS_SERVER_ADDRESS pDnsAddr = NULL;
221
struct dns_entry *da = NULL;
222
struct dns_domain_entry *dd = NULL;
225
struct dns_domain_entry *pDomain = NULL;
223
226
ULONG ret = ERROR_SUCCESS;
225
228
/* @todo add SKIPing flags to get only required information */
227
ret = pData->pfGetAdaptersAddresses(AF_INET, 0, NULL /* reserved */, addresses, &size);
230
/* determine size of buffer */
232
ret = pData->pfGetAdaptersAddresses(AF_INET, 0, NULL /* reserved */, pAdapterAddr, &size);
228
233
if (ret != ERROR_BUFFER_OVERFLOW)
230
235
LogRel(("NAT: error %lu occurred on capacity detection operation\n", ret));
236
240
LogRel(("NAT: Win socket API returns non capacity\n"));
240
addresses = RTMemAllocZ(size);
241
if (addresses == NULL)
244
pAdapterAddr = RTMemAllocZ(size);
243
247
LogRel(("NAT: No memory available \n"));
247
ret = pData->pfGetAdaptersAddresses(AF_INET, 0, NULL /* reserved */, addresses, &size);
250
ret = pData->pfGetAdaptersAddresses(AF_INET, 0, NULL /* reserved */, pAdapterAddr, &size);
248
251
if (ret != ERROR_SUCCESS)
250
253
LogRel(("NAT: error %lu occurred on fetching adapters info\n", ret));
251
RTMemFree(addresses);
254
RTMemFree(pAdapterAddr);
258
for (pAddr = pAdapterAddr; pAddr != NULL; pAddr = pAddr->Next)
258
if (addr->OperStatus != IfOperStatusUp)
260
dns = addr->FirstDnsServerAddress;
261
if (pAddr->OperStatus != IfOperStatusUp)
264
for (pDnsAddr = pAddr->FirstDnsServerAddress; pDnsAddr != NULL; pDnsAddr = pDnsAddr->Next)
263
struct sockaddr *saddr = dns->Address.lpSockaddr;
264
if (saddr->sa_family != AF_INET)
266
struct sockaddr *SockAddr = pDnsAddr->Address.lpSockaddr;
267
struct in_addr InAddr;
268
struct dns_entry *pDns;
270
if (SockAddr->sa_family != AF_INET)
273
InAddr = ((struct sockaddr_in *)SockAddr)->sin_addr;
266
275
/* add dns server to list */
267
da = RTMemAllocZ(sizeof(struct dns_entry));
276
pDns = RTMemAllocZ(sizeof(struct dns_entry));
270
279
LogRel(("NAT: Can't allocate buffer for DNS entry\n"));
271
RTMemFree(addresses);
280
RTMemFree(pAdapterAddr);
272
281
return VERR_NO_MEMORY;
274
LogRel(("NAT: adding %R[IP4] to DNS server list\n", &((struct sockaddr_in *)saddr)->sin_addr));
275
if ((((struct sockaddr_in *)saddr)->sin_addr.s_addr & htonl(IN_CLASSA_NET)) == ntohl(INADDR_LOOPBACK & IN_CLASSA_NET)) {
276
da->de_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
284
LogRel(("NAT: adding %R[IP4] to DNS server list\n", &InAddr));
285
if ((InAddr.s_addr & htonl(IN_CLASSA_NET)) == ntohl(INADDR_LOOPBACK & IN_CLASSA_NET))
286
pDns->de_addr.s_addr = htonl(ntohl(pData->special_addr.s_addr) | CTL_ALIAS);
288
pDns->de_addr.s_addr = InAddr.s_addr;
290
TAILQ_INSERT_HEAD(&pData->pDnsList, pDns, de_list);
292
if (pAddr->DnsSuffix == NULL)
296
RTUtf16ToUtf8(pAddr->DnsSuffix, &pszSuffix);
297
if (!pszSuffix || strlen(pszSuffix) == 0)
280
da->de_addr.s_addr = ((struct sockaddr_in *)saddr)->sin_addr.s_addr;
282
TAILQ_INSERT_HEAD(&pData->dns_list_head, da, de_list);
284
if (addr->DnsSuffix == NULL)
288
RTUtf16ToUtf8(addr->DnsSuffix, &suffix);
290
if (!suffix || strlen(suffix) == 0) {
299
RTStrFree(pszSuffix);
296
LIST_FOREACH(dd, &pData->dns_domain_list_head, dd_list)
304
LIST_FOREACH(pDomain, &pData->pDomainList, dd_list)
298
if ( dd->dd_pszDomain != NULL
299
&& strcmp(dd->dd_pszDomain, suffix) == 0)
306
if ( pDomain->dd_pszDomain != NULL
307
&& strcmp(pDomain->dd_pszDomain, pszSuffix) == 0)
310
RTStrFree(pszSuffix);
308
dd = RTMemAllocZ(sizeof(struct dns_domain_entry));
316
pDomain = RTMemAllocZ(sizeof(struct dns_domain_entry));
311
319
LogRel(("NAT: not enough memory\n"));
313
RTMemFree(addresses);
320
RTStrFree(pszSuffix);
321
RTMemFree(pAdapterAddr);
314
322
return VERR_NO_MEMORY;
316
dd->dd_pszDomain = suffix;
317
LogRel(("NAT: adding domain name %s to search list\n", dd->dd_pszDomain));
318
LIST_INSERT_HEAD(&pData->dns_domain_list_head, dd, dd_list);
324
pDomain->dd_pszDomain = pszSuffix;
325
LogRel(("NAT: adding domain name %s to search list\n", pDomain->dd_pszDomain));
326
LIST_INSERT_HEAD(&pData->pDomainList, pDomain, dd_list);
326
RTMemFree(addresses);
330
RTMemFree(pAdapterAddr);
330
334
#else /* !RT_OS_WINDOWS */
336
static int RTFileGets(RTFILE File, void *pvBuf, size_t cbBufSize, size_t *pcbRead)
340
int rc = VERR_NO_MEMORY;
341
char *pu8Buf = (char *)pvBuf;
344
while ( RT_SUCCESS(rc = RTFileRead(File, &bTest, 1, &cbRead))
345
&& (pu8Buf - (char *)pvBuf) < cbBufSize)
350
if (bTest == '\r' || bTest == '\n')
332
362
static int get_dns_addr_domain(PNATState pData, bool fVerbose,
333
363
struct in_addr *pdns_addr,
334
364
const char **ppszDomain)
340
370
struct in_addr tmp_addr;
343
375
/* Try various locations. */
344
376
char *etc = getenv("ETC");
347
snprintf(buff, sizeof(buff), "%s/RESOLV2", etc);
348
f = fopen(buff, "rt");
352
snprintf(buff, sizeof(buff), "%s/RESOLV2", _PATH_ETC);
353
f = fopen(buff, "rt");
357
snprintf(buff, sizeof(buff), "%s/resolv.conf", _PATH_ETC);
358
f = fopen(buff, "rt");
362
f = fopen("/etc/resolv.conf", "r");
379
RTStrmPrintf(buff, sizeof(buff), "%s/RESOLV2", etc);
380
rc = RTFileOpen(&f, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
384
RTStrmPrintf(buff, sizeof(buff), "%s/RESOLV2", _PATH_ETC);
385
rc = RTFileOpen(&f, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
389
RTStrmPrintf(buff, sizeof(buff), "%s/resolv.conf", _PATH_ETC);
390
rc = RTFileOpen(&f, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
394
rc = RTFileOpen(&f, "/etc/resolv.conf", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
364
396
char *home = getenv("HOME");
365
snprintf(buff, sizeof(buff), "%s/resolv.conf", home);
366
f = fopen(buff, "r");
397
RTStrPrintf(buff, sizeof(buff), "%s/resolv.conf", home);
398
rc = RTFileOpen(&f, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
369
401
Log(("NAT: DNS we're using %s\n", buff));
373
f = fopen("/etc/resolv.conf", "r");
405
rc = RTFileOpen(&f, "/etc/resolv.conf", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
374
406
Log(("NAT: DNS we're using %s\n", buff));
382
414
*ppszDomain = NULL;
383
Log(("nat: DNS Servers:\n"));
384
while (fgets(buff, 512, f) != NULL)
416
Log(("NAT: DNS Servers:\n"));
417
while ( RT_SUCCESS(rc = RTFileGets(f, buff, 512, &bytes))
386
struct dns_entry *da = NULL;
420
struct dns_entry *pDns = NULL;
387
421
if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1)
389
423
if (!inet_aton(buff2, &tmp_addr))
392
da = RTMemAllocZ(sizeof (struct dns_entry));
427
pDns = RTMemAllocZ(sizeof (struct dns_entry));
395
430
LogRel(("can't alloc memory for DNS entry\n"));
399
da->de_addr.s_addr = tmp_addr.s_addr;
400
if ((da->de_addr.s_addr & htonl(IN_CLASSA_NET)) == ntohl(INADDR_LOOPBACK & IN_CLASSA_NET)) {
401
da->de_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS);
435
pDns->de_addr.s_addr = tmp_addr.s_addr;
436
if ((pDns->de_addr.s_addr & htonl(IN_CLASSA_NET)) == ntohl(INADDR_LOOPBACK & IN_CLASSA_NET))
438
pDns->de_addr.s_addr = htonl(ntohl(pData->special_addr.s_addr) | CTL_ALIAS);
403
TAILQ_INSERT_HEAD(&pData->dns_list_head, da, de_list);
440
TAILQ_INSERT_HEAD(&pData->pDnsList, pDns, de_list);
406
443
if ((!strncmp(buff, "domain", 6) || !strncmp(buff, "search", 6)))
410
struct dns_domain_entry *dd = NULL;
447
struct dns_domain_entry *pDomain = NULL;
412
449
tok = strtok_r(&buff[6], " \t\n", &saveptr);
413
LIST_FOREACH(dd, &pData->dns_domain_list_head, dd_list)
450
LIST_FOREACH(pDomain, &pData->pDomainList, dd_list)
416
&& strcmp(tok, dd->dd_pszDomain) == 0)
453
&& strcmp(tok, pDomain->dd_pszDomain) == 0)
422
if (tok != NULL && found == 0) {
423
dd = RTMemAllocZ(sizeof(struct dns_domain_entry));
459
if (tok != NULL && found == 0)
461
pDomain = RTMemAllocZ(sizeof(struct dns_domain_entry));
426
464
LogRel(("NAT: not enought memory to add domain list\n"));
427
465
return VERR_NO_MEMORY;
429
dd->dd_pszDomain = RTStrDup(tok);
430
LogRel(("NAT: adding domain name %s to search list\n", dd->dd_pszDomain));
431
LIST_INSERT_HEAD(&pData->dns_domain_list_head, dd, dd_list);
467
pDomain->dd_pszDomain = RTStrDup(tok);
468
LogRel(("NAT: adding domain name %s to search list\n", pDomain->dd_pszDomain));
469
LIST_INSERT_HEAD(&pData->pDomainList, pDomain, dd_list);
1359
1450
htip = ntohl(*(uint32_t*)ah->ar_tip);
1360
1451
tip = *(uint32_t*)ah->ar_tip;
1363
#ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
1364
reh = mtod(mr, struct ethhdr *);
1365
memcpy(reh->h_source, eh->h_source, ETH_ALEN); /* XXX: if_encap will swap src and dst*/
1366
Log4(("NAT: arp:%R[ether]->%R[ether]\n",
1367
reh->h_source, reh->h_dest));
1368
Log4(("NAT: arp: %R[IP4]\n", &tip));
1370
mr->m_data += if_maxlinkhdr;
1371
mr->m_len = sizeof(struct arphdr);
1372
rah = mtod(mr, struct arphdr *);
1374
1453
ar_op = ntohs(ah->ar_op);
1377
1456
case ARPOP_REQUEST:
1457
#ifndef VBOX_WITH_SLIRP_BSD_MBUF
1460
reh = mtod(mr, struct ethhdr *);
1461
memcpy(reh->h_source, eh->h_source, ETH_ALEN); /* XXX: if_encap will swap src and dst*/
1462
Log4(("NAT: arp:%R[ether]->%R[ether]\n",
1463
reh->h_source, reh->h_dest));
1464
Log4(("NAT: arp: %R[IP4]\n", &tip));
1466
mr->m_data += if_maxlinkhdr;
1467
mr->m_len = sizeof(struct arphdr);
1468
rah = mtod(mr, struct arphdr *);
1470
mr = m_getcl(pData, M_NOWAIT, MT_HEADER, M_PKTHDR);
1471
reh = mtod(mr, struct ethhdr *);
1472
mr->m_data += ETH_HLEN;
1473
rah = mtod(mr, struct arphdr *);
1474
mr->m_len = sizeof(struct arphdr);
1476
memcpy(reh->h_source, eh->h_source, ETH_ALEN); /* XXX: if_encap will swap src and dst*/
1378
1478
#ifdef VBOX_WITH_NAT_SERVICE
1379
if (tip == special_addr.s_addr) goto arp_ok;
1479
if (tip == pData->special_addr.s_addr)
1381
if ((htip & pData->netmask) == ntohl(special_addr.s_addr))
1482
if ((htip & pData->netmask) == ntohl(pData->special_addr.s_addr))
1383
1484
if ( CTL_CHECK(htip, CTL_DNS)
1384
1485
|| CTL_CHECK(htip, CTL_ALIAS)
1412
1516
memcpy(rah->ar_sip, ah->ar_tip, 4);
1413
1517
memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
1414
1518
memcpy(rah->ar_tip, ah->ar_sip, 4);
1415
if_encap(pData, ETH_P_ARP, mr);
1519
if_encap(pData, ETH_P_ARP, mr, ETH_ENCAP_URG);
1416
1520
m_free(pData, m);
1522
/* Gratuitous ARP */
1523
if ( *(uint32_t *)ah->ar_sip == *(uint32_t *)ah->ar_tip
1524
&& memcmp(ah->ar_tha, broadcast_ethaddr, ETH_ALEN) == 0
1525
&& memcmp(eh->h_dest, broadcast_ethaddr, ETH_ALEN) == 0)
1527
/* we've received anounce about address asignment
1528
* Let's do ARP cache update
1530
if (slirp_arp_cache_update(pData, *(uint32_t *)ah->ar_tip, &eh->h_dest[0]) == 0)
1536
slirp_arp_cache_add(pData, *(uint32_t *)ah->ar_tip, &eh->h_dest[0]);
1419
1540
case ARPOP_REPLY:
1421
struct arp_cache_entry *ac = NULL;
1422
if (slirp_update_arp_cache(pData, *(uint32_t *)ah->ar_sip, ah->ar_sha) == 0)
1541
if (slirp_arp_cache_update(pData, *(uint32_t *)ah->ar_sip, &ah->ar_sha[0]) == 0)
1424
1543
m_free(pData, m);
1427
ac = RTMemAllocZ(sizeof(struct arp_cache_entry));
1430
LogRel(("NAT: Can't allocate arp cache entry\n"));
1434
ac->ip = *(uint32_t *)ah->ar_sip;
1435
memcpy(ac->ether, ah->ar_sha, ETH_ALEN);
1436
LIST_INSERT_HEAD(&pData->arp_cache, ac, list);
1546
slirp_arp_cache_add(pData, *(uint32_t *)ah->ar_sip, ah->ar_sha);
1555
#ifdef VBOX_WITH_SLIRP_BSD_MBUF
1444
1556
void slirp_input(PNATState pData, const uint8_t *pkt, int pkt_len)
1558
void slirp_input(PNATState pData, void *pvArg)
1446
1561
struct mbuf *m;
1448
1563
static bool fWarnedIpv6;
1564
#ifdef VBOX_WITH_SLIRP_BSD_MBUF
1449
1565
struct ethhdr *eh = (struct ethhdr*)pkt;
1570
uint8_t au8Ether[ETH_ALEN];
1572
#ifndef VBOX_WITH_SLIRP_BSD_MBUF
1573
m = (struct mbuf *)pvArg;
1574
if (m->m_len < ETH_HLEN)
1576
LogRel(("NAT: packet having size %d has been ingnored\n", m->m_len));
1580
eh = mtod(m, struct ethhdr *);
1581
proto = ntohs(eh->h_proto);
1451
1583
Log2(("NAT: slirp_input %d\n", pkt_len));
1452
1584
if (pkt_len < ETH_HLEN)
1546
eh->h_proto = htons(eth_proto);
1548
slirp_output(pData->pvUser, m, mtod(m, uint8_t *), m->m_len);
1713
#ifndef VBOX_WITH_SLIRP_BSD_MBUF
1550
buf = RTMemAlloc(1600);
1716
mlen = m_length(m, NULL);
1717
buf = RTMemAlloc(mlen);
1551
1718
if (buf == NULL)
1553
1720
LogRel(("NAT: Can't alloc memory for outgoing buffer\n"));
1556
memcpy(buf, mtod(m, uint8_t *), m->m_len);
1557
slirp_output(pData->pvUser, NULL, buf, m->m_len);
1724
eh->h_proto = htons(eth_proto);
1725
#ifdef VBOX_WITH_SLIRP_BSD_MBUF
1726
m_copydata(m, 0, mlen, (char *)buf);
1728
if (flags & ETH_ENCAP_URG)
1729
slirp_urg_output(pData->pvUser, m, mtod(m, const uint8_t *), mlen);
1731
slirp_output(pData->pvUser, m, mtod(m, const uint8_t *), mlen);
1734
STAM_PROFILE_STOP(&pData->StatIF_encap, a);
1735
#ifdef VBOX_WITH_SLIRP_BSD_MBUF
1559
1736
m_free(pData, m);
1741
* Still we're using dhcp server leasing to map ether to IP
1742
* @todo see rt_lookup_in_cache
1744
static uint32_t find_guest_ip(PNATState pData, const uint8_t *eth_addr)
1746
uint32_t ip = INADDR_ANY;
1749
if (eth_addr == NULL)
1752
if ( memcmp(eth_addr, zerro_ethaddr, ETH_ALEN) == 0
1753
|| memcmp(eth_addr, broadcast_ethaddr, ETH_ALEN) == 0)
1756
rc = slirp_arp_lookup_ip_by_ether(pData, eth_addr, &ip);
1760
bootp_cache_lookup_ip_by_ether(pData, eth_addr, &ip);
1761
/* ignore return code, ip will be set to INADDR_ANY on error */
1766
* We need check if we've activated port forwarding
1767
* for specific machine ... that of course relates to
1769
* @todo finish this for service case
1771
static void activate_port_forwarding(PNATState pData, const uint8_t *h_source)
1773
struct port_forward_rule *rule;
1775
/* check mac here */
1776
LIST_FOREACH(rule, &pData->port_forward_rule_head, list)
1779
struct alias_link *link;
1780
struct libalias *lib;
1783
struct sockaddr_in *psin;
1784
socklen_t socketlen;
1785
struct in_addr alias;
1787
uint32_t guest_addr; /* need to understand if we already give address to guest */
1789
if (rule->activated)
1792
#ifdef VBOX_WITH_NAT_SERVICE
1793
if (memcmp(rule->mac_address, h_source, ETH_ALEN) != 0)
1794
continue; /*not right mac, @todo: it'd be better do the list port forwarding per mac */
1795
guest_addr = find_guest_ip(pData, h_source);
1798
if (memcmp(client_ethaddr, h_source, ETH_ALEN) != 0)
1801
guest_addr = find_guest_ip(pData, h_source);
1803
if (guest_addr == INADDR_ANY)
1805
/* the address wasn't granted */
1809
#if !defined(VBOX_WITH_NAT_SERVICE)
1810
if (rule->guest_addr.s_addr != guest_addr)
1814
LogRel(("NAT: set redirect %s host port %d => guest port %d @ %R[IP4]\n",
1815
(rule->proto == IPPROTO_UDP?"UDP":"TCP"),
1816
rule->host_port, rule->guest_port, &guest_addr));
1818
if (rule->proto == IPPROTO_UDP)
1819
so = udp_listen(pData, rule->bind_ip.s_addr, htons(rule->host_port), guest_addr,
1820
htons(rule->guest_port), 0);
1822
so = solisten(pData, rule->bind_ip.s_addr, htons(rule->host_port), guest_addr,
1823
htons(rule->guest_port), 0);
1826
goto remove_port_forwarding;
1828
psin = (struct sockaddr_in *)&sa;
1829
psin->sin_family = AF_INET;
1831
psin->sin_addr.s_addr = INADDR_ANY;
1832
socketlen = sizeof(struct sockaddr);
1834
rc = getsockname(so->s, &sa, &socketlen);
1835
if (rc < 0 || sa.sa_family != AF_INET)
1836
goto remove_port_forwarding;
1838
psin = (struct sockaddr_in *)&sa;
1840
lib = LibAliasInit(pData, NULL);
1841
flags = LibAliasSetMode(lib, 0, 0);
1842
flags |= PKT_ALIAS_LOG; /* set logging */
1843
flags |= PKT_ALIAS_REVERSE; /* set logging */
1844
flags = LibAliasSetMode(lib, flags, ~0);
1846
alias.s_addr = htonl(ntohl(guest_addr) | CTL_ALIAS);
1847
link = LibAliasRedirectPort(lib, psin->sin_addr, htons(rule->host_port),
1848
alias, htons(rule->guest_port),
1849
pData->special_addr, -1, /* not very clear for now */
1852
goto remove_port_forwarding;
1855
rule->activated = 1;
1856
pData->cRedirectionsActive++;
1859
remove_port_forwarding:
1860
LogRel(("NAT: failed to redirect %s %d => %d\n",
1861
(rule->proto == IPPROTO_UDP?"UDP":"TCP"), rule->host_port, rule->guest_port));
1862
LIST_REMOVE(rule, list);
1863
pData->cRedirectionsStored--;
1869
* Changes in 3.1 instead of opening new socket do the following:
1870
* gain more information:
1875
* 5. guest MAC address
1876
* the guest's MAC address is rather important for service, but we easily
1877
* could get it from VM configuration in DrvNAT or Service, the idea is activating
1878
* corresponding port-forwarding
1563
1880
int slirp_redir(PNATState pData, int is_udp, struct in_addr host_addr, int host_port,
1564
struct in_addr guest_addr, int guest_port)
1881
struct in_addr guest_addr, int guest_port, const uint8_t *ethaddr)
1567
#ifdef VBOX_WITH_SLIRP_ALIAS
1568
struct alias_link *link;
1569
struct libalias *lib;
1572
struct sockaddr_in *psin;
1573
socklen_t socketlen;
1574
struct in_addr alias;
1577
Log2(("NAT: set redirect %s hp:%d gp:%d\n", (is_udp?"UDP":"TCP"), host_port, guest_port));
1580
so = udp_listen(pData, host_addr.s_addr, htons(host_port), guest_addr.s_addr,
1581
htons(guest_port), 0);
1585
so = solisten(pData, host_addr.s_addr, htons(host_port), guest_addr.s_addr,
1586
htons(guest_port), 0);
1592
#ifndef VBOX_WITH_SLIRP_ALIAS
1593
Log2(("NAT: redirecting socket %R[natsock]\n", so));
1594
return (so != NULL ? 0 : -1);
1597
psin = (struct sockaddr_in *)&sa;
1598
psin->sin_family = AF_INET;
1600
psin->sin_addr.s_addr = INADDR_ANY;
1601
socketlen = sizeof(struct sockaddr);
1603
rc = getsockname(so->s, &sa, &socketlen);
1604
if (rc < 0 || sa.sa_family != AF_INET)
1606
Log(("NAT: can't get socket's name\n"));
1610
psin = (struct sockaddr_in *)&sa;
1613
lib = LibAliasInit(pData, NULL);
1614
flags = LibAliasSetMode(lib, 0, 0);
1615
flags |= PKT_ALIAS_LOG; /* set logging */
1616
flags |= PKT_ALIAS_REVERSE; /* set logging */
1617
flags = LibAliasSetMode(lib, flags, ~0);
1619
lib = LIST_FIRST(&instancehead);
1622
alias.s_addr = htonl(ntohl(guest_addr.s_addr) | CTL_ALIAS);
1623
link = LibAliasRedirectPort(lib, psin->sin_addr, htons(host_port),
1624
alias, htons(guest_port),
1625
special_addr, -1, /* not very clear for now*/
1626
(is_udp ? IPPROTO_UDP : IPPROTO_TCP));
1629
Log(("NAT: can't create redirect\n"));
1883
struct port_forward_rule *rule = NULL;
1884
Assert(memcmp(ethaddr, zerro_ethaddr, ETH_ALEN) == 0);
1886
rule = RTMemAllocZ(sizeof(struct port_forward_rule));
1890
rule->proto = (is_udp ? IPPROTO_UDP : IPPROTO_TCP);
1891
rule->host_port = host_port;
1892
rule->guest_port = guest_port;
1893
#ifndef VBOX_WITH_NAT_SERVICE
1894
rule->guest_addr.s_addr = guest_addr.s_addr;
1896
rule->bind_ip.s_addr = host_addr.s_addr;
1897
memcpy(rule->mac_address, ethaddr, ETH_ALEN);
1898
/* @todo add mac address */
1899
LIST_INSERT_HEAD(&pData->port_forward_rule_head, rule, list);
1900
pData->cRedirectionsStored++;
1638
1904
int slirp_add_exec(PNATState pData, int do_pty, const char *args, int addr_low_byte,
1641
1907
return add_exec(&exec_list, do_pty, (char *)args,
1642
1908
addr_low_byte, htons(guest_port));
1645
void slirp_set_ethaddr(PNATState pData, const uint8_t *ethaddr)
1911
void slirp_set_ethaddr_and_activate_port_forwarding(PNATState pData, const uint8_t *ethaddr, uint32_t GuestIP)
1647
#ifndef VBOX_WITHOUT_SLIRP_CLIENT_ETHER
1913
#ifndef VBOX_WITH_NAT_SERVICE
1648
1914
memcpy(client_ethaddr, ethaddr, ETH_ALEN);
1916
if (GuestIP != INADDR_ANY)
1918
slirp_arp_cache_update_or_add(pData, GuestIP, ethaddr);
1919
activate_port_forwarding(pData, ethaddr);
1652
1923
#if defined(RT_OS_WINDOWS)