tcp_subr.c revision 8b23a6c7e1aee255004dd19098d4c2462b61b849
18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 1982, 1986, 1988, 1990, 1993 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The Regents of the University of California. All rights reserved. 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Redistribution and use in source and binary forms, with or without 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * modification, are permitted provided that the following conditions 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * are met: 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * notice, this list of conditions and the following disclaimer. 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * documentation and/or other materials provided with the distribution. 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 3. All advertising materials mentioning features or use of this software 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * must display the following acknowledgement: 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This product includes software developed by the University of 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * California, Berkeley and its contributors. 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 4. Neither the name of the University nor the names of its contributors 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * may be used to endorse or promote products derived from this software 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * without specific prior written permission. 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * SUCH DAMAGE. 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * @(#)tcp_subr.c 8.1 (Berkeley) 6/10/93 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tcp_subr.c,v 1.5 1994/10/08 22:39:58 phk Exp 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Changes and additions relating to SLiRP 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 1995 Danny Gasparovski. 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Please read the file COPYRIGHT for the 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * terms and conditions of the copyright. 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define WANT_SYS_IOCTL_H 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <slirp.h> 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "proxy_common.h" 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* patchable/settable parameters for tcp */ 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint tcp_mssdflt = TCP_MSS; 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ; 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint tcp_do_rfc1323 = 0; /* Don't do rfc1323 performance enhancements */ 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint tcp_rcvspace; /* You may want to change this */ 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint tcp_sndspace; /* Keep small if you have an error prone link */ 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Tcp initialization 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_init() 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_iss = 1; /* wrong */ 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcb.so_next = tcb.so_prev = &tcb; 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* tcp_rcvspace = our Window we advertise to the remote */ 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_rcvspace = TCP_RCVSPACE; 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_sndspace = TCP_SNDSPACE; 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Make sure tcp_sndspace is at least 2*MSS */ 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcp_sndspace < 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr))) 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_sndspace = 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr)); 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Create template to be used to send tcp packets on a connection. 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Call after host entry created, fills 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in a skeletal tcp/ip header, minimizing the amount of work 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * necessary when the connection is used. 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* struct tcpiphdr * */ 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_template(tp) 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tcpcb *tp; 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so = tp->t_socket; 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register struct tcpiphdr *n = &tp->t_template; 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_mbuf = NULL; 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_x1 = 0; 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_pr = IPPROTO_TCP; 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_src = ip_seth(so->so_faddr_ip); 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_dst = ip_seth(so->so_laddr_ip); 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_sport = port_seth(so->so_faddr_port); 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_dport = port_seth(so->so_laddr_port); 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_seq = 0; 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_ack = 0; 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_x2 = 0; 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_off = 5; 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_flags = 0; 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_win = 0; 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_sum = 0; 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_urp = 0; 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Send a single message to the TCP at address specified by 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the given TCP/IP header. If m == 0, then we make a copy 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of the tcpiphdr at ti and send directly to the addressed host. 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This is used to force keep alive messages out using the TCP 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * template for a connection tp->t_template. If flags are given 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * then we send a message back to the TCP which originated the 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * segment ti, and discard the mbuf containing it and any other 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * attached mbufs. 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * In any case the ack and sequence number of the transmitted 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * segment are as specified by the parameters. 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_respond(tp, ti, m, ack, seq, flags) 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tcpcb *tp; 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register struct tcpiphdr *ti; 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register MBuf m; 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_seq ack, seq; 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int flags; 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register int tlen; 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int win = 0; 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_respond"); 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("tp = %lx", (long)tp); 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("ti = %lx", (long)ti); 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("m = %lx", (long)m); 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("ack = %u", ack); 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("seq = %u", seq); 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("flags = %x", flags); 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp) 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project win = sbuf_space(&tp->t_socket->so_rcv); 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (m == 0) { 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((m = mbuf_alloc()) == NULL) 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCP_COMPAT_42 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlen = 1; 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlen = 0; 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_data += if_maxlinkhdr; 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *MBUF_TO(m, struct tcpiphdr *) = *ti; 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti = MBUF_TO(m, struct tcpiphdr *); 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags = TH_ACK; 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ti points into m so the next line is just making 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the mbuf point to ti 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_data = (caddr_t)ti; 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = sizeof (struct tcpiphdr); 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlen = 0; 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define xchg(a,b,type) { type t; t=a; a=b; b=t; } 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xchg(ti->ti_dst, ti->ti_src, ipaddr_t); 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project xchg(ti->ti_dport, ti->ti_sport, port_t); 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef xchg 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen)); 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlen += sizeof (struct tcpiphdr); 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = tlen; 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_mbuf = 0; 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_x1 = 0; 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_seq = htonl(seq); 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_ack = htonl(ack); 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_x2 = 0; 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_off = sizeof (struct tcphdr) >> 2; 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_flags = flags; 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp) 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_win = htons((u_int16_t) (win >> tp->rcv_scale)); 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_win = htons((u_int16_t)win); 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_urp = 0; 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_sum = 0; 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_sum = cksum(m, tlen); 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((struct ip *)ti)->ip_len = tlen; 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(flags & TH_RST) 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((struct ip *)ti)->ip_ttl = MAXTTL; 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((struct ip *)ti)->ip_ttl = ip_defttl; 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) ip_output((struct socket *)0, m); 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Create a new TCP control block, making an 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * empty reassembly queue and hooking it to the argument 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * protocol control block. 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct tcpcb * 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_newtcpcb(so) 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so; 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register struct tcpcb *tp; 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = (struct tcpcb *)malloc(sizeof(*tp)); 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp == NULL) 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ((struct tcpcb *)0); 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memset((char *) tp, 0, sizeof(struct tcpcb)); 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp; 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_maxseg = tcp_mssdflt; 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_socket = so; 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * reasonable initial retransmit time. 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_srtt = TCPTV_SRTTBASE; 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2; 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_rttmin = TCPTV_MIN; 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCPT_RANGESET(tp->t_rxtcur, 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1, 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCPTV_MIN, TCPTV_REXMTMAX); 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_CLOSED; 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_tcpcb = tp; 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (tp); 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Drop a TCP connection, reporting 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the specified error. If connection is synchronized, 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * then send a RST to peer. 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct tcpcb *tcp_drop(struct tcpcb *tp, int err) 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* tcp_drop(tp, errno) 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register struct tcpcb *tp; 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int errno; 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_drop"); 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("tp = %lx", (long)tp); 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("errno = %d", errno); 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (TCPS_HAVERCVDSYN(tp->t_state)) { 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_CLOSED; 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) tcp_output(tp); 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcpstat.tcps_drops++; 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcpstat.tcps_conndrops++; 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (errno == ETIMEDOUT && tp->t_softerror) 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * errno = tp->t_softerror; 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* so->so_error = errno; */ 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (tcp_close(tp)); 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Close a TCP control block: 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * discard all space held by the tcp 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * discard internet protocol block 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * wake up any sleepers 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct tcpcb * 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_close(tp) 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register struct tcpcb *tp; 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register struct tcpiphdr *t; 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so = tp->t_socket; 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register MBuf m; 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_close"); 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("tp = %lx", (long )tp); 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* free the reassembly queue, if any */ 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project t = tcpfrag_list_first(tp); 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (!tcpfrag_list_end(t, tp)) { 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project t = tcpiphdr_next(t); 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m = tcpiphdr_prev(t)->ti_mbuf; 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remque(tcpiphdr2qlink(tcpiphdr_prev(t))); 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mbuf_free(m); 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* It's static */ 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (tp->t_template) 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (void) mbuf_free(MBUF_FROM(tp->t_template)); 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* free(tp, M_PCB); */ 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(tp); 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_tcpcb = 0; 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project soisfdisconnected(so); 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* clobber input socket cache if we're closing the cached connection */ 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so == tcp_last_so) 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_last_so = &tcb; 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_close(so->s); 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sbuf_free(&so->so_rcv); 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sbuf_free(&so->so_snd); 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sofree(so); 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcpstat.tcps_closed++; 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ((struct tcpcb *)0); 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_drain() 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* XXX */ 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * When a source quench is received, close congestion window 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to one segment. We will gradually open it again as we proceed. 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef notdef 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_quench(i, errno) 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int errno; 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tcpcb *tp = intotcpcb(inp); 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp) 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_cwnd = tp->t_maxseg; 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* notdef */ 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * TCP protocol interface to socket abstraction. 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * User issued close, and wish to trail through shutdown states: 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if never received SYN, just forget it. If got a SYN from peer, 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If already got a FIN from peer, then almost done; go to LAST_ACK 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * state. In all other cases, have already sent FIN to peer (e.g. 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * after PRU_SHUTDOWN), and just have to play tedious game waiting 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * for peer to send FIN or not respond to keep-alives, etc. 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We can let the user exit from the close as soon as the FIN is acked. 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_sockclosed(tp) 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tcpcb *tp; 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_sockclosed"); 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("tp = %lx", (long)tp); 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (tp->t_state) { 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_CLOSED: 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_LISTEN: 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_SYN_SENT: 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_CLOSED; 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = tcp_close(tp); 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_SYN_RECEIVED: 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_ESTABLISHED: 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_FIN_WAIT_1; 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_CLOSE_WAIT: 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_LAST_ACK; 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* soisfdisconnecting(tp->t_socket); */ 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp && tp->t_state >= TCPS_FIN_WAIT_2) 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project soisfdisconnected(tp->t_socket); 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp) 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_output(tp); 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_proxy_event( struct socket* so, 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int s, 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyEvent event ) 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_state &= ~SS_PROXIFIED; 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (event == PROXY_EVENT_CONNECTED) { 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->s = s; 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_state &= ~(SS_ISFCONNECTING); 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_state = SS_NOFDREF; 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* continue the connect */ 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_input(NULL, sizeof(struct ip), so); 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Connect to a host on the Internet 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Called by tcp_input 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Only do a connect, the tcp fields will be set in tcp_input 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * return 0 if there's a result of the connect, 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * else return -1 means we're still connecting 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The return value is almost always -1 since the socket is 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * nonblocking. Connect returns after the SYN is sent, and does 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * not wait for ACK+SYN. 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint tcp_fconnect(so) 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so; 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret=0; 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int try_proxy = 1; 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SockAddress sockaddr; 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t sock_ip; 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint16_t sock_port; 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_fconnect"); 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("so = %lx", (long )so); 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_ip = so->so_faddr_ip; 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_port = so->so_faddr_port; 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((sock_ip & 0xffffff00) == special_addr_ip) { 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* It's an alias */ 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int last_byte = sock_ip & 0xff; 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (CTL_IS_DNS(last_byte)) 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_ip = dns_addr[last_byte - CTL_DNS]; 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_ip = loopback_addr_ip; 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project try_proxy = 0; 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_address_init_inet( &sockaddr, sock_ip, sock_port ); 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_MISC((dfd, " connect()ing, addr=%s, proxy=%d\n", 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_address_to_string(&sockaddr), try_proxy)); 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (try_proxy) { 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!proxy_manager_add(&sockaddr, SOCKET_STREAM, (ProxyEventFunc) tcp_proxy_event, so)) { 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project soisfconnecting(so); 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->s = -1; 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_state |= SS_PROXIFIED; 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((ret=so->s=socket_create_inet(SOCKET_STREAM)) >= 0) 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int s = so->s; 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_nonblock(s); 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_xreuseaddr(s); 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_oobinline(s); 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* We don't care what port we get */ 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_connect(s, &sockaddr); 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If it's not in progress, it failed, so we just return 0, 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * without clearing SS_NOFDREF 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project soisfconnecting(so); 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return(ret); 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Accept the socket and connect to the local-host 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We have a problem. The correct thing to do would be 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to first connect to the local-host, and only if the 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * connection is accepted, then do an accept() here. 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * But, a) we need to know who's trying to connect 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to the socket to be able to SYN the local-host, and 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * b) we are already connected to the foreign host by 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the time it gets to accept(), so... We simply accept 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * here and SYN the local-host. 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_connect(inso) 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *inso; 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so; 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SockAddress addr; 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t addr_ip; 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tcpcb *tp; 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int s; 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_connect"); 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("inso = %lx", (long)inso); 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If it's an SS_ACCEPTONCE socket, no need to socreate() 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * another socket, just use the accept() socket. 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (inso->so_state & SS_FACCEPTONCE) { 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* FACCEPTONCE already have a tcpcb */ 5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so = inso; 5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so = socreate()) == NULL) { 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* If it failed, get rid of the pending connection */ 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_close(socket_accept(inso->s, NULL)); 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcp_attach(so) < 0) { 5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(so); /* NOT sofree */ 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_laddr_ip = inso->so_laddr_ip; 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_laddr_port = inso->so_laddr_port; 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) tcp_mss(sototcpcb(so), 0); 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((s = socket_accept(inso->s, &addr)) < 0) { 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_close(sototcpcb(so)); /* This will sofree() as well */ 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_nonblock(s); 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_xreuseaddr(s); 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_oobinline(s); 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_nodelay(s); 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_faddr_port = sock_address_get_port(&addr); 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project addr_ip = sock_address_get_ip(&addr); 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_faddr_ip = addr_ip; 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Translate connections from localhost to the real hostname */ 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (addr_ip == 0 || addr_ip == loopback_addr_ip) 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_faddr_ip = alias_addr_ip; 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Close the accept() socket, set right state */ 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (inso->so_state & SS_FACCEPTONCE) { 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_close(so->s); /* If we only accept once, close the accept() socket */ 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_state = SS_NOFDREF; /* Don't select it yet, even though we have an FD */ 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if it's not FACCEPTONCE, it's already NOFDREF */ 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->s = s; 5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_iptos = tcp_tos(so); 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = sototcpcb(so); 5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_template(tp); 5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Compute window scaling to request. */ 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* while (tp->request_r_scale < TCP_MAX_WINSHIFT && 5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) 5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->request_r_scale++; 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* soisconnecting(so); */ /* NOFDREF used instead */ 5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcpstat.tcps_connattempt++; 5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_SYN_SENT; 5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->iss = tcp_iss; 5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_iss += TCP_ISSINCR/2; 5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_sendseqinit(tp); 5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_output(tp); 5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Attach a TCPCB to a socket. 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_attach(so) 5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so; 5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) 5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project insque(so, &tcb); 5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Set the socket's type of service field 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct tos_t tcptos[] = { 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */ 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */ 5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 23, IPTOS_LOWDELAY, 0}, /* telnet */ 5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */ 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT}, /* rlogin */ 5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT}, /* shell */ 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 544, IPTOS_LOWDELAY, EMU_KSH}, /* kshell */ 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 543, IPTOS_LOWDELAY, 0}, /* klogin */ 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */ 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 6668, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC undernet */ 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 7070, IPTOS_LOWDELAY, EMU_REALAUDIO }, /* RealAudio control */ 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 113, IPTOS_LOWDELAY, EMU_IDENT }, /* identd protocol */ 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 0, 0, 0} 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Return TOS according to the above table 6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectu_int8_t 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_tos(so) 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so; 6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i = 0; 6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while(tcptos[i].tos) { 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((tcptos[i].fport && so->so_faddr_port == tcptos[i].fport) || 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (tcptos[i].lport && so->so_laddr_port == tcptos[i].lport)) { 6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_emu = tcptos[i].emu; 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return tcptos[i].tos; 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i++; 6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint do_echo = -1; 6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Emulate programs that try and connect to us 6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This includes ftp (the data connection is 6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * initiated by the server) and IRC (DCC CHAT and 6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * DCC SEND) for now 6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * NOTE: It's possible to crash SLiRP by sending it 6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * unstandard strings to emulate... if this is a problem, 6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * more checks are needed here 6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXX Assumes the whole command came in one packet 6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXX Some ftp clients will have their TOS set to 6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LOWDELAY and so Nagel will kick in. Because of this, 6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * we'll get the first letter, followed by the rest, so 6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * we simply scan for ORT instead of PORT... 6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * DCC doesn't have this problem because there's other stuff 6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the packet before the DCC command. 6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Return 1 if the mbuf m is still valid and should be 6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * sbuf_append()ed 6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * NOTE: if you return 0 you MUST mbuf_free() the mbuf! 6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_emu(so, m) 6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so; 6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project MBuf m; 6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_int n1, n2, n3, n4, n5, n6; 6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buff[256]; 6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_int32_t laddr; 6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_int lport; 6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *bptr; 6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_emu"); 6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("so = %lx", (long)so); 6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("m = %lx", (long)m); 6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(so->so_emu) { 6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int x, i; 6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EMU_IDENT: 6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Identification protocol as per rfc-1413 6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *tmpso; 6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SockAddress addr; 6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SBuf so_rcv = &so->so_rcv; 6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); 6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so_rcv->sb_wptr += m->m_len; 6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so_rcv->sb_rptr += m->m_len; 6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_data[m->m_len] = 0; /* NULL terminate */ 6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) { 6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sscanf(so_rcv->sb_data, "%d%*[ ,]%d", &n1, &n2) == 2) { 6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* n2 is the one on our host */ 6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { 6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tmpso->so_laddr_ip == so->so_laddr_ip && 6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmpso->so_laddr_port == n2 && 6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmpso->so_faddr_ip == so->so_faddr_ip && 6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmpso->so_faddr_port == n1) { 6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (socket_get_address(tmpso->s, &addr) == 0) 6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n2 = sock_address_get_port(&addr); 6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so_rcv->sb_cc = sprintf(so_rcv->sb_data, "%d,%d\r\n", n1, n2); 7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so_rcv->sb_rptr = so_rcv->sb_data; 7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; 7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mbuf_free(m); 7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EMU_FTP: /* ftp */ 7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */ 7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) { 7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Need to emulate the PORT command 7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]", 7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &n1, &n2, &n3, &n4, &n5, &n6, buff); 7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (x < 6) 7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project laddr = (n1 << 24) | (n2 << 16) | (n3 << 8) | (n4); 7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lport = (n5 << 8) | (n6); 7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n6 = so->so_faddr_port; 7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n5 = (n6 >> 8) & 0xff; 7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n6 &= 0xff; 7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project laddr = so->so_faddr_ip; 7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n1 = ((laddr >> 24) & 0xff); 7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n2 = ((laddr >> 16) & 0xff); 7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n3 = ((laddr >> 8) & 0xff); 7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n4 = (laddr & 0xff); 7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = bptr - m->m_data; /* Adjust length */ 7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s", 7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n1, n2, n3, n4, n5, n6, x==7?buff:""); 7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { 7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Need to emulate the PASV response 7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project x = sscanf(bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%256[^\177]", 7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &n1, &n2, &n3, &n4, &n5, &n6, buff); 7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (x < 6) 7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project laddr = (n1 << 24) | (n2 << 16) | (n3 << 8) | (n4); 7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lport = (n5 << 8) | (n6); 7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n6 = so->so_faddr_port; 7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n5 = (n6 >> 8) & 0xff; 7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n6 &= 0xff; 7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project laddr = so->so_faddr_ip; 7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n1 = ((laddr >> 24) & 0xff); 7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n2 = ((laddr >> 16) & 0xff); 7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n3 = ((laddr >> 8) & 0xff); 7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n4 = (laddr & 0xff); 7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = bptr - m->m_data; /* Adjust length */ 7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", 7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n1, n2, n3, n4, n5, n6, x==7?buff:""); 7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EMU_KSH: 7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The kshell (Kerberos rsh) and shell services both pass 7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * a local port port number to carry signals to the server 7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and stderr to the client. It is passed at the beginning 7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of the connection as a NUL-terminated decimal ASCII string. 7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_emu = 0; 7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (lport = 0, i = 0; i < m->m_len-1; ++i) { 7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (m->m_data[i] < '0' || m->m_data[i] > '9') 7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; /* invalid number */ 7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lport *= 10; 7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lport += m->m_data[i] - '0'; 7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (m->m_data[m->m_len-1] == '\0' && lport != 0 && 7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (so = solisten(0, so->so_laddr_ip, lport, SS_FACCEPTONCE)) != NULL) 7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = sprintf(m->m_data, "%d", so->so_faddr_port)+1; 7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EMU_IRC: 7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Need to emulate DCC CHAT, DCC SEND and DCC MOVE 7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */ 8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL) 8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* The %256s is for the broken mIRC */ 8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) { 8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = bptr - m->m_data; /* Adjust length */ 8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n", 8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (unsigned long) so->so_faddr_ip, 8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_faddr_port, 1); 8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { 8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = bptr - m->m_data; /* Adjust length */ 8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n", 8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buff, (unsigned long)so->so_faddr_ip, 8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_faddr_port, n1, 1); 8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { 8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = bptr - m->m_data; /* Adjust length */ 8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n", 8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buff, (unsigned long)so->so_faddr_ip, 8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_faddr_port, n1, 1); 8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EMU_REALAUDIO: 8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * RealAudio emulation - JP. We must try to parse the incoming 8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * data and try to find the two characters that contain the 8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * port number. Then we redirect an udp port and replace the 8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * number with the real port we got. 8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The 1.0 beta versions of the player are not supported 8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * any more. 8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * A typical packet for player version 1.0 (release version): 8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0000:50 4E 41 00 05 8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....�..g�l�c..P 8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH 8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v 8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB 8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Now the port number 0x1BD7 is found at offset 0x04 of the 8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Now the port number 0x1BD7 is found at offset 0x04 of the 8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * second packet. This time we received five bytes first and 8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * then the rest. You never know how many bytes you get. 8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * A typical packet for player version 2.0 (beta): 8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........�. 8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .gux�c..Win2.0.0 8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ 8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas 8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B 8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Port number 0x1BC1 is found at offset 0x0d. 8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This is just a horrible switch statement. Variable ra tells 8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * us where we're going. 8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bptr = m->m_data; 8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (bptr < m->m_data + m->m_len) { 8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_short p; 8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static int ra = 0; 8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char ra_tbl[4]; 8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra_tbl[0] = 0x50; 8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra_tbl[1] = 0x4e; 8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra_tbl[2] = 0x41; 8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra_tbl[3] = 0; 8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (ra) { 8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: 8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*bptr++ != ra_tbl[ra]) { 8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra = 0; 8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We may get 0x50 several times, ignore them 8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*bptr == 0x50) { 8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra = 1; 8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bptr++; 8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (*bptr++ != ra_tbl[ra]) { 8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra = 0; 9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 4: 9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * skip version number 9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bptr++; 9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 5: 9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The difference between versions 1.0 and 9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 2.0 is here. For future versions of 9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the player this may need to be modified. 9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*(bptr + 1) == 0x02) 9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bptr += 8; 9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bptr += 4; 9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 6: 9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* This is the field containing the port 9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * number that RA-player is listening to. 9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lport = (((u_char*)bptr)[0] << 8) 9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project + ((u_char *)bptr)[1]; 9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (lport < 6970) 9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lport += 256; /* don't know why */ 9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (lport < 6970 || lport > 7170) 9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; /* failed */ 9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* try to get udp port between 6970 - 7170 */ 9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (p = 6970; p < 7071; p++) { 9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (udp_listen( p, 9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_laddr_ip, 9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lport, 9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SS_FACCEPTONCE)) { 9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p == 7071) 9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = 0; 9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(u_char *)bptr++ = (p >> 8) & 0xff; 9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(u_char *)bptr++ = p & 0xff; 9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra = 0; 9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; /* port redirected, we're done */ 9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra = 0; 9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra++; 9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Ooops, not emulated, won't call tcp_emu again */ 9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_emu = 0; 9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Do misc. config of SLiRP while its running. 9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Return 0 if this connections is to be closed, 1 otherwise, 9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * return 2 if this is a command-line connection 9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_ctl(so) 9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so; 9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SBuf sb = &so->so_snd; 9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int command; 9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct ex_list *ex_ptr; 9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int do_pty; 9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project // struct socket *tmpso; 9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_ctl"); 9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("so = %lx", (long )so); 9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Check if they're authorised 9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ctl_addr_ip && (ctl_addr_ip == -1 || (so->so_laddr_ip != ctl_addr_ip))) { 9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sb->sb_cc = sprintf(sb->sb_wptr,"Error: Permission denied.\r\n"); 9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sb->sb_wptr += sb->sb_cc; 9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project command = (so->so_faddr_ip & 0xff); 9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(command) { 9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Nothing bound.. 10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* tcp_fconnect(so); */ 10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case CTL_ALIAS: 10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sb->sb_cc = sprintf(sb->sb_wptr, 10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Error: No application configured.\r\n"); 10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sb->sb_wptr += sb->sb_cc; 10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return(0); 10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1011