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. 135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 3. Neither the name of the University nor the names of its contributors 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * may be used to endorse or promote products derived from this software 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * without specific prior written permission. 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * SUCH DAMAGE. 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * @(#)tcp_subr.c 8.1 (Berkeley) 6/10/93 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tcp_subr.c,v 1.5 1994/10/08 22:39:58 phk Exp 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Changes and additions relating to SLiRP 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 1995 Danny Gasparovski. 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Please read the file COPYRIGHT for the 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * terms and conditions of the copyright. 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <slirp.h> 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* patchable/settable parameters for tcp */ 445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Don't do rfc1323 performance enhancements */ 455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define TCP_DO_RFC1323 0 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Tcp initialization 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_init(void) 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_iss = 1; /* wrong */ 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcb.so_next = tcb.so_prev = &tcb; 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Create template to be used to send tcp packets on a connection. 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Call after host entry created, fills 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in a skeletal tcp/ip header, minimizing the amount of work 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * necessary when the connection is used. 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* struct tcpiphdr * */ 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_template(struct tcpcb *tp) 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so = tp->t_socket; 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register struct tcpiphdr *n = &tp->t_template; 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_mbuf = NULL; 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_x1 = 0; 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_pr = IPPROTO_TCP; 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); 745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n->ti_src = so->so_faddr; 755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n->ti_dst = so->so_laddr; 765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n->ti_sport = so->so_fport; 775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n->ti_dport = so->so_lport; 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_seq = 0; 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_ack = 0; 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_x2 = 0; 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_off = 5; 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_flags = 0; 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_win = 0; 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_sum = 0; 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n->ti_urp = 0; 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Send a single message to the TCP at address specified by 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the given TCP/IP header. If m == 0, then we make a copy 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of the tcpiphdr at ti and send directly to the addressed host. 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This is used to force keep alive messages out using the TCP 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * template for a connection tp->t_template. If flags are given 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * then we send a message back to the TCP which originated the 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * segment ti, and discard the mbuf containing it and any other 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * attached mbufs. 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * In any case the ack and sequence number of the transmitted 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * segment are as specified by the parameters. 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m, 1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcp_seq ack, tcp_seq seq, int flags) 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register int tlen; 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int win = 0; 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_respond"); 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("tp = %lx", (long)tp); 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("ti = %lx", (long)ti); 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("m = %lx", (long)m); 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("ack = %u", ack); 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("seq = %u", seq); 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("flags = %x", flags); 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp) 1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner win = sbspace(&tp->t_socket->so_rcv); 1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (m == NULL) { 1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((m = m_get()) == NULL) 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TCP_COMPAT_42 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlen = 1; 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlen = 0; 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m->m_data += IF_MAXLINKHDR; 1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *mtod(m, struct tcpiphdr *) = *ti; 1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ti = mtod(m, struct tcpiphdr *); 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags = TH_ACK; 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ti points into m so the next line is just making 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the mbuf point to ti 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_data = (caddr_t)ti; 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = sizeof (struct tcpiphdr); 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlen = 0; 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define xchg(a,b,type) { type t; t=a; a=b; b=t; } 1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_int32_t); 1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner xchg(ti->ti_dport, ti->ti_sport, u_int16_t); 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef xchg 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen)); 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tlen += sizeof (struct tcpiphdr); 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = tlen; 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ti->ti_mbuf = NULL; 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_x1 = 0; 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_seq = htonl(seq); 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_ack = htonl(ack); 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_x2 = 0; 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_off = sizeof (struct tcphdr) >> 2; 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_flags = flags; 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp) 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_win = htons((u_int16_t) (win >> tp->rcv_scale)); 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_win = htons((u_int16_t)win); 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_urp = 0; 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_sum = 0; 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ti->ti_sum = cksum(m, tlen); 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((struct ip *)ti)->ip_len = tlen; 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(flags & TH_RST) 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((struct ip *)ti)->ip_ttl = MAXTTL; 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ((struct ip *)ti)->ip_ttl = IPDEFTTL; 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) ip_output((struct socket *)0, m); 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Create a new TCP control block, making an 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * empty reassembly queue and hooking it to the argument 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * protocol control block. 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct tcpcb * 1795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_newtcpcb(struct socket *so) 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register struct tcpcb *tp; 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = (struct tcpcb *)malloc(sizeof(*tp)); 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp == NULL) 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ((struct tcpcb *)0); 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memset((char *) tp, 0, sizeof(struct tcpcb)); 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp; 1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tp->t_maxseg = TCP_MSS; 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_socket = so; 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * reasonable initial retransmit time. 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_srtt = TCPTV_SRTTBASE; 2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tp->t_rttvar = TCPTV_SRTTDFLT << 2; 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_rttmin = TCPTV_MIN; 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCPT_RANGESET(tp->t_rxtcur, 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1, 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TCPTV_MIN, TCPTV_REXMTMAX); 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_CLOSED; 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_tcpcb = tp; 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (tp); 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Drop a TCP connection, reporting 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the specified error. If connection is synchronized, 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * then send a RST to peer. 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct tcpcb *tcp_drop(struct tcpcb *tp, int err) 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* tcp_drop(tp, errno) 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register struct tcpcb *tp; 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int errno; 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_drop"); 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("tp = %lx", (long)tp); 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("errno = %d", errno); 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (TCPS_HAVERCVDSYN(tp->t_state)) { 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_CLOSED; 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) tcp_output(tp); 2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_drops++); 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_conndrops++); 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (errno == ETIMEDOUT && tp->t_softerror) 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * errno = tp->t_softerror; 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* so->so_error = errno; */ 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (tcp_close(tp)); 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Close a TCP control block: 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * discard all space held by the tcp 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * discard internet protocol block 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * wake up any sleepers 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct tcpcb * 2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_close(struct tcpcb *tp) 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register struct tcpiphdr *t; 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so = tp->t_socket; 2575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner register struct mbuf *m; 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_close"); 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("tp = %lx", (long )tp); 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* free the reassembly queue, if any */ 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project t = tcpfrag_list_first(tp); 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (!tcpfrag_list_end(t, tp)) { 2655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner t = tcpiphdr_next(t); 2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m = tcpiphdr_prev(t)->ti_mbuf; 2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner remque(tcpiphdr2qlink(tcpiphdr_prev(t))); 2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_freem(m); 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* It's static */ 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* if (tp->t_template) 2725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * (void) m_free(dtom(tp->t_template)); 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* free(tp, M_PCB); */ 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(tp); 2765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_tcpcb = NULL; 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project soisfdisconnected(so); 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* clobber input socket cache if we're closing the cached connection */ 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so == tcp_last_so) 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_last_so = &tcb; 2815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner closesocket(so->s); 2825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbfree(&so->so_rcv); 2835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbfree(&so->so_snd); 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sofree(so); 2855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_closed++); 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ((struct tcpcb *)0); 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef notdef 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_drain() 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* XXX */ 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * When a source quench is received, close congestion window 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to one segment. We will gradually open it again as we proceed. 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttcp_quench(i, errno) 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int errno; 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tcpcb *tp = intotcpcb(inp); 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp) 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->snd_cwnd = tp->t_maxseg; 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* notdef */ 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * TCP protocol interface to socket abstraction. 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * User issued close, and wish to trail through shutdown states: 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if never received SYN, just forget it. If got a SYN from peer, 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If already got a FIN from peer, then almost done; go to LAST_ACK 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * state. In all other cases, have already sent FIN to peer (e.g. 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * after PRU_SHUTDOWN), and just have to play tedious game waiting 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * for peer to send FIN or not respond to keep-alives, etc. 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We can let the user exit from the close as soon as the FIN is acked. 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 3285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_sockclosed(struct tcpcb *tp) 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_sockclosed"); 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("tp = %lx", (long)tp); 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (tp->t_state) { 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_CLOSED: 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_LISTEN: 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_SYN_SENT: 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_CLOSED; 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = tcp_close(tp); 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_SYN_RECEIVED: 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_ESTABLISHED: 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_FIN_WAIT_1; 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TCPS_CLOSE_WAIT: 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_LAST_ACK; 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* soisfdisconnecting(tp->t_socket); */ 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp && tp->t_state >= TCPS_FIN_WAIT_2) 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project soisfdisconnected(tp->t_socket); 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tp) 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_output(tp); 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Connect to a host on the Internet 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Called by tcp_input 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Only do a connect, the tcp fields will be set in tcp_input 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * return 0 if there's a result of the connect, 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * else return -1 means we're still connecting 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The return value is almost always -1 since the socket is 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * nonblocking. Connect returns after the SYN is sent, and does 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * not wait for ACK+SYN. 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint tcp_fconnect(struct socket *so) 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int ret=0; 3725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DEBUG_CALL("tcp_fconnect"); 3745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DEBUG_ARG("so = %lx", (long )so); 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if( (ret=so->s=socket(AF_INET,SOCK_STREAM,0)) >= 0) { 3775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int opt, s=so->s; 3785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sockaddr_in addr; 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fd_nonblock(s); 3815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner opt = 1; 3825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(opt )); 3835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner opt = 1; 3845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt )); 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr.sin_family = AF_INET; 3875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* It's an alias */ 3895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch(ntohl(so->so_faddr.s_addr) & 0xff) { 3905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case CTL_DNS: 3915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr.sin_addr = dns_addr; 3925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 3935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case CTL_ALIAS: 3945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: 3955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr.sin_addr = loopback_addr; 3965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 3975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else 3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr.sin_addr = so->so_faddr; 4005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr.sin_port = so->so_fport; 4015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, " 4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "addr.sin_addr.s_addr=%.16s\n", 4045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); 4055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* We don't care what port we get */ 4065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = connect(s,(struct sockaddr *)&addr,sizeof (addr)); 4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* 4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * If it's not in progress, it failed, so we just return 0, 4105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * without clearing SS_NOFDREF 4115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner soisfconnecting(so); 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return(ret); 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Accept the socket and connect to the local-host 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We have a problem. The correct thing to do would be 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to first connect to the local-host, and only if the 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * connection is accepted, then do an accept() here. 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * But, a) we need to know who's trying to connect 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to the socket to be able to SYN the local-host, and 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * b) we are already connected to the foreign host by 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the time it gets to accept(), so... We simply accept 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * here and SYN the local-host. 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 4315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_connect(struct socket *inso) 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *so; 4345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sockaddr_in addr; 4355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner socklen_t addrlen = sizeof(struct sockaddr_in); 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct tcpcb *tp; 4375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int s, opt; 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_connect"); 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("inso = %lx", (long)inso); 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If it's an SS_ACCEPTONCE socket, no need to socreate() 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * another socket, just use the accept() socket. 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (inso->so_state & SS_FACCEPTONCE) { 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* FACCEPTONCE already have a tcpcb */ 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so = inso; 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so = socreate()) == NULL) { 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* If it failed, get rid of the pending connection */ 4525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner closesocket(accept(inso->s,(struct sockaddr *)&addr,&addrlen)); 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (tcp_attach(so) < 0) { 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free(so); /* NOT sofree */ 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_laddr = inso->so_laddr; 4605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_lport = inso->so_lport; 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) tcp_mss(sototcpcb(so), 0); 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) { 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_close(sototcpcb(so)); /* This will sofree() as well */ 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fd_nonblock(s); 4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner opt = 1; 4715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); 4725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner opt = 1; 4735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); 4745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner opt = 1; 4755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int)); 4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_fport = addr.sin_port; 4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_faddr = addr.sin_addr; 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Translate connections from localhost to the real hostname */ 4805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) 4815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_faddr = alias_addr; 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Close the accept() socket, set right state */ 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (inso->so_state & SS_FACCEPTONCE) { 4855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner closesocket(so->s); /* If we only accept once, close the accept() socket */ 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_state = SS_NOFDREF; /* Don't select it yet, even though we have an FD */ 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if it's not FACCEPTONCE, it's already NOFDREF */ 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->s = s; 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_iptos = tcp_tos(so); 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp = sototcpcb(so); 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_template(tp); 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Compute window scaling to request. */ 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* while (tp->request_r_scale < TCP_MAX_WINSHIFT && 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * tp->request_r_scale++; 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* soisconnecting(so); */ /* NOFDREF used instead */ 5035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_connattempt++); 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_state = TCPS_SYN_SENT; 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; 5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tp->iss = tcp_iss; 5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_iss += TCP_ISSINCR/2; 5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_sendseqinit(tp); 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tcp_output(tp); 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Attach a TCPCB to a socket. 5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 5175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_attach(struct socket *so) 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project insque(so, &tcb); 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Set the socket's type of service field 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic const struct tos_t tcptos[] = { 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */ 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */ 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 23, IPTOS_LOWDELAY, 0}, /* telnet */ 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */ 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT}, /* rlogin */ 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT}, /* shell */ 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 544, IPTOS_LOWDELAY, EMU_KSH}, /* kshell */ 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 543, IPTOS_LOWDELAY, 0}, /* klogin */ 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */ 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 6668, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC undernet */ 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 7070, IPTOS_LOWDELAY, EMU_REALAUDIO }, /* RealAudio control */ 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 113, IPTOS_LOWDELAY, EMU_IDENT }, /* identd protocol */ 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {0, 0, 0, 0} 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_QEMU 5475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic 5485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 5495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct emu_t *tcpemu = NULL; 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Return TOS according to the above table 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectu_int8_t 5555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_tos(struct socket *so) 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i = 0; 5585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct emu_t *emup; 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while(tcptos[i].tos) { 5615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) || 5625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) { 5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_emu = tcptos[i].emu; 5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return tcptos[i].tos; 5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project i++; 5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Nope, lets see if there's a user-added one */ 5705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (emup = tcpemu; emup; emup = emup->next) { 5715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((emup->fport && (ntohs(so->so_fport) == emup->fport)) || 5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (emup->lport && (ntohs(so->so_lport) == emup->lport))) { 5735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_emu = emup->emu; 5745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return emup->tos; 5755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint do_echo = -1; 5835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Emulate programs that try and connect to us 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This includes ftp (the data connection is 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * initiated by the server) and IRC (DCC CHAT and 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * DCC SEND) for now 5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * NOTE: It's possible to crash SLiRP by sending it 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * unstandard strings to emulate... if this is a problem, 5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * more checks are needed here 5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXX Assumes the whole command came in one packet 5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXX Some ftp clients will have their TOS set to 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LOWDELAY and so Nagel will kick in. Because of this, 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * we'll get the first letter, followed by the rest, so 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * we simply scan for ORT instead of PORT... 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * DCC doesn't have this problem because there's other stuff 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the packet before the DCC command. 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Return 1 if the mbuf m is still valid and should be 6055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * sbappend()ed 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 6075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * NOTE: if you return 0 you MUST m_free() the mbuf! 6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 6105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_emu(struct socket *so, struct mbuf *m) 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_int n1, n2, n3, n4, n5, n6; 6135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char buff[257]; 6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_int32_t laddr; 6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_int lport; 6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *bptr; 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_emu"); 6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("so = %lx", (long)so); 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("m = %lx", (long)m); 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(so->so_emu) { 6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int x, i; 6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EMU_IDENT: 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Identification protocol as per rfc-1413 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct socket *tmpso; 6325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sockaddr_in addr; 6335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner socklen_t addrlen = sizeof(struct sockaddr_in); 6345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sbuf *so_rcv = &so->so_rcv; 6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); 6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so_rcv->sb_wptr += m->m_len; 6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so_rcv->sb_rptr += m->m_len; 6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_data[m->m_len] = 0; /* NULL terminate */ 6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) { 6415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) { 6425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner HTONS(n1); 6435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner HTONS(n2); 6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* n2 is the one on our host */ 6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { 6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr && 6475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tmpso->so_lport == n2 && 6485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tmpso->so_faddr.s_addr == so->so_faddr.s_addr && 6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tmpso->so_fport == n1) { 6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (getsockname(tmpso->s, 6515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (struct sockaddr *)&addr, &addrlen) == 0) 6525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n2 = ntohs(addr.sin_port); 6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_rcv->sb_cc = snprintf(so_rcv->sb_data, 6585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_rcv->sb_datalen, 6595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "%d,%d\r\n", n1, n2); 6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so_rcv->sb_rptr = so_rcv->sb_data; 6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; 6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_free(m); 6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 6685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case EMU_RLOGIN: 6695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* 6705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Rlogin emulation 6715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * First we accumulate all the initial option negotiation, 6725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * then fork_exec() rlogin according to the options 6735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 6745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 6755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int i, i2, n; 6765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *ptr; 6775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char args[100]; 6785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char term[100]; 6795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sbuf *so_snd = &so->so_snd; 6805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sbuf *so_rcv = &so->so_rcv; 6815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* First check if they have a priveladged port, or too much data has arrived */ 6835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 || 6845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) { 6855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memcpy(so_snd->sb_wptr, "Permission denied\n", 18); 6865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_wptr += 18; 6875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_cc += 18; 6885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcp_sockclosed(sototcpcb(so)); 6895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_free(m); 6905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 6915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Append the current data */ 6945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); 6955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_rcv->sb_wptr += m->m_len; 6965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_rcv->sb_rptr += m->m_len; 6975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_free(m); 6985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* 7005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Check if we have all the initial options, 7015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * and build argument list to rlogin while we're here 7025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 7035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n = 0; 7045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ptr = so_rcv->sb_data; 7055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner args[0] = 0; 7065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner term[0] = 0; 7075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (ptr < so_rcv->sb_wptr) { 7085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (*ptr++ == 0) { 7095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n++; 7105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (n == 2) { 7115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sprintf(args, "rlogin -l %s %s", 7125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ptr, inet_ntoa(so->so_faddr)); 7135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (n == 3) { 7145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner i2 = so_rcv->sb_wptr - ptr; 7155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (i = 0; i < i2; i++) { 7165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ptr[i] == '/') { 7175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ptr[i] = 0; 7185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAVE_SETENV 7195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sprintf(term, "%s", ptr); 7205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 7215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sprintf(term, "TERM=%s", ptr); 7225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 7235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ptr[i] = '/'; 7245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 7255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (n != 4) 7325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 7335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* We have it, set our term variable and fork_exec() */ 7355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAVE_SETENV 7365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner setenv("TERM", term, 1); 7375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 7385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner putenv(term); 7395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 7405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fork_exec(so, args, 2); 7415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner term[0] = 0; 7425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_emu = 0; 7435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* And finally, send the client a 0 character */ 7455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_wptr[0] = 0; 7465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_wptr++; 7475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_cc++; 7485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 7505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case EMU_RSH: 7535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* 7545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * rsh emulation 7555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * First we accumulate all the initial option negotiation, 7565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * then rsh_exec() rsh according to the options 7575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 7585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 7595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int n; 7605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *ptr; 7615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *user; 7625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *args; 7635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sbuf *so_snd = &so->so_snd; 7645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sbuf *so_rcv = &so->so_rcv; 7655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* First check if they have a priveladged port, or too much data has arrived */ 7675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 || 7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) { 7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memcpy(so_snd->sb_wptr, "Permission denied\n", 18); 7705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_wptr += 18; 7715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_cc += 18; 7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcp_sockclosed(sototcpcb(so)); 7735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_free(m); 7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 7755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Append the current data */ 7785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); 7795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_rcv->sb_wptr += m->m_len; 7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_rcv->sb_rptr += m->m_len; 7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_free(m); 7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* 7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Check if we have all the initial options, 7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * and build argument list to rlogin while we're here 7865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n = 0; 7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ptr = so_rcv->sb_data; 7895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner user=""; 7905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner args=""; 7915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (so->extra==NULL) { 7925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct socket *ns; 7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct tcpcb* tp; 7945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int port=atoi(ptr); 7955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (port <= 0) return 0; 7965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (port > 1023 || port < 512) { 7975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memcpy(so_snd->sb_wptr, "Permission denied\n", 18); 7985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_wptr += 18; 7995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_cc += 18; 8005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcp_sockclosed(sototcpcb(so)); 8015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 8025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((ns=socreate()) == NULL) 8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (tcp_attach(ns)<0) { 8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner free(ns); 8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ns->so_laddr=so->so_laddr; 8115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ns->so_lport=htons(port); 8125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (void) tcp_mss(sototcpcb(ns), 0); 8145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ns->so_faddr=so->so_faddr; 8165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ns->so_fport=htons(IPPORT_RESERVED-1); /* Use a fake port. */ 8175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ns->so_faddr.s_addr == 0 || 8195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ns->so_faddr.s_addr == loopback_addr.s_addr) 8205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ns->so_faddr = alias_addr; 8215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ns->so_iptos = tcp_tos(ns); 8235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tp = sototcpcb(ns); 8245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcp_template(tp); 8265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Compute window scaling to request. */ 8285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* while (tp->request_r_scale < TCP_MAX_WINSHIFT && 8295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) 8305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * tp->request_r_scale++; 8315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 8325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /*soisfconnecting(ns);*/ 8345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner STAT(tcpstat.tcps_connattempt++); 8365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tp->t_state = TCPS_SYN_SENT; 8385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; 8395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tp->iss = tcp_iss; 8405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcp_iss += TCP_ISSINCR/2; 8415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcp_sendseqinit(tp); 8425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcp_output(tp); 8435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->extra=ns; 8445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (ptr < so_rcv->sb_wptr) { 8465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (*ptr++ == 0) { 8475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n++; 8485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (n == 2) { 8495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner user=ptr; 8505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else if (n == 3) { 8515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner args=ptr; 8525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (n != 4) 8575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 8585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner rsh_exec(so,so->extra, user, inet_ntoa(so->so_faddr), args); 8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_emu = 0; 8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->extra=NULL; 8625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* And finally, send the client a 0 character */ 8645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_wptr[0] = 0; 8655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_wptr++; 8665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_cc++; 8675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case EMU_CTL: 8725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 8735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int num; 8745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sbuf *so_snd = &so->so_snd; 8755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sbuf *so_rcv = &so->so_rcv; 8765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* 8785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * If there is binary data here, we save it in so->so_m 8795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 8805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!so->so_m) { 8815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int rxlen; 8825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *rxdata; 8835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner rxdata=mtod(m, char *); 8845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (rxlen=m->m_len; rxlen; rxlen--) { 8855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (*rxdata++ & 0x80) { 8865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_m = m; 8875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 8885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } /* if(so->so_m==NULL) */ 8915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* 8935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Append the line 8945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 8955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbappendsb(so_rcv, m); 8965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* To avoid going over the edge of the buffer, we reset it */ 8985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (so_snd->sb_cc == 0) 8995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_wptr = so_snd->sb_rptr = so_snd->sb_data; 9005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* 9025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * A bit of a hack: 9035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * If the first packet we get here is 1 byte long, then it 9045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * was done in telnet character mode, therefore we must echo 9055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * the characters as they come. Otherwise, we echo nothing, 9065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * because in linemode, the line is already echoed 9075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * XXX two or more control connections won't work 9085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 9095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (do_echo == -1) { 9105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (m->m_len == 1) do_echo = 1; 9115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else do_echo = 0; 9125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (do_echo) { 9145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbappendsb(so_snd, m); 9155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_free(m); 9165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcp_output(sototcpcb(so)); /* XXX */ 9175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else 9185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_free(m); 9195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner num = 0; 9215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (num < so->so_rcv.sb_cc) { 9225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (*(so->so_rcv.sb_rptr + num) == '\n' || 9235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *(so->so_rcv.sb_rptr + num) == '\r') { 9245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int n; 9255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *(so_rcv->sb_rptr + num) = 0; 9275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ctl_password && !ctl_password_ok) { 9285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Need a password */ 9295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (sscanf(so_rcv->sb_rptr, "pass %256s", buff) == 1) { 9305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (strcmp(buff, ctl_password) == 0) { 9315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ctl_password_ok = 1; 9325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n = sprintf(so_snd->sb_wptr, 9335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "Password OK.\r\n"); 9345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto do_prompt; 9355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n = sprintf(so_snd->sb_wptr, 9385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "Error: Password required, log on with \"pass PASSWORD\"\r\n"); 9395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto do_prompt; 9405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cfg_quitting = 0; 9425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n = do_config(so_rcv->sb_rptr, so, PRN_SPRINTF); 9435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (!cfg_quitting) { 9445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Register the printed data */ 9455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerdo_prompt: 9465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_cc += n; 9475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_wptr += n; 9485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Add prompt */ 9495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n = sprintf(so_snd->sb_wptr, "Slirp> "); 9505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_cc += n; 9515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_snd->sb_wptr += n; 9525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Drop so_rcv data */ 9545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_rcv->sb_cc = 0; 9555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so_rcv->sb_wptr = so_rcv->sb_rptr = so_rcv->sb_data; 9565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcp_output(sototcpcb(so)); /* Send the reply */ 9575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner num++; 9595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 9615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EMU_FTP: /* ftp */ 9645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *(m->m_data+m->m_len) = 0; /* NUL terminate for strstr */ 9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) { 9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Need to emulate the PORT command 9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner x = sscanf(bptr, "ORT %u,%u,%u,%u,%u,%u\r\n%256[^\177]", 9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &n1, &n2, &n3, &n4, &n5, &n6, buff); 9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (x < 6) 9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); 9755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lport = htons((n5 << 8) | (n6)); 9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n6 = ntohs(so->so_fport); 9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n5 = (n6 >> 8) & 0xff; 9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n6 &= 0xff; 9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner laddr = ntohl(so->so_faddr.s_addr); 9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n1 = ((laddr >> 24) & 0xff); 9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n2 = ((laddr >> 16) & 0xff); 9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n3 = ((laddr >> 8) & 0xff); 9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n4 = (laddr & 0xff); 9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = bptr - m->m_data; /* Adjust length */ 9935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m->m_len += snprintf(bptr, m->m_hdr.mh_size - m->m_len, 9945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "ORT %d,%d,%d,%d,%d,%d\r\n%s", 9955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n1, n2, n3, n4, n5, n6, x==7?buff:""); 9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { 9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Need to emulate the PASV response 10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 10015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner x = sscanf(bptr, "27 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n%256[^\177]", 10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &n1, &n2, &n3, &n4, &n5, &n6, buff); 10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (x < 6) 10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); 10075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lport = htons((n5 << 8) | (n6)); 10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n6 = ntohs(so->so_fport); 10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n5 = (n6 >> 8) & 0xff; 10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n6 &= 0xff; 10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner laddr = ntohl(so->so_faddr.s_addr); 10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n1 = ((laddr >> 24) & 0xff); 10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n2 = ((laddr >> 16) & 0xff); 10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n3 = ((laddr >> 8) & 0xff); 10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n4 = (laddr & 0xff); 10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = bptr - m->m_data; /* Adjust length */ 10255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m->m_len += snprintf(bptr, m->m_hdr.mh_size - m->m_len, 10265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", 10275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n1, n2, n3, n4, n5, n6, x==7?buff:""); 10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EMU_KSH: 10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The kshell (Kerberos rsh) and shell services both pass 10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * a local port port number to carry signals to the server 10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and stderr to the client. It is passed at the beginning 10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of the connection as a NUL-terminated decimal ASCII string. 10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_emu = 0; 10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (lport = 0, i = 0; i < m->m_len-1; ++i) { 10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (m->m_data[i] < '0' || m->m_data[i] > '9') 10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; /* invalid number */ 10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lport *= 10; 10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lport += m->m_data[i] - '0'; 10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (m->m_data[m->m_len-1] == '\0' && lport != 0 && 10495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL) 10505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m->m_len = snprintf(m->m_data, m->m_hdr.mh_size, "%d", 10515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ntohs(so->so_fport)) + 1; 10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EMU_IRC: 10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Need to emulate DCC CHAT, DCC SEND and DCC MOVE 10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */ 10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL) 10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* The %256s is for the broken mIRC */ 10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) { 10645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) 10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = bptr - m->m_data; /* Adjust length */ 10685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m->m_len += snprintf(bptr, m->m_hdr.mh_size, 10695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "DCC CHAT chat %lu %u%c\n", 10705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (unsigned long)ntohl(so->so_faddr.s_addr), 10715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ntohs(so->so_fport), 1); 10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { 10735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) 10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = bptr - m->m_data; /* Adjust length */ 10775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m->m_len += snprintf(bptr, m->m_hdr.mh_size, 10785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "DCC SEND %s %lu %u %u%c\n", buff, 10795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (unsigned long)ntohl(so->so_faddr.s_addr), 10805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ntohs(so->so_fport), n1, 1); 10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { 10825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) 10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project m->m_len = bptr - m->m_data; /* Adjust length */ 10865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m->m_len += snprintf(bptr, m->m_hdr.mh_size, 10875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "DCC MOVE %s %lu %u %u%c\n", buff, 10885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (unsigned long)ntohl(so->so_faddr.s_addr), 10895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ntohs(so->so_fport), n1, 1); 10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EMU_REALAUDIO: 10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * RealAudio emulation - JP. We must try to parse the incoming 10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * data and try to find the two characters that contain the 10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * port number. Then we redirect an udp port and replace the 10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * number with the real port we got. 10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The 1.0 beta versions of the player are not supported 11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * any more. 11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * A typical packet for player version 1.0 (release version): 11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0000:50 4E 41 00 05 11065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....�..g�l�c..P 11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH 11088b23a6c7e1aee255004dd19098d4c2462b61b849The 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 11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB 11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Now the port number 0x1BD7 is found at offset 0x04 of the 11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Now the port number 0x1BD7 is found at offset 0x04 of the 11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * second packet. This time we received five bytes first and 11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * then the rest. You never know how many bytes you get. 11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * A typical packet for player version 2.0 (beta): 11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 11185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........�. 11195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .gux�c..Win2.0.0 11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ 11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas 11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B 11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Port number 0x1BC1 is found at offset 0x0d. 11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This is just a horrible switch statement. Variable ra tells 11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * us where we're going. 11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bptr = m->m_data; 11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (bptr < m->m_data + m->m_len) { 11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_short p; 11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static int ra = 0; 11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char ra_tbl[4]; 11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra_tbl[0] = 0x50; 11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra_tbl[1] = 0x4e; 11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra_tbl[2] = 0x41; 11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra_tbl[3] = 0; 11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (ra) { 11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: 11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: 11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*bptr++ != ra_tbl[ra]) { 11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra = 0; 11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We may get 0x50 several times, ignore them 11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*bptr == 0x50) { 11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra = 1; 11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bptr++; 11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else if (*bptr++ != ra_tbl[ra]) { 11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra = 0; 11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 4: 11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * skip version number 11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bptr++; 11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 5: 11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The difference between versions 1.0 and 11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 2.0 is here. For future versions of 11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the player this may need to be modified. 11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*(bptr + 1) == 0x02) 11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bptr += 8; 11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bptr += 4; 11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 6: 11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* This is the field containing the port 11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * number that RA-player is listening to. 11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lport = (((u_char*)bptr)[0] << 8) 11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project + ((u_char *)bptr)[1]; 11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (lport < 6970) 11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lport += 256; /* don't know why */ 11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (lport < 6970 || lport > 7170) 11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; /* failed */ 11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* try to get udp port between 6970 - 7170 */ 11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (p = 6970; p < 7071; p++) { 11975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (udp_listen( htons(p), 11985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_laddr.s_addr, 11995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner htons(lport), 12005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner SS_FACCEPTONCE)) { 12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p == 7071) 12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = 0; 12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(u_char *)bptr++ = (p >> 8) & 0xff; 12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(u_char *)bptr++ = p & 0xff; 12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra = 0; 12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; /* port redirected, we're done */ 12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra = 0; 12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ra++; 12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Ooops, not emulated, won't call tcp_emu again */ 12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_emu = 0; 12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Do misc. config of SLiRP while its running. 12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Return 0 if this connections is to be closed, 1 otherwise, 12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * return 2 if this is a command-line connection 12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 12325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertcp_ctl(struct socket *so) 12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sbuf *sb = &so->so_snd; 12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int command; 12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct ex_list *ex_ptr; 12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int do_pty; 12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project // struct socket *tmpso; 12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("tcp_ctl"); 12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("so = %lx", (long )so); 12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Check if they're authorised 12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 12475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ctl_addr.s_addr && (ctl_addr.s_addr == -1 || (so->so_laddr.s_addr != ctl_addr.s_addr))) { 12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sb->sb_cc = sprintf(sb->sb_wptr,"Error: Permission denied.\r\n"); 12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sb->sb_wptr += sb->sb_cc; 12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 12535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner command = (ntohl(so->so_faddr.s_addr) & 0xff); 12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch(command) { 12565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: /* Check for exec's */ 12575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 12585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* 12595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Check if it's pty_exec 12605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 12615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { 12625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ex_ptr->ex_fport == so->so_fport && 12635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner command == ex_ptr->ex_addr) { 12645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ex_ptr->ex_pty == 3) { 12655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->s = -1; 12665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->extra = (void *)ex_ptr->ex_exec; 12675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 1; 12685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 12695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner do_pty = ex_ptr->ex_pty; 12705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner goto do_exec; 12715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 12725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 12735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Nothing bound.. 12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* tcp_fconnect(so); */ 12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* FALLTHROUGH */ 12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case CTL_ALIAS: 12815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sb->sb_cc = snprintf(sb->sb_wptr, sb->sb_datalen - (sb->sb_wptr - sb->sb_data), 12825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "Error: No application configured.\r\n"); 12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sb->sb_wptr += sb->sb_cc; 12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return(0); 12855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 12865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner do_exec: 12875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec)); 12885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return(fork_exec(so, ex_ptr->ex_exec, do_pty)); 12895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 12905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 12915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case CTL_CMD: 12925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { 12935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (tmpso->so_emu == EMU_CTL && 12945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner !(tmpso->so_tcpcb? 12955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (tmpso->so_tcpcb->t_state & (TCPS_TIME_WAIT|TCPS_LAST_ACK)) 12965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner :0)) { 12975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Ooops, control connection already active */ 12985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sb->sb_cc = sprintf(sb->sb_wptr,"Sorry, already connected.\r\n"); 12995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sb->sb_wptr += sb->sb_cc; 13005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 13015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 13025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 13035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_emu = EMU_CTL; 13045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ctl_password_ok = 0; 13055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sb->sb_cc = sprintf(sb->sb_wptr, "Slirp command-line ready (type \"help\" for help).\r\nSlirp> "); 13065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sb->sb_wptr += sb->sb_cc; 13075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner do_echo=-1; 13085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return(2); 13095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1312