Changeset 25276 in vbox
- Timestamp:
- Dec 9, 2009 4:23:51 PM (15 years ago)
- Location:
- trunk/src/VBox/Devices/Network/slirp
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/bootp.c
r25265 r25276 40 40 /* XXX: only DHCP is supported */ 41 41 static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE }; 42 static void bootp_reply(PNATState pData, struct mbuf *m0, int off, uint16_t flags); 42 43 static void bootp_reply(PNATState pData, struct mbuf *m0, int offReply, uint16_t flags); 43 44 44 45 static uint8_t *dhcp_find_option(uint8_t *vend, uint8_t tag) … … 60 61 return NULL; 61 62 } 63 62 64 static BOOTPClient *bc_alloc_client(PNATState pData) 63 65 { … … 78 80 return NULL; 79 81 } 82 80 83 static BOOTPClient *get_new_addr(PNATState pData, struct in_addr *paddr) 81 84 { 82 85 BOOTPClient *bc; 83 86 bc = bc_alloc_client(pData); 84 if ( bc == NULL)87 if (!bc) 85 88 return NULL; 89 86 90 paddr->s_addr = htonl(ntohl(pData->special_addr.s_addr) | (bc->number + START_ADDR)); 87 91 bc->addr.s_addr = paddr->s_addr; … … 97 101 { 98 102 memset(&bootp_clients[i], 0, sizeof(BOOTPClient)); 99 return 1;100 } 101 } 102 return 0;103 return VINF_SUCCESS; 104 } 105 } 106 return VERR_NOT_FOUND; 103 107 } 104 108 … … 205 209 } 206 210 207 static int dhcp_do_ack_offer(PNATState pData, struct mbuf *m, BOOTPClient *bc, int is_from_request) 208 { 209 int off = 0; 211 static int dhcp_do_ack_offer(PNATState pData, struct mbuf *m, BOOTPClient *bc, int fDhcpRequest) 212 { 210 213 struct bootp_t *rbp = NULL; 211 214 uint8_t *q; … … 236 239 rbp->bp_siaddr = pData->tftp_server; /* Next Server IP address, i.e. TFTP */ 237 240 Log(("NAT: DHCP: bp_siaddr:%R[IP4]\n", &rbp->bp_siaddr)); 238 if ( is_from_request)241 if (fDhcpRequest) 239 242 { 240 243 rbp->bp_ciaddr.s_addr = bc->addr.s_addr; /* Client IP address */ … … 331 334 332 335 dhcp_create_msg(pData, bp, m, DHCPNAK); 333 334 336 return 7; 335 337 } 336 static int dhcp_send_ack(PNATState pData, struct bootp_t *bp, BOOTPClient *bc, struct mbuf *m, int is_from_request) 338 339 static int dhcp_send_ack(PNATState pData, struct bootp_t *bp, BOOTPClient *bc, struct mbuf *m, int fDhcpRequest) 337 340 { 338 341 struct bootp_t *rbp; 339 int off = 0; /* boot_reply will fill general options and add END before sending response*/342 int offReply = 0; /* boot_reply will fill general options and add END before sending response */ 340 343 341 344 dhcp_create_msg(pData, bp, m, DHCPACK); 342 off = dhcp_do_ack_offer(pData, m, bc, is_from_request); 343 return off; 344 } 345 offReply = dhcp_do_ack_offer(pData, m, bc, fDhcpRequest); 346 return offReply; 347 } 348 345 349 static int dhcp_send_offer(PNATState pData, struct bootp_t *bp, BOOTPClient *bc, struct mbuf *m) 346 350 { 347 int off = 0; /* boot_reply will fill general options and add END before sending response*/351 int offReply = 0; /* boot_reply will fill general options and add END before sending response */ 348 352 349 353 dhcp_create_msg(pData, bp, m, DHCPOFFER); 350 off = dhcp_do_ack_offer(pData, m, bc,0);351 return off ;354 offReply = dhcp_do_ack_offer(pData, m, bc, /* fDhcpRequest=*/ 0); 355 return offReply; 352 356 } 353 357 … … 364 368 * 365 369 */ 366 enum DHCP_REQUEST_STATES{INIT_REBOOT, SELECTING, RENEWING, REBINDING, NONE}; 370 371 enum DHCP_REQUEST_STATES 372 { 373 INIT_REBOOT, 374 SELECTING, 375 RENEWING, 376 REBINDING, 377 NONE 378 }; 379 367 380 static int dhcp_decode_request(PNATState pData, struct bootp_t *bp, const uint8_t *buf, int size, struct mbuf *m) 368 381 { 369 382 BOOTPClient *bc = NULL; 370 383 struct in_addr daddr; 371 int off ;384 int offReply; 372 385 uint8_t *opt; 373 386 uint8_t *req_ip = NULL; … … 375 388 uint32_t ui32; 376 389 enum DHCP_REQUEST_STATES dhcp_stat = NONE; 377 /*need to understand which type of request we get */ 390 391 /* need to understand which type of request we get */ 378 392 req_ip = dhcp_find_option(&bp->bp_vend[0], RFC2132_REQ_ADDR); 379 393 server_ip = dhcp_find_option(&bp->bp_vend[0], RFC2132_SRV_ID); … … 382 396 if (server_ip != NULL) 383 397 { 384 /* selecting*/398 /* selecting */ 385 399 if (!bc) 386 400 { 387 LogRel(("NAT: DHCP no IP was n'tallocated\n"));401 LogRel(("NAT: DHCP no IP was allocated\n")); 388 402 return -1; 389 403 } 404 390 405 dhcp_stat = SELECTING; 391 406 Assert((bp->bp_ciaddr.s_addr == INADDR_ANY)); … … 412 427 } 413 428 } 414 /*?? renewing ??*/ 429 430 /*?? renewing ??*/ 415 431 switch (dhcp_stat) 416 432 { 417 433 case RENEWING: 418 { 419 Assert(( server_ip == NULL 420 && req_ip == NULL 421 && bp->bp_ciaddr.s_addr != INADDR_ANY)); 434 Assert((server_ip == NULL && req_ip == NULL && bp->bp_ciaddr.s_addr != INADDR_ANY)); 422 435 if (bc != NULL) 423 436 { … … 429 442 if ((bp->bp_ciaddr.s_addr & htonl(pData->netmask)) != pData->special_addr.s_addr) 430 443 { 431 off = dhcp_send_nack(pData, bp, bc, m); 432 return off; 444 LogRel(("NAT: Client %R[IP4] requested IP -- sending NAK\n", &bp->bp_ciaddr)); 445 offReply = dhcp_send_nack(pData, bp, bc, m); 446 return offReply; 433 447 } 448 434 449 bc = bc_alloc_client(pData); 435 if ( bc == NULL)450 if (!bc) 436 451 { 437 LogRel(("NAT: can't alloc address. RENEW has been silently ignored \n"));452 LogRel(("NAT: can't alloc address. RENEW has been silently ignored.\n")); 438 453 return -1; 439 454 } 455 440 456 Assert((bp->bp_hlen == ETH_ALEN)); 441 457 memcpy(bc->macaddr, bp->bp_hwaddr, bp->bp_hlen); … … 443 459 slirp_arp_cache_update(pData, bp->bp_ciaddr.s_addr, bp->bp_hwaddr); 444 460 } 445 }446 break; 461 break; 462 447 463 case INIT_REBOOT: 448 464 Assert(server_ip == NULL); … … 451 467 if ((ui32 & htonl(pData->netmask)) != pData->special_addr.s_addr) 452 468 { 453 LogRel(("NAT: address %R[IP4] has been req .\n", &ui32));454 off= dhcp_send_nack(pData, bp, bc, m);455 return off;469 LogRel(("NAT: address %R[IP4] has been requested -- sending NAK\n", &ui32)); 470 offReply = dhcp_send_nack(pData, bp, bc, m); 471 return offReply; 456 472 } 473 457 474 bc = bc_alloc_client(pData); 458 if ( bc == NULL)475 if (!bc) 459 476 { 460 477 LogRel(("NAT: can't alloc address. RENEW has been silently ignored\n")); … … 465 482 bc->addr.s_addr = ui32; 466 483 slirp_arp_cache_update(pData, bp->bp_ciaddr.s_addr, bp->bp_hwaddr); 467 break; 484 break; 485 468 486 case NONE: 469 487 Assert((dhcp_stat != NONE)); 470 488 return -1; 489 471 490 default: 472 break; 473 } 474 off = dhcp_send_ack(pData, bp, bc, m, 1); 475 return off; 476 } 477 478 static int dhcp_decode_discover(PNATState pData, struct bootp_t *bp, const uint8_t *buf, int size, int flag, struct mbuf *m) 491 break; 492 } 493 494 LogRel(("NAT: DHCP offered IP address %R[IP4]\n", &bc->addr)); 495 offReply = dhcp_send_ack(pData, bp, bc, m, /* fDhcpRequest=*/ 1); 496 return offReply; 497 } 498 499 static int dhcp_decode_discover(PNATState pData, struct bootp_t *bp, const uint8_t *buf, int size, int fDhcpDiscover, struct mbuf *m) 479 500 { 480 501 BOOTPClient *bc; 481 502 struct in_addr daddr; 482 int off ;483 /* flag == 1 discover */ 484 if (f lag == 1)503 int offReply; 504 505 if (fDhcpDiscover) 485 506 { 486 507 bc = find_addr(pData, &daddr, bp->bp_hwaddr); … … 496 517 memcpy(bc->macaddr, bp->bp_hwaddr, 6); 497 518 } 519 498 520 bc->xid = bp->bp_xid; 499 /*bc isn't NULL */500 off = dhcp_send_offer(pData, bp, bc, m);501 return off ;521 LogRel(("NAT: DHCP offered IP address %R[IP4]\n", &bc->addr)); 522 offReply = dhcp_send_offer(pData, bp, bc, m); 523 return offReply; 502 524 } 503 525 else 504 526 { 505 /* flag == 0 inform */506 527 bc = find_addr(pData, &daddr, bp->bp_hwaddr); 507 if ( bc == NULL)528 if (!bc) 508 529 { 509 530 LogRel(("NAT: DHCP Inform was ignored no boot client was found\n")); 510 531 return -1; 511 532 } 512 off = dhcp_send_ack(pData, bp, bc, m, 0); 513 return off; 514 } 533 534 LogRel(("NAT: DHCP offered IP address %R[IP4]\n", &bc->addr)); 535 offReply = dhcp_send_ack(pData, bp, bc, m, /* fDhcpRequest=*/ 0); 536 return offReply; 537 } 538 515 539 return -1; 516 540 } … … 518 542 static int dhcp_decode_release(PNATState pData, struct bootp_t *bp, const uint8_t *buf, int size) 519 543 { 520 release_addr(pData, &bp->bp_ciaddr); 544 int rc = release_addr(pData, &bp->bp_ciaddr); 545 LogRel(("NAT: %s %R[IP4]\n", 546 RT_SUCCESS(rc) ? "DHCP released IP address" : "Ignored DHCP release for IP address", 547 &bp->bp_ciaddr)); 521 548 return 0; 522 549 } … … 592 619 int pmsg_type; 593 620 struct in_addr req_ip; 594 int f lag= 0;621 int fDhcpDiscover = 0; 595 622 int len, tag; 596 623 struct mbuf *m = NULL; … … 619 646 return; 620 647 } 648 621 649 switch (*(p+2)) 622 650 { 623 651 case DHCPDISCOVER: 624 f lag= 1;652 fDhcpDiscover = 1; 625 653 /**/ 626 654 case DHCPINFORM: 627 rc = dhcp_decode_discover(pData, bp, buf, size, f lag, m);655 rc = dhcp_decode_discover(pData, bp, buf, size, fDhcpDiscover, m); 628 656 if (rc > 0) 629 657 goto reply; … … 671 699 } 672 700 673 static void bootp_reply(PNATState pData, struct mbuf *m, int off , uint16_t flags)701 static void bootp_reply(PNATState pData, struct mbuf *m, int offReply, uint16_t flags) 674 702 { 675 703 struct sockaddr_in saddr, daddr; … … 682 710 q = rbp->bp_vend; 683 711 nack = (q[6] == DHCPNAK); 684 q += off ;712 q += offReply; 685 713 686 714 #ifndef VBOX_WITH_NAT_SERVICE … … 692 720 FILL_BOOTP_EXT(q, RFC2132_SRV_ID, 4, &saddr.sin_addr); 693 721 694 695 *q++ = RFC1533_END; /*end of message */ 696 722 *q++ = RFC1533_END; /* end of message */ 697 723 698 724 #ifdef VBOX_WITH_SLIRP_BSD_MBUF … … 725 751 int i; 726 752 727 if ( ether == NULL || pip == NULL)753 if (!ether || !pip) 728 754 return VERR_INVALID_PARAMETER; 729 755 -
trunk/src/VBox/Devices/Network/slirp/ip_input.c
r23369 r25276 233 233 STAM_PROFILE_STOP(&pData->StatIP_input, a); 234 234 return; 235 235 236 bad: 236 237 Log2(("NAT: IP datagram to %R[IP4] with size(%d) claimed as bad\n", -
trunk/src/VBox/Devices/Network/slirp/slirp.c
r25266 r25276 194 194 #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) 195 195 196 static void activate_port_forwarding(PNATState, struct ethhdr *);196 static void activate_port_forwarding(PNATState, uint8_t *pEther); 197 197 198 198 static const uint8_t special_ethaddr[6] = … … 662 662 { 663 663 struct socket *so; 664 struct port_forward_rule *rule = NULL; 664 665 665 666 while ((so = tcb.so_next) != &tcb) … … 673 674 while ((so = udb.so_next) != &udb) 674 675 udp_detach(pData, so); 676 677 /* 678 * Clear the active state of port-forwarding rules to force 679 * re-setup on restoration of communications. 680 */ 681 LIST_FOREACH(rule, &pData->port_forward_rule_head, list) 682 { 683 rule->activated = 0; 684 } 685 pData->cRedirectionsActive = 0; 675 686 676 687 link_up = 0; … … 1516 1527 slirp_arp_cache_add(pData, *(uint32_t *)ah->ar_tip, &eh->h_dest[0]); 1517 1528 /* good opportunity to activate port-forwarding on address (self)asignment*/ 1518 if (pData-> port_forwarding_activated != pData->port_forwarding_count)1519 activate_port_forwarding(pData, eh );1529 if (pData->cRedirectionsActive != pData->cRedirectionsStored) 1530 activate_port_forwarding(pData, eh->h_source); 1520 1531 } 1521 1532 break; … … 1529 1540 slirp_arp_cache_add(pData, *(uint32_t *)ah->ar_sip, ah->ar_sha); 1530 1541 /* after/save restore we need up port forwarding again */ 1531 if (pData-> port_forwarding_activated != pData->port_forwarding_count)1532 activate_port_forwarding(pData, eh );1542 if (pData->cRedirectionsActive != pData->cRedirectionsStored) 1543 activate_port_forwarding(pData, eh->h_source); 1533 1544 m_free(pData, m); 1534 1545 break; … … 1554 1565 struct ethhdr *eh; 1555 1566 #endif 1567 uint8_t au8Ether[ETH_ALEN]; 1556 1568 1557 1569 #ifndef VBOX_WITH_SLIRP_BSD_MBUF … … 1607 1619 /* Note: we add to align the IP header */ 1608 1620 1609 if (pData->port_forwarding_activated != pData->port_forwarding_count) 1610 activate_port_forwarding(pData, mtod(m, struct ethhdr *)); 1621 memcpy(au8Ether, eh->h_source, ETH_ALEN); 1611 1622 1612 1623 switch(proto) … … 1653 1664 } 1654 1665 1666 if (pData->cRedirectionsActive != pData->cRedirectionsStored) 1667 activate_port_forwarding(pData, au8Ether); 1668 1655 1669 #ifdef VBOX_WITH_SLIRP_BSD_MBUF 1656 1670 RTMemFree((void *)pkt); … … 1729 1743 uint32_t ip = INADDR_ANY; 1730 1744 int rc; 1731 1745 1732 1746 if (eth_addr == NULL) 1733 1747 return INADDR_ANY; … … 1752 1766 * @todo finish this for service case 1753 1767 */ 1754 static void activate_port_forwarding(PNATState pData, struct ethhdr *ethdr)1768 static void activate_port_forwarding(PNATState pData, uint8_t *h_source) 1755 1769 { 1756 1770 struct port_forward_rule *rule = NULL; … … 1771 1785 1772 1786 if (rule->activated) 1773 continue; /*already activated */ 1787 continue; 1788 1774 1789 #ifdef VBOX_WITH_NAT_SERVICE 1775 if (memcmp(rule->mac_address, ethdr->h_source, ETH_ALEN) != 0)1790 if (memcmp(rule->mac_address, h_source, ETH_ALEN) != 0) 1776 1791 continue; /*not right mac, @todo: it'd be better do the list port forwarding per mac */ 1777 guest_addr = find_guest_ip(pData, ethdr->h_source);1792 guest_addr = find_guest_ip(pData, h_source); 1778 1793 #else 1779 1794 #if 0 1780 if (memcmp(client_ethaddr, ethdr->h_source, ETH_ALEN) != 0)1795 if (memcmp(client_ethaddr, h_source, ETH_ALEN) != 0) 1781 1796 continue; 1782 1797 #endif 1783 guest_addr = find_guest_ip(pData, ethdr->h_source);1798 guest_addr = find_guest_ip(pData, h_source); 1784 1799 #endif 1785 1800 if (guest_addr == INADDR_ANY) … … 1788 1803 return; 1789 1804 } 1805 1790 1806 #if !defined(VBOX_WITH_NAT_SERVICE) 1791 1807 if (rule->guest_addr.s_addr != guest_addr) … … 1793 1809 #endif 1794 1810 1795 LogRel(("NAT: set redirect %s hp:%d gp:%d\n", (rule->proto == IPPROTO_UDP?"UDP":"TCP"), 1796 rule->host_port, rule->guest_port)); 1811 LogRel(("NAT: set redirect %s host port %d => guest port %d @ %R[IP4]\n", 1812 (rule->proto == IPPROTO_UDP?"UDP":"TCP"), 1813 rule->host_port, rule->guest_port, &guest_addr)); 1797 1814 1798 1815 if (rule->proto == IPPROTO_UDP) 1799 {1800 1816 so = udp_listen(pData, rule->bind_ip.s_addr, htons(rule->host_port), guest_addr, 1801 1817 htons(rule->guest_port), 0); 1802 pData->port_forwarding_activated++;1803 }1804 1818 else 1805 {1806 1819 so = solisten(pData, rule->bind_ip.s_addr, htons(rule->host_port), guest_addr, 1807 1820 htons(rule->guest_port), 0); 1808 pData->port_forwarding_activated++;1809 }1810 1821 1811 1822 if (so == NULL) 1812 {1813 LogRel(("NAT: failed redirect %s hp:%d gp:%d\n", (rule->proto == IPPROTO_UDP?"UDP":"TCP"),1814 rule->host_port, rule->guest_port));1815 1823 goto remove_port_forwarding; 1816 }1817 1824 1818 1825 psin = (struct sockaddr_in *)&sa; … … 1824 1831 rc = getsockname(so->s, &sa, &socketlen); 1825 1832 if (rc < 0 || sa.sa_family != AF_INET) 1826 {1827 LogRel(("NAT: failed redirect %s hp:%d gp:%d\n", (rule->proto == IPPROTO_UDP?"UDP":"TCP"),1828 rule->host_port, rule->guest_port));1829 1833 goto remove_port_forwarding; 1830 }1831 1834 1832 1835 psin = (struct sockaddr_in *)&sa; … … 1844 1847 rule->proto); 1845 1848 if (!link) 1846 {1847 LogRel(("NAT: failed redirect %s hp:%d gp:%d\n", (rule->proto == IPPROTO_UDP?"UDP":"TCP"),1848 rule->host_port, rule->guest_port));1849 1849 goto remove_port_forwarding; 1850 }1851 1850 1852 1851 so->so_la = lib; 1853 1852 rule->activated = 1; 1853 pData->cRedirectionsActive++; 1854 1854 continue; 1855 1855 1856 1856 remove_port_forwarding: 1857 LogRel(("NAT: failed to redirect %s %d => %d\n", 1858 (rule->proto == IPPROTO_UDP?"UDP":"TCP"), rule->host_port, rule->guest_port)); 1857 1859 LIST_REMOVE(rule, list); 1858 pData-> port_forwarding_count--;1860 pData->cRedirectionsStored--; 1859 1861 RTMemFree(rule); 1860 1862 } … … 1878 1880 struct port_forward_rule *rule = NULL; 1879 1881 Assert(memcmp(ethaddr, zerro_ethaddr, ETH_ALEN) == 0); 1882 1880 1883 rule = RTMemAllocZ(sizeof(struct port_forward_rule)); 1881 1884 if (rule == NULL) 1882 1885 return 1; 1886 1883 1887 rule->proto = (is_udp ? IPPROTO_UDP : IPPROTO_TCP); 1884 1888 rule->host_port = host_port; … … 1891 1895 /* @todo add mac address */ 1892 1896 LIST_INSERT_HEAD(&pData->port_forward_rule_head, rule, list); 1893 pData-> port_forwarding_count++;1897 pData->cRedirectionsStored++; 1894 1898 return 0; 1895 1899 } 1896 1900 1897 1901 int slirp_add_exec(PNATState pData, int do_pty, const char *args, int addr_low_byte, 1898 int guest_port)1902 int guest_port) 1899 1903 { 1900 1904 return add_exec(&exec_list, do_pty, (char *)args, … … 1999 2003 } 2000 2004 else 2001 {2002 2005 LogRel(("NAT: Host Resolver conflicts with DNS proxy, the last one was forcely ignored\n")); 2003 }2004 2006 } 2005 2007 … … 2013 2015 } \ 2014 2016 else \ 2015 { \2016 2017 LogRel(("NAT: (" #name ":%d)\n", (val))); \ 2017 } \2018 2018 } while (0) 2019 2019 -
trunk/src/VBox/Devices/Network/slirp/slirp_state.h
r25265 r25276 318 318 LIST_HEAD(handler_chain, proto_handler) handler_chain; 319 319 struct port_forward_rule_list port_forward_rule_head; 320 int port_forwarding_activated;321 int port_forwarding_count;320 int cRedirectionsActive; 321 int cRedirectionsStored; 322 322 struct arp_cache_head arp_cache; 323 323 /*libalis modules' handlers*/
Note:
See TracChangeset
for help on using the changeset viewer.