Changeset 22013 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Aug 6, 2009 3:23:44 AM (15 years ago)
- Location:
- trunk/src/VBox/Devices/Network/slirp
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/counters.h
r21698 r22013 77 77 PROFILE_COUNTER(IP_output, "IP::output"); 78 78 PROFILE_COUNTER(IF_encap, "IF::encap"); 79 #ifdef VBOX_WITH_SLIRP_ALIAS80 79 PROFILE_COUNTER(ALIAS_input, "ALIAS::input"); 81 80 PROFILE_COUNTER(ALIAS_output, "ALIAS::output"); 82 #endif83 81 -
trunk/src/VBox/Devices/Network/slirp/ip_input.c
r21717 r22013 45 45 #include <slirp.h> 46 46 #include "ip_icmp.h" 47 #ifdef VBOX_WITH_SLIRP_ALIAS 48 # include "alias.h" 49 #endif 47 #include "alias.h" 50 48 51 49 … … 86 84 87 85 ipstat.ips_total++; 88 #ifdef VBOX_WITH_SLIRP_ALIAS89 86 { 90 87 int rc; … … 95 92 Log2(("NAT: LibAlias return %d\n", rc)); 96 93 } 97 #endif98 94 99 95 if (m->m_len < sizeof(struct ip)) -
trunk/src/VBox/Devices/Network/slirp/ip_output.c
r21716 r22013 44 44 45 45 #include <slirp.h> 46 #ifdef VBOX_WITH_SLIRP_ALIAS 47 # include "alias.h" 48 #endif 46 #include "alias.h" 49 47 50 48 #ifdef VBOX_WITHOUT_SLIRP_CLIENT_ETHER … … 151 149 } 152 150 #endif 153 #ifdef VBOX_WITH_SLIRP_ALIAS154 151 { 155 152 int rc; … … 160 157 STAM_PROFILE_STOP(&pData->StatALIAS_output, a); 161 158 } 162 #endif163 159 164 160 if_output(pData, so, m); … … 255 251 ip->ip_sum = 0; 256 252 ip->ip_sum = cksum(m, hlen); 257 #ifdef VBOX_WITH_SLIRP_ALIAS258 253 { 259 254 int rc; … … 264 259 STAM_PROFILE_STOP(&pData->StatALIAS_output, a); 265 260 } 266 #endif267 261 268 262 sendorfree: … … 272 266 m->m_nextpkt = 0; 273 267 if (error == 0) 274 {275 #ifdef VBOX_WITH_SLIRP_ALIAS276 268 { 277 269 int rc; … … 279 271 mtod(m, char *), m->m_len); 280 272 Log2(("NAT: LibAlias return %d\n", rc)); 281 }282 #endif283 273 if_output(pData, so, m); 284 274 } -
trunk/src/VBox/Devices/Network/slirp/mbuf.c
r21415 r22013 82 82 m->m_nextpkt = 0; 83 83 m->m_prevpkt = 0; 84 #ifdef VBOX_WITH_SLIRP_ALIAS85 84 m->m_la = NULL; 86 #endif87 85 88 86 end_error: -
trunk/src/VBox/Devices/Network/slirp/mbuf.h
r20446 r22013 74 74 caddr_t mh_data; /* Location of data */ 75 75 int mh_len; /* Amount of data in this mbuf */ 76 #ifdef VBOX_WITH_SLIRP_ALIAS77 76 struct libalias *mh_la; /*Real freebsd store hocksin similar way*/ 78 #endif79 77 }; 80 78 … … 114 112 #define m_ext M_dat.m_ext_ 115 113 #define m_so m_hdr.mh_so 116 #ifdef VBOX_WITH_SLIRP_ALIAS117 114 #define m_la m_hdr.mh_la 118 #endif119 115 120 116 #define ifq_prev m_prev -
trunk/src/VBox/Devices/Network/slirp/slirp.c
r21864 r22013 15 15 # include <IPHlpApi.h> 16 16 #endif 17 #ifdef VBOX_WITH_SLIRP_ALIAS 18 # include <alias.h> 19 #endif 17 #include <alias.h> 20 18 21 19 #if !defined(RT_OS_WINDOWS) … … 541 539 542 540 getouraddr(pData); 543 544 #ifdef VBOX_WITH_SLIRP_ALIAS545 541 { 546 542 int flags = 0; … … 559 555 ftp_alias_load(pData); 560 556 nbt_alias_load(pData); 561 562 } 563 #endif 557 } 564 558 return fNATfailed ? VINF_NAT_DNS : VINF_SUCCESS; 565 559 } … … 659 653 ftp_alias_unload(pData); 660 654 nbt_alias_unload(pData); 661 #ifdef VBOX_WITH_SLIRP_ALIAS662 655 while(!LIST_EMPTY(&instancehead)) { 663 656 struct libalias *la = LIST_FIRST(&instancehead); … … 665 658 LibAliasUninit(la); 666 659 } 667 #endif668 660 #ifdef RT_OS_WINDOWS 669 661 WSACleanup(); … … 1533 1525 { 1534 1526 struct socket *so; 1535 #ifdef VBOX_WITH_SLIRP_ALIAS1536 1527 struct alias_link *link; 1537 1528 struct libalias *lib; … … 1542 1533 struct in_addr alias; 1543 1534 int rc; 1544 #endif 1535 1545 1536 Log2(("NAT: set redirect %s hp:%d gp:%d\n", (is_udp?"UDP":"TCP"), host_port, guest_port)); 1546 1537 if (is_udp) … … 1558 1549 return -1; 1559 1550 } 1560 #ifndef VBOX_WITH_SLIRP_ALIAS1561 Log2(("NAT: redirecting socket %R[natsock]\n", so));1562 return (so != NULL ? 0 : -1);1563 #else1564 1551 1565 1552 psin = (struct sockaddr_in *)&sa; … … 1601 1588 1602 1589 return 0; 1603 #endif1604 1590 } 1605 1591 -
trunk/src/VBox/Devices/Network/slirp/slirp.h
r21865 r22013 343 343 AssertCompileSize(struct ethhdr, 14); 344 344 # endif 345 #if defined(VBOX_ WITH_SLIRP_ALIAS) && defined(VBOX_SLIRP_ALIAS)345 #if defined(VBOX_SLIRP_ALIAS) 346 346 347 347 # define ip_next(ip) (void *)((uint8_t *)(ip) + ((ip)->ip_hl << 2)) … … 405 405 } 406 406 # endif /* DEBUG */ 407 #endif /*VBOX_WITH_SLIRP_ALIAS && VBOX_SLIRP_ALIAS*/ 408 409 #ifdef VBOX_WITH_SLIRP_ALIAS 407 #endif /*VBOX_SLIRP_ALIAS*/ 408 410 409 int ftp_alias_load(PNATState); 411 410 int ftp_alias_unload(PNATState); 412 411 int nbt_alias_load(PNATState); 413 412 int nbt_alias_unload(PNATState); 414 #endif /*VBOX_WITH_SLIRP_ALIAS*/ 415 416 #endif 417 413 #endif 414 -
trunk/src/VBox/Devices/Network/slirp/slirp_state.h
r21864 r22013 226 226 bool use_dns_proxy; 227 227 228 #ifdef VBOX_WITH_SLIRP_ALIAS229 228 LIST_HEAD(RT_NOTHING, libalias) instancehead; 230 229 struct libalias *proxy_alias; 231 230 LIST_HEAD(handler_chain, proto_handler) handler_chain; 232 #endif233 231 234 232 #define PROFILE_COUNTER(name, dsc) STAMPROFILE Stat ## name … … 671 669 #define sock_answer pData->sock_answer 672 670 673 #ifdef VBOX_WITH_SLIRP_ALIAS 674 # define instancehead pData->instancehead 675 #endif 671 #define instancehead pData->instancehead 676 672 677 673 #endif /* !___slirp_state_h */ -
trunk/src/VBox/Devices/Network/slirp/socket.h
r21004 r22013 87 87 unsigned char so_ethaddr[6]; 88 88 #endif 89 #ifdef VBOX_WITH_SLIRP_ALIAS90 89 /* required for port-forwarding */ 91 90 struct libalias *so_la; 92 #endif93 91 }; 94 92 -
trunk/src/VBox/Devices/Network/slirp/tcp_output.c
r20164 r22013 601 601 } 602 602 #endif 603 #ifdef VBOX_WITH_SLIRP_ALIAS604 603 if(so->so_la != NULL) 605 604 m->m_la = so->so_la; 606 #endif607 605 error = ip_output(pData, so, m); 608 606 -
trunk/src/VBox/Devices/Network/slirp/tcp_subr.c
r20959 r22013 481 481 so->so_laddr = inso->so_laddr; 482 482 so->so_lport = inso->so_lport; 483 #ifdef VBOX_WITH_SLIRP_ALIAS484 483 so->so_la = inso->so_la; 485 #endif486 484 } 487 485 … … 621 619 tcp_tos(struct socket *so) 622 620 { 623 #ifndef VBOX_WITH_SLIRP_ALIAS624 int i = 0;625 626 while(tcptos[i].tos)627 {628 if ( (tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport))629 || (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport)))630 {631 so->so_emu = tcptos[i].emu;632 return tcptos[i].tos;633 }634 i++;635 }636 #endif637 621 return 0; 638 622 } … … 660 644 tcp_emu(PNATState pData, struct socket *so, struct mbuf *m) 661 645 { 662 #ifndef VBOX_WITH_SLIRP_ALIAS663 u_int n1, n2, n3, n4, n5, n6;664 char buff[256];665 u_int32_t laddr;666 u_int lport;667 char *bptr;668 669 DEBUG_CALL("tcp_emu");670 DEBUG_ARG("so = %lx", (long)so);671 DEBUG_ARG("m = %lx", (long)m);672 673 switch(so->so_emu)674 {675 int x, i;676 677 case EMU_IDENT:678 /*679 * Identification protocol as per rfc-1413680 */681 {682 struct socket *tmpso;683 struct sockaddr_in addr;684 socklen_t addrlen = sizeof(struct sockaddr_in);685 struct sbuf *so_rcv = &so->so_rcv;686 687 memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);688 so_rcv->sb_wptr += m->m_len;689 so_rcv->sb_rptr += m->m_len;690 m->m_data[m->m_len] = 0; /* NULL terminate */691 if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n'))692 {693 if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2)694 {695 HTONS(n1);696 HTONS(n2);697 /* n2 is the one on our host */698 for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next)699 {700 if ( tmpso->so_laddr.s_addr == so->so_laddr.s_addr701 && tmpso->so_lport == n2702 && tmpso->so_faddr.s_addr == so->so_faddr.s_addr703 && tmpso->so_fport == n1)704 {705 if (getsockname(tmpso->s,706 (struct sockaddr *)&addr, &addrlen) == 0)707 n2 = ntohs(addr.sin_port);708 break;709 }710 }711 }712 so_rcv->sb_cc = sprintf(so_rcv->sb_data, "%d,%d\r\n", n1, n2);713 so_rcv->sb_rptr = so_rcv->sb_data;714 so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc;715 }716 m_free(pData, m);717 return 0;718 }719 720 case EMU_FTP:721 *(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */722 if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL)723 {724 /*725 * Need to emulate the PORT command726 */727 struct sockaddr_in addr;728 socklen_t addrlen = sizeof addr;729 730 if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen))731 return 1;732 733 x = sscanf(bptr, "ORT %u,%u,%u,%u,%u,%u\r\n%256[^\177]",734 &n1, &n2, &n3, &n4, &n5, &n6, buff);735 if (x < 6)736 return 1;737 738 laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));739 lport = htons((n5 << 8) | (n6));740 741 if ((so = solisten(pData, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)742 return 1;743 744 n6 = ntohs(so->so_fport);745 746 n5 = (n6 >> 8) & 0xff;747 n6 &= 0xff;748 749 laddr = ntohl(addr.sin_addr.s_addr);750 751 n1 = ((laddr >> 24) & 0xff);752 n2 = ((laddr >> 16) & 0xff);753 n3 = ((laddr >> 8) & 0xff);754 n4 = ( laddr & 0xff);755 756 m->m_len = bptr - m->m_data; /* Adjust length */757 m->m_len += sprintf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%s",758 n1, n2, n3, n4, n5, n6, x==7?buff:"");759 return 1;760 }761 else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL)762 {763 /*764 * Need to emulate the PASV response765 */766 struct sockaddr_in addr;767 socklen_t addrlen = sizeof addr;768 769 if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen))770 return 1;771 772 x = sscanf(bptr, "27 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n%256[^\177]",773 &n1, &n2, &n3, &n4, &n5, &n6, buff);774 if (x < 6)775 return 1;776 777 laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));778 lport = htons((n5 << 8) | (n6));779 780 if ((so = solisten(pData, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)781 return 1;782 783 n6 = ntohs(so->so_fport);784 785 n5 = (n6 >> 8) & 0xff;786 n6 &= 0xff;787 788 laddr = ntohl(addr.sin_addr.s_addr);789 790 n1 = ((laddr >> 24) & 0xff);791 n2 = ((laddr >> 16) & 0xff);792 n3 = ((laddr >> 8) & 0xff);793 n4 = (laddr & 0xff);794 795 m->m_len = bptr - m->m_data; /* Adjust length */796 m->m_len += sprintf(bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s",797 n1, n2, n3, n4, n5, n6, x==7?buff:"");798 799 return 1;800 }801 return 1;802 803 case EMU_KSH:804 /*805 * The kshell (Kerberos rsh) and shell services both pass806 * a local port port number to carry signals to the server807 * and stderr to the client. It is passed at the beginning808 * of the connection as a NUL-terminated decimal ASCII string.809 */810 so->so_emu = 0;811 for (lport = 0, i = 0; i < m->m_len-1; ++i)812 {813 if (m->m_data[i] < '0' || m->m_data[i] > '9')814 return 1; /* invalid number */815 lport *= 10;816 lport += m->m_data[i] - '0';817 }818 if ( m->m_data[m->m_len-1] == '\0'819 && lport != 0820 && (so = solisten(pData, 0, so->so_laddr.s_addr,821 htons(lport), SS_FACCEPTONCE)) != NULL)822 m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1;823 return 1;824 825 case EMU_IRC:826 /*827 * Need to emulate DCC CHAT, DCC SEND and DCC MOVE828 */829 *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */830 if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL)831 return 1;832 833 /* The %256s is for the broken mIRC */834 if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3)835 {836 if ((so = solisten(pData, 0, htonl(laddr),837 htons(lport), SS_FACCEPTONCE)) == NULL)838 return 1;839 840 m->m_len = bptr - m->m_data; /* Adjust length */841 m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n",842 (unsigned long)ntohl(so->so_faddr.s_addr),843 ntohs(so->so_fport), 1);844 }845 else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4)846 {847 if ((so = solisten(pData, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)848 return 1;849 850 m->m_len = bptr - m->m_data; /* Adjust length */851 m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n",852 buff, (unsigned long)ntohl(so->so_faddr.s_addr),853 ntohs(so->so_fport), n1, 1);854 }855 else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4)856 {857 if ((so = solisten(pData, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)858 return 1;859 860 m->m_len = bptr - m->m_data; /* Adjust length */861 m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n",862 buff, (unsigned long)ntohl(so->so_faddr.s_addr),863 ntohs(so->so_fport), n1, 1);864 }865 return 1;866 867 #ifdef VBOX868 /** @todo Disabled EMU_REALAUDIO, because it uses a static variable.869 * This is not legal when more than one slirp instance is active. */870 #else /* !VBOX */871 case EMU_REALAUDIO:872 /*873 * RealAudio emulation - JP. We must try to parse the incoming874 * data and try to find the two characters that contain the875 * port number. Then we redirect an udp port and replace the876 * number with the real port we got.877 *878 * The 1.0 beta versions of the player are not supported879 * any more.880 *881 * A typical packet for player version 1.0 (release version):882 *883 * 0000:50 4E 41 00 05884 * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....×..gælÜc..P885 * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH886 * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v887 * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB888 *889 * Now the port number 0x1BD7 is found at offset 0x04 of the890 * Now the port number 0x1BD7 is found at offset 0x04 of the891 * second packet. This time we received five bytes first and892 * then the rest. You never know how many bytes you get.893 *894 * A typical packet for player version 2.0 (beta):895 *896 * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........Á.897 * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxõc..Win2.0.0898 * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/899 * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas900 * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B901 *902 * Port number 0x1BC1 is found at offset 0x0d.903 *904 * This is just a horrible switch statement. Variable ra tells905 * us where we're going.906 */907 908 bptr = m->m_data;909 while (bptr < m->m_data + m->m_len)910 {911 u_short p;912 static int ra = 0;913 char ra_tbl[4];914 915 ra_tbl[0] = 0x50;916 ra_tbl[1] = 0x4e;917 ra_tbl[2] = 0x41;918 ra_tbl[3] = 0;919 920 switch (ra)921 {922 case 0:923 case 2:924 case 3:925 if (*bptr++ != ra_tbl[ra])926 {927 ra = 0;928 continue;929 }930 break;931 932 case 1:933 /*934 * We may get 0x50 several times, ignore them935 */936 if (*bptr == 0x50)937 {938 ra = 1;939 bptr++;940 continue;941 }942 else if (*bptr++ != ra_tbl[ra])943 {944 ra = 0;945 continue;946 }947 break;948 949 case 4:950 /*951 * skip version number952 */953 bptr++;954 break;955 956 case 5:957 /*958 * The difference between versions 1.0 and959 * 2.0 is here. For future versions of960 * the player this may need to be modified.961 */962 if (*(bptr + 1) == 0x02)963 bptr += 8;964 else965 bptr += 4;966 break;967 968 case 6:969 /* This is the field containing the port970 * number that RA-player is listening to.971 */972 lport = (((u_char*)bptr)[0] << 8)973 + ((u_char *)bptr)[1];974 if (lport < 6970)975 lport += 256; /* don't know why */976 if (lport < 6970 || lport > 7170)977 return 1; /* failed */978 979 /* try to get udp port between 6970 - 7170 */980 for (p = 6970; p < 7071; p++)981 {982 if (udp_listen(htons(p),983 so->so_laddr.s_addr,984 htons(lport),985 SS_FACCEPTONCE))986 {987 break;988 }989 }990 if (p == 7071)991 p = 0;992 *(u_char *)bptr++ = (p >> 8) & 0xff;993 *(u_char *)bptr++ = p & 0xff;994 ra = 0;995 return 1; /* port redirected, we're done */996 break;997 998 default:999 ra = 0;1000 }1001 ra++;1002 }1003 return 1;1004 #endif /* !VBOX */1005 1006 default:1007 /* Ooops, not emulated, won't call tcp_emu again */1008 so->so_emu = 0;1009 return 1;1010 }1011 #else /* !VBOX_WITH_SLIRP_ALIAS */1012 646 /*XXX: libalias should care about it */ 1013 647 so->so_emu = 0; 1014 648 return 1; 1015 #endif 1016 } 649 } -
trunk/src/VBox/Devices/Network/slirp/udp.c
r21664 r22013 473 473 udp_emu(PNATState pData, struct socket *so, struct mbuf *m) 474 474 { 475 #ifndef VBOX_WITH_SLIRP_ALIAS476 struct sockaddr_in addr;477 socklen_t addrlen = sizeof(addr);478 #ifdef EMULATE_TALK479 CTL_MSG_OLD *omsg;480 CTL_MSG *nmsg;481 char buff[sizeof(CTL_MSG)];482 u_char type;483 484 struct talk_request485 {486 struct talk_request *next;487 struct socket *udp_so;488 struct socket *tcp_so;489 } *req;490 491 static struct talk_request *req_tbl = 0;492 493 #endif494 495 struct cu_header496 {497 uint16_t d_family; /* destination family */498 uint16_t d_port; /* destination port */499 uint32_t d_addr; /* destination address */500 uint16_t s_family; /* source family */501 uint16_t s_port; /* source port */502 uint32_t so_addr; /* source address */503 uint32_t seqn; /* sequence number */504 uint16_t message; /* message */505 uint16_t data_type; /* data type */506 uint16_t pkt_len; /* packet length */507 } *cu_head;508 509 switch(so->so_emu)510 {511 #ifdef EMULATE_TALK512 case EMU_TALK:513 case EMU_NTALK:514 /*515 * Talk emulation. We always change the ctl_addr to get516 * some answers from the daemon. When an ANNOUNCE comes,517 * we send LEAVE_INVITE to the local daemons. Also when a518 * DELETE comes, we send copies to the local daemons.519 */520 if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0)521 return;522 523 #define IS_OLD (so->so_emu == EMU_TALK)524 525 #define COPY_MSG(dest, src) \526 do { \527 dest->type = src->type; \528 dest->id_num = src->id_num; \529 dest->pid = src->pid; \530 dest->addr = src->addr; \531 dest->ctl_addr = src->ctl_addr; \532 memcpy(&dest->l_name, &src->l_name, NAME_SIZE_OLD); \533 memcpy(&dest->r_name, &src->r_name, NAME_SIZE_OLD); \534 memcpy(&dest->r_tty, &src->r_tty, TTY_SIZE);535 } while (0)536 537 #define OTOSIN(ptr, field) ((struct sockaddr_in *)&ptr->field)538 /* old_sockaddr to sockaddr_in */539 540 541 if (IS_OLD)542 {543 /* old talk */544 omsg = mtod(m, CTL_MSG_OLD*);545 nmsg = (CTL_MSG *) buff;546 type = omsg->type;547 OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port;548 OTOSIN(omsg, ctl_addr)->sin_addr = our_addr;549 strncpy(omsg->l_name, getlogin(), NAME_SIZE_OLD);550 }551 else552 {553 /* new talk */554 omsg = (CTL_MSG_OLD *) buff;555 nmsg = mtod(m, CTL_MSG *);556 type = nmsg->type;557 OTOSIN(nmsg, ctl_addr)->sin_port = addr.sin_port;558 OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr;559 strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD);560 }561 562 if (type == LOOK_UP)563 return; /* for LOOK_UP this is enough */564 565 if (IS_OLD)566 {567 /* make a copy of the message */568 COPY_MSG(nmsg, omsg);569 nmsg->vers = 1;570 nmsg->answer = 0;571 }572 else573 COPY_MSG(omsg, nmsg);574 575 /*576 * If if is an ANNOUNCE message, we go through the577 * request table to see if a tcp port has already578 * been redirected for this socket. If not, we solisten()579 * a new socket and add this entry to the table.580 * The port number of the tcp socket and our IP581 * are put to the addr field of the message structures.582 * Then a LEAVE_INVITE is sent to both local daemon583 * ports, 517 and 518. This is why we have two copies584 * of the message, one in old talk and one in new talk585 * format.586 */587 588 if (type == ANNOUNCE)589 {590 int s;591 u_short temp_port;592 593 for (req = req_tbl; req; req = req->next)594 if (so == req->udp_so)595 break; /* found it */596 597 if (!req)598 {599 /* no entry for so, create new */600 req = (struct talk_request *)RTMemAlloc(sizeof(struct talk_request));601 req->udp_so = so;602 req->tcp_so = solisten(0,603 OTOSIN(omsg, addr)->sin_addr.s_addr,604 OTOSIN(omsg, addr)->sin_port,605 SS_FACCEPTONCE);606 req->next = req_tbl;607 req_tbl = req;608 }609 610 /* replace port number in addr field */611 addrlen = sizeof(addr);612 getsockname(req->tcp_so->s, (struct sockaddr *) &addr, &addrlen);613 OTOSIN(omsg, addr)->sin_port = addr.sin_port;614 OTOSIN(omsg, addr)->sin_addr = our_addr;615 OTOSIN(nmsg, addr)->sin_port = addr.sin_port;616 OTOSIN(nmsg, addr)->sin_addr = our_addr;617 618 /* send LEAVE_INVITEs */619 temp_port = OTOSIN(omsg, ctl_addr)->sin_port;620 OTOSIN(omsg, ctl_addr)->sin_port = 0;621 OTOSIN(nmsg, ctl_addr)->sin_port = 0;622 omsg->type = nmsg->type = LEAVE_INVITE;623 624 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);625 addr.sin_addr = our_addr;626 addr.sin_family = AF_INET;627 addr.sin_port = htons(517);628 sendto(s, (char *)omsg, sizeof(*omsg), 0,629 (struct sockaddr *)&addr, sizeof(addr));630 addr.sin_port = htons(518);631 sendto(s, (char *)nmsg, sizeof(*nmsg), 0,632 (struct sockaddr *) &addr, sizeof(addr));633 closesocket(s) ;634 635 omsg->type = nmsg->type = ANNOUNCE;636 OTOSIN(omsg, ctl_addr)->sin_port = temp_port;637 OTOSIN(nmsg, ctl_addr)->sin_port = temp_port;638 }639 640 /*641 * If it is a DELETE message, we send a copy to the642 * local daemons. Then we delete the entry corresponding643 * to our socket from the request table.644 */645 646 if (type == DELETE)647 {648 struct talk_request *temp_req, *req_next;649 int s;650 u_short temp_port;651 652 temp_port = OTOSIN(omsg, ctl_addr)->sin_port;653 OTOSIN(omsg, ctl_addr)->sin_port = 0;654 OTOSIN(nmsg, ctl_addr)->sin_port = 0;655 656 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);657 addr.sin_addr = our_addr;658 addr.sin_family = AF_INET;659 addr.sin_port = htons(517);660 sendto(s, (char *)omsg, sizeof(*omsg), 0,661 (struct sockaddr *)&addr, sizeof(addr));662 addr.sin_port = htons(518);663 sendto(s, (char *)nmsg, sizeof(*nmsg), 0,664 (struct sockaddr *)&addr, sizeof(addr));665 closesocket(s);666 667 OTOSIN(omsg, ctl_addr)->sin_port = temp_port;668 OTOSIN(nmsg, ctl_addr)->sin_port = temp_port;669 670 /* delete table entry */671 if (so == req_tbl->udp_so)672 {673 temp_req = req_tbl;674 req_tbl = req_tbl->next;675 RTMemFree(temp_req);676 }677 else678 {679 temp_req = req_tbl;680 for (req = req_tbl->next; req; req = req_next)681 {682 req_next = req->next;683 if (so == req->udp_so)684 {685 temp_req->next = req_next;686 RTMemFree(req);687 break;688 }689 else690 temp_req = req;691 }692 }693 }694 695 return;696 #endif697 698 case EMU_CUSEEME:699 /*700 * Cu-SeeMe emulation.701 * Hopefully the packet is more that 16 bytes long. We don't702 * do any other tests, just replace the address and port703 * fields.704 */705 if (m->m_len >= sizeof (*cu_head))706 {707 if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0)708 return;709 cu_head = mtod(m, struct cu_header *);710 cu_head->s_port = addr.sin_port;711 cu_head->so_addr = our_addr.s_addr;712 }713 return;714 }715 #else /*!VBOX_WITH_SLIRP_ALIAS*/716 475 so->so_emu = 0; 717 #endif /* VBOX_WITH_SLIRP_ALIAS */718 476 } 719 477
Note:
See TracChangeset
for help on using the changeset viewer.