660
642
tcp_emu(PNATState pData, struct socket *so, struct mbuf *m)
662
#ifndef VBOX_WITH_SLIRP_ALIAS
663
u_int n1, n2, n3, n4, n5, n6;
669
DEBUG_CALL("tcp_emu");
670
DEBUG_ARG("so = %lx", (long)so);
671
DEBUG_ARG("m = %lx", (long)m);
679
* Identification protocol as per rfc-1413
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;
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'))
693
if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2)
697
/* n2 is the one on our host */
698
for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next)
700
if ( tmpso->so_laddr.s_addr == so->so_laddr.s_addr
701
&& tmpso->so_lport == n2
702
&& tmpso->so_faddr.s_addr == so->so_faddr.s_addr
703
&& tmpso->so_fport == n1)
705
if (getsockname(tmpso->s,
706
(struct sockaddr *)&addr, &addrlen) == 0)
707
n2 = ntohs(addr.sin_port);
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;
721
*(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */
722
if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL)
725
* Need to emulate the PORT command
727
struct sockaddr_in addr;
728
socklen_t addrlen = sizeof addr;
730
if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen))
733
x = sscanf(bptr, "ORT %u,%u,%u,%u,%u,%u\r\n%256[^\177]",
734
&n1, &n2, &n3, &n4, &n5, &n6, buff);
738
laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
739
lport = htons((n5 << 8) | (n6));
741
if ((so = solisten(pData, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)
744
n6 = ntohs(so->so_fport);
746
n5 = (n6 >> 8) & 0xff;
749
laddr = ntohl(addr.sin_addr.s_addr);
751
n1 = ((laddr >> 24) & 0xff);
752
n2 = ((laddr >> 16) & 0xff);
753
n3 = ((laddr >> 8) & 0xff);
754
n4 = ( laddr & 0xff);
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:"");
761
else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL)
764
* Need to emulate the PASV response
766
struct sockaddr_in addr;
767
socklen_t addrlen = sizeof addr;
769
if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen))
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);
777
laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
778
lport = htons((n5 << 8) | (n6));
780
if ((so = solisten(pData, 0, laddr, lport, SS_FACCEPTONCE)) == NULL)
783
n6 = ntohs(so->so_fport);
785
n5 = (n6 >> 8) & 0xff;
788
laddr = ntohl(addr.sin_addr.s_addr);
790
n1 = ((laddr >> 24) & 0xff);
791
n2 = ((laddr >> 16) & 0xff);
792
n3 = ((laddr >> 8) & 0xff);
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:"");
805
* The kshell (Kerberos rsh) and shell services both pass
806
* a local port port number to carry signals to the server
807
* and stderr to the client. It is passed at the beginning
808
* of the connection as a NUL-terminated decimal ASCII string.
811
for (lport = 0, i = 0; i < m->m_len-1; ++i)
813
if (m->m_data[i] < '0' || m->m_data[i] > '9')
814
return 1; /* invalid number */
816
lport += m->m_data[i] - '0';
818
if ( m->m_data[m->m_len-1] == '\0'
820
&& (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;
827
* Need to emulate DCC CHAT, DCC SEND and DCC MOVE
829
*(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */
830
if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL)
833
/* The %256s is for the broken mIRC */
834
if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3)
836
if ((so = solisten(pData, 0, htonl(laddr),
837
htons(lport), SS_FACCEPTONCE)) == NULL)
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);
845
else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4)
847
if ((so = solisten(pData, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
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);
855
else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4)
857
if ((so = solisten(pData, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
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);
868
/** @todo Disabled EMU_REALAUDIO, because it uses a static variable.
869
* This is not legal when more than one slirp instance is active. */
873
* RealAudio emulation - JP. We must try to parse the incoming
874
* data and try to find the two characters that contain the
875
* port number. Then we redirect an udp port and replace the
876
* number with the real port we got.
878
* The 1.0 beta versions of the player are not supported
881
* A typical packet for player version 1.0 (release version):
883
* 0000:50 4E 41 00 05
884
* 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....�..g�l�c..P
885
* 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH
886
* 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v
887
* 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB
889
* Now the port number 0x1BD7 is found at offset 0x04 of the
890
* Now the port number 0x1BD7 is found at offset 0x04 of the
891
* second packet. This time we received five bytes first and
892
* then the rest. You never know how many bytes you get.
894
* A typical packet for player version 2.0 (beta):
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.0
898
* 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/20releas
900
* 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B
902
* Port number 0x1BC1 is found at offset 0x0d.
904
* This is just a horrible switch statement. Variable ra tells
905
* us where we're going.
909
while (bptr < m->m_data + m->m_len)
925
if (*bptr++ != ra_tbl[ra])
934
* We may get 0x50 several times, ignore them
942
else if (*bptr++ != ra_tbl[ra])
951
* skip version number
958
* The difference between versions 1.0 and
959
* 2.0 is here. For future versions of
960
* the player this may need to be modified.
962
if (*(bptr + 1) == 0x02)
969
/* This is the field containing the port
970
* number that RA-player is listening to.
972
lport = (((u_char*)bptr)[0] << 8)
973
+ ((u_char *)bptr)[1];
975
lport += 256; /* don't know why */
976
if (lport < 6970 || lport > 7170)
977
return 1; /* failed */
979
/* try to get udp port between 6970 - 7170 */
980
for (p = 6970; p < 7071; p++)
982
if (udp_listen(htons(p),
992
*(u_char *)bptr++ = (p >> 8) & 0xff;
993
*(u_char *)bptr++ = p & 0xff;
995
return 1; /* port redirected, we're done */
1007
/* Ooops, not emulated, won't call tcp_emu again */
1011
#else /* !VBOX_WITH_SLIRP_ALIAS */
1012
644
/*XXX: libalias should care about it */