- Timestamp:
- Aug 6, 2009 10:37:24 AM (15 years ago)
- Location:
- trunk/src/VBox/Devices/Network
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DrvNAT.cpp
r21659 r22020 691 691 static int drvNATConstructRedir(unsigned iInstance, PDRVNAT pThis, PCFGMNODE pCfgHandle, RTIPV4ADDR Network) 692 692 { 693 RTMAC Mac; 694 memset(&Mac, 0, sizeof(RTMAC)); /*can't get MAC here */ 693 695 /* 694 696 * Enumerate redirections. … … 741 743 struct in_addr BindIP; 742 744 GETIP_DEF(rc, pThis, pNode, BindIP, INADDR_ANY); 743 if (slirp_redir(pThis->pNATState, fUDP, BindIP, iHostPort, GuestIP, iGuestPort ) < 0)745 if (slirp_redir(pThis->pNATState, fUDP, BindIP, iHostPort, GuestIP, iGuestPort, Mac.au8) < 0) 744 746 return PDMDrvHlpVMSetError(pThis->pDrvIns, VERR_NAT_REDIR_SETUP, RT_SRC_POS, 745 747 N_("NAT#%d: configuration error: failed to set up " -
trunk/src/VBox/Devices/Network/slirp/ip_output.c
r22013 r22020 50 50 { 51 51 int i; 52 /* @todo ( r -vasily) to quick ramp up on routing rails52 /* @todo (vasily) to quick ramp up on routing rails 53 53 * we use information from DHCP server leasings, this 54 54 * code couldn't detect any changes in network topology -
trunk/src/VBox/Devices/Network/slirp/libslirp.h
r21004 r22020 58 58 int slirp_redir(PNATState pData, int is_udp, struct in_addr host_addr, 59 59 int host_port, struct in_addr guest_addr, 60 int guest_port );60 int guest_port, const uint8_t *); 61 61 int slirp_add_exec(PNATState pData, int do_pty, const char *args, int addr_low_byte, 62 62 int guest_port); -
trunk/src/VBox/Devices/Network/slirp/slirp.c
r22014 r22020 189 189 #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) 190 190 191 static void acivate_port_forwarding(PNATState, struct ethhdr *); 192 static in_addr_t find_guest_ip(PNATState, uint8_t *); 193 191 194 static const uint8_t special_ethaddr[6] = 192 195 { … … 1444 1447 m->m_len = pkt_len ; 1445 1448 memcpy(m->m_data, pkt, pkt_len); 1449 1450 if (pData->port_forwarding_activated == 0) 1451 acivate_port_forwarding(pData, mtod(m, struct ethhdr *)); 1446 1452 1447 1453 proto = ntohs(*(uint16_t *)(pkt + 12)); … … 1510 1516 #endif 1511 1517 eh->h_proto = htons(eth_proto); 1512 #if 01513 slirp_output(pData->pvUser, m, mtod(m, uint8_t *), m->m_len);1514 #else1515 1518 memcpy(buf, mtod(m, uint8_t *), m->m_len); 1516 1519 slirp_output(pData->pvUser, NULL, buf, m->m_len); … … 1518 1521 STAM_PROFILE_STOP(&pData->StatIF_encap, a); 1519 1522 m_free(pData, m); 1520 #endif 1521 } 1522 1523 } 1524 1525 /** 1526 * Still we're using dhcp server leasing to map ether to IP 1527 * @todo see rt_lookup_in_cache 1528 */ 1529 static in_addr_t find_guest_ip(PNATState pData, uint8_t *eth_addr) 1530 { 1531 int i; 1532 if (memcmp(eth_addr, zerro_ethaddr, ETH_ALEN) == 0 1533 || memcmp(eth_addr, broadcast_ethaddr, ETH_ALEN) == 0) 1534 goto done; 1535 for (i = 0; i < NB_ADDR; i++) 1536 { 1537 if ( bootp_clients[i].allocated 1538 && memcmp(bootp_clients[i].macaddr, eth_addr, ETH_ALEN) == 0) 1539 return bootp_clients[i].addr.s_addr; 1540 } 1541 done: 1542 return INADDR_ANY; 1543 } 1544 1545 /** 1546 * We need check if we've activated port forwarding 1547 * for specific machine ... that of course relates to 1548 * service mode 1549 * @todo finish this for service case 1550 */ 1551 static void acivate_port_forwarding(PNATState pData, struct ethhdr *ethdr) 1552 { 1553 struct port_forward_rule *rule = NULL; 1554 1555 pData->port_forwarding_activated = 1; 1556 /* check mac here */ 1557 LIST_FOREACH(rule, &pData->port_forward_rule_head, list) 1558 { 1559 struct socket *so; 1560 struct alias_link *link; 1561 struct libalias *lib; 1562 int flags; 1563 struct sockaddr sa; 1564 struct sockaddr_in *psin; 1565 socklen_t socketlen; 1566 struct in_addr alias; 1567 int rc; 1568 in_addr_t guest_addr; /* need to understand if we already give address to guest */ 1569 1570 if (rule->activated) 1571 continue; /*already activated */ 1572 #ifdef VBOX_WITH_NAT_SERVICE 1573 if (memcmp(rule->mac_address, ethdr->h_source, ETH_ALEN) != 0) 1574 continue; /*not right mac, @todo: it'd be better do the list port forwarding per mac */ 1575 guest_addr = find_guest_ip(pData, ethdr->h_source); 1576 #else 1577 if (memcmp(client_ethaddr, ethdr->h_source, ETH_ALEN) != 0) 1578 continue; 1579 guest_addr = find_guest_ip(pData, ethdr->h_source); 1580 Assert(rule->guest_addr.s_addr == guest_addr); 1581 #endif 1582 if (guest_addr == INADDR_ANY) 1583 { 1584 /* the address wasn't granted */ 1585 pData->port_forwarding_activated = 0; 1586 return; 1587 } 1588 1589 LogRel(("NAT: set redirect %s hp:%d gp:%d\n", (rule->proto == IPPROTO_UDP?"UDP":"TCP"), 1590 rule->host_port, rule->guest_port)); 1591 if (rule->proto == IPPROTO_UDP) 1592 { 1593 so = udp_listen(pData, rule->bind_ip.s_addr, htons(rule->host_port), guest_addr, 1594 htons(rule->guest_port), 0); 1595 } 1596 else 1597 { 1598 so = solisten(pData, rule->bind_ip.s_addr, htons(rule->host_port), guest_addr, 1599 htons(rule->guest_port), 0); 1600 } 1601 if (so == NULL) 1602 { 1603 LogRel(("NAT: failed redirect %s hp:%d gp:%d\n", (rule->proto == IPPROTO_UDP?"UDP":"TCP"), 1604 rule->host_port, rule->guest_port)); 1605 goto remove_port_forwarding; 1606 } 1607 1608 psin = (struct sockaddr_in *)&sa; 1609 psin->sin_family = AF_INET; 1610 psin->sin_port = 0; 1611 psin->sin_addr.s_addr = INADDR_ANY; 1612 socketlen = sizeof(struct sockaddr); 1613 1614 rc = getsockname(so->s, &sa, &socketlen); 1615 if (rc < 0 || sa.sa_family != AF_INET) 1616 { 1617 LogRel(("NAT: failed redirect %s hp:%d gp:%d\n", (rule->proto == IPPROTO_UDP?"UDP":"TCP"), 1618 rule->host_port, rule->guest_port)); 1619 goto remove_port_forwarding; 1620 } 1621 1622 psin = (struct sockaddr_in *)&sa; 1623 1624 lib = LibAliasInit(pData, NULL); 1625 flags = LibAliasSetMode(lib, 0, 0); 1626 flags |= PKT_ALIAS_LOG; /* set logging */ 1627 flags |= PKT_ALIAS_REVERSE; /* set logging */ 1628 flags = LibAliasSetMode(lib, flags, ~0); 1629 1630 alias.s_addr = htonl(ntohl(guest_addr) | CTL_ALIAS); 1631 link = LibAliasRedirectPort(lib, psin->sin_addr, htons(rule->host_port), 1632 alias, htons(rule->guest_port), 1633 special_addr, -1, /* not very clear for now*/ 1634 rule->proto); 1635 if (link == NULL) 1636 { 1637 LogRel(("NAT: failed redirect %s hp:%d gp:%d\n", (rule->proto == IPPROTO_UDP?"UDP":"TCP"), 1638 rule->host_port, rule->guest_port)); 1639 goto remove_port_forwarding; 1640 } 1641 so->so_la = lib; 1642 rule->activated = 1; 1643 continue; 1644 remove_port_forwarding: 1645 LIST_REMOVE(rule, list); 1646 RTMemFree(rule); 1647 } 1648 } 1649 1650 /** 1651 * Changes in 3.1 instead of opening new socket do the following: 1652 * gain more information: 1653 * 1. bind IP 1654 * 2. host port 1655 * 3. guest port 1656 * 4. proto 1657 * 5. guest MAC address 1658 * the guest's MAC address is rather important for service, but we easily 1659 * could get it from VM configuration in DrvNAT or Service, the idea is activating 1660 * corresponding port-forwarding 1661 */ 1523 1662 int slirp_redir(PNATState pData, int is_udp, struct in_addr host_addr, int host_port, 1524 struct in_addr guest_addr, int guest_port) 1525 { 1526 struct socket *so; 1527 struct alias_link *link; 1528 struct libalias *lib; 1529 int flags; 1530 struct sockaddr sa; 1531 struct sockaddr_in *psin; 1532 socklen_t socketlen; 1533 struct in_addr alias; 1534 int rc; 1535 1536 Log2(("NAT: set redirect %s hp:%d gp:%d\n", (is_udp?"UDP":"TCP"), host_port, guest_port)); 1537 if (is_udp) 1538 { 1539 so = udp_listen(pData, host_addr.s_addr, htons(host_port), guest_addr.s_addr, 1540 htons(guest_port), 0); 1541 } 1542 else 1543 { 1544 so = solisten(pData, host_addr.s_addr, htons(host_port), guest_addr.s_addr, 1545 htons(guest_port), 0); 1546 } 1547 if (so == NULL) 1548 { 1549 return -1; 1550 } 1551 1552 psin = (struct sockaddr_in *)&sa; 1553 psin->sin_family = AF_INET; 1554 psin->sin_port = 0; 1555 psin->sin_addr.s_addr = INADDR_ANY; 1556 socketlen = sizeof(struct sockaddr); 1557 1558 rc = getsockname(so->s, &sa, &socketlen); 1559 if (rc < 0 || sa.sa_family != AF_INET) 1560 { 1561 Log(("NAT: can't get socket's name\n")); 1663 struct in_addr guest_addr, int guest_port, const uint8_t *ethaddr) 1664 { 1665 struct port_forward_rule *rule = NULL; 1666 Assert(memcmp(ethaddr, zerro_ethaddr, ETH_ALEN) == 0); 1667 rule = RTMemAllocZ(sizeof(struct port_forward_rule)); 1668 if (rule == NULL) 1562 1669 return 1; 1563 } 1564 1565 psin = (struct sockaddr_in *)&sa; 1566 1567 #if 1 1568 lib = LibAliasInit(pData, NULL); 1569 flags = LibAliasSetMode(lib, 0, 0); 1570 flags |= PKT_ALIAS_LOG; /* set logging */ 1571 flags |= PKT_ALIAS_REVERSE; /* set logging */ 1572 flags = LibAliasSetMode(lib, flags, ~0); 1573 #else 1574 lib = LIST_FIRST(&instancehead); 1575 #endif 1576 1577 alias.s_addr = htonl(ntohl(guest_addr.s_addr) | CTL_ALIAS); 1578 link = LibAliasRedirectPort(lib, psin->sin_addr, htons(host_port), 1579 alias, htons(guest_port), 1580 special_addr, -1, /* not very clear for now*/ 1581 (is_udp ? IPPROTO_UDP : IPPROTO_TCP)); 1582 if (link == NULL) 1583 { 1584 Log(("NAT: can't create redirect\n")); 1585 return 1; 1586 } 1587 so->so_la = lib; 1588 1670 rule->proto = (is_udp ? IPPROTO_UDP : IPPROTO_TCP); 1671 rule->host_port = host_port; 1672 rule->guest_port = guest_port; 1673 #ifndef VBOX_WITH_NAT_SERVICE 1674 rule->guest_addr.s_addr = guest_addr.s_addr; 1675 #endif 1676 rule->bind_ip.s_addr = host_addr.s_addr; 1677 memcmp(rule->mac_address, ethaddr, ETH_ALEN); 1678 /* @todo add mac address */ 1679 LIST_INSERT_HEAD(&pData->port_forward_rule_head, rule, list); 1589 1680 return 0; 1590 1681 } … … 1599 1690 void slirp_set_ethaddr(PNATState pData, const uint8_t *ethaddr) 1600 1691 { 1601 #ifndef VBOX_WITH OUT_SLIRP_CLIENT_ETHER1692 #ifndef VBOX_WITH_NAT_SERVICE 1602 1693 memcpy(client_ethaddr, ethaddr, ETH_ALEN); 1603 1694 #endif -
trunk/src/VBox/Devices/Network/slirp/slirp_state.h
r22013 r22020 71 71 }; 72 72 TAILQ_HEAD(dns_list_head, dns_entry); 73 74 struct port_forward_rule 75 { 76 uint16_t proto; 77 uint16_t host_port; 78 uint16_t guest_port; 79 #ifndef VBOX_WITH_NAT_SERVICE 80 struct in_addr guest_addr; 81 #endif 82 struct in_addr bind_ip; 83 uint8_t mac_address[6]; /*need ETH_ALEN here */ 84 int activated; 85 LIST_ENTRY(port_forward_rule) list; 86 }; 87 LIST_HEAD(port_forward_rule_list, port_forward_rule); 73 88 74 89 /** Main state/configuration structure for slirp NAT. */ … … 130 145 uint8_t client_ethaddr[6]; 131 146 #else 147 # ifndef VBOX_WITH_NAT_SERVICE 148 uint8_t client_ethaddr[6]; 149 # endif 132 150 const uint8_t *slirp_ethaddr; 133 151 #endif … … 229 247 struct libalias *proxy_alias; 230 248 LIST_HEAD(handler_chain, proto_handler) handler_chain; 249 struct port_forward_rule_list port_forward_rule_head; 250 int port_forwarding_activated; 231 251 232 252 #define PROFILE_COUNTER(name, dsc) STAMPROFILE Stat ## name
Note:
See TracChangeset
for help on using the changeset viewer.