1 /* 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)tcp_subr.c 8.1 (Berkeley) 6/10/93 30 * tcp_subr.c,v 1.5 1994/10/08 22:39:58 phk Exp 31 */ 32 33 /* 34 * Changes and additions relating to SLiRP 35 * Copyright (c) 1995 Danny Gasparovski. 36 * 37 * Please read the file COPYRIGHT for the 38 * terms and conditions of the copyright. 39 */ 40 41 #include <slirp.h> 42 43 /* patchable/settable parameters for tcp */ 44 /* Don't do rfc1323 performance enhancements */ 45 #define TCP_DO_RFC1323 0 46 47 /* 48 * Tcp initialization 49 */ 50 void 51 tcp_init(void) 52 { 53 tcp_iss = 1; /* wrong */ 54 tcb.so_next = tcb.so_prev = &tcb; 55 } 56 57 /* 58 * Create template to be used to send tcp packets on a connection. 59 * Call after host entry created, fills 60 * in a skeletal tcp/ip header, minimizing the amount of work 61 * necessary when the connection is used. 62 */ 63 /* struct tcpiphdr * */ 64 void 65 tcp_template(struct tcpcb *tp) 66 { 67 struct socket *so = tp->t_socket; 68 register struct tcpiphdr *n = &tp->t_template; 69 70 n->ti_mbuf = NULL; 71 n->ti_x1 = 0; 72 n->ti_pr = IPPROTO_TCP; 73 n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); 74 n->ti_src = so->so_faddr; 75 n->ti_dst = so->so_laddr; 76 n->ti_sport = so->so_fport; 77 n->ti_dport = so->so_lport; 78 79 n->ti_seq = 0; 80 n->ti_ack = 0; 81 n->ti_x2 = 0; 82 n->ti_off = 5; 83 n->ti_flags = 0; 84 n->ti_win = 0; 85 n->ti_sum = 0; 86 n->ti_urp = 0; 87 } 88 89 /* 90 * Send a single message to the TCP at address specified by 91 * the given TCP/IP header. If m == 0, then we make a copy 92 * of the tcpiphdr at ti and send directly to the addressed host. 93 * This is used to force keep alive messages out using the TCP 94 * template for a connection tp->t_template. If flags are given 95 * then we send a message back to the TCP which originated the 96 * segment ti, and discard the mbuf containing it and any other 97 * attached mbufs. 98 * 99 * In any case the ack and sequence number of the transmitted 100 * segment are as specified by the parameters. 101 */ 102 void 103 tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m, 104 tcp_seq ack, tcp_seq seq, int flags) 105 { 106 register int tlen; 107 int win = 0; 108 109 DEBUG_CALL("tcp_respond"); 110 DEBUG_ARG("tp = %lx", (long)tp); 111 DEBUG_ARG("ti = %lx", (long)ti); 112 DEBUG_ARG("m = %lx", (long)m); 113 DEBUG_ARG("ack = %u", ack); 114 DEBUG_ARG("seq = %u", seq); 115 DEBUG_ARG("flags = %x", flags); 116 117 if (tp) 118 win = sbspace(&tp->t_socket->so_rcv); 119 if (m == NULL) { 120 if ((m = m_get()) == NULL) 121 return; 122 #ifdef TCP_COMPAT_42 123 tlen = 1; 124 #else 125 tlen = 0; 126 #endif 127 m->m_data += IF_MAXLINKHDR; 128 *mtod(m, struct tcpiphdr *) = *ti; 129 ti = mtod(m, struct tcpiphdr *); 130 flags = TH_ACK; 131 } else { 132 /* 133 * ti points into m so the next line is just making 134 * the mbuf point to ti 135 */ 136 m->m_data = (caddr_t)ti; 137 138 m->m_len = sizeof (struct tcpiphdr); 139 tlen = 0; 140 #define xchg(a,b,type) { type t; t=a; a=b; b=t; } 141 xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_int32_t); 142 xchg(ti->ti_dport, ti->ti_sport, u_int16_t); 143 #undef xchg 144 } 145 ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen)); 146 tlen += sizeof (struct tcpiphdr); 147 m->m_len = tlen; 148 149 ti->ti_mbuf = NULL; 150 ti->ti_x1 = 0; 151 ti->ti_seq = htonl(seq); 152 ti->ti_ack = htonl(ack); 153 ti->ti_x2 = 0; 154 ti->ti_off = sizeof (struct tcphdr) >> 2; 155 ti->ti_flags = flags; 156 if (tp) 157 ti->ti_win = htons((u_int16_t) (win >> tp->rcv_scale)); 158 else 159 ti->ti_win = htons((u_int16_t)win); 160 ti->ti_urp = 0; 161 ti->ti_sum = 0; 162 ti->ti_sum = cksum(m, tlen); 163 ((struct ip *)ti)->ip_len = tlen; 164 165 if(flags & TH_RST) 166 ((struct ip *)ti)->ip_ttl = MAXTTL; 167 else 168 ((struct ip *)ti)->ip_ttl = IPDEFTTL; 169 170 (void) ip_output((struct socket *)0, m); 171 } 172 173 /* 174 * Create a new TCP control block, making an 175 * empty reassembly queue and hooking it to the argument 176 * protocol control block. 177 */ 178 struct tcpcb * 179 tcp_newtcpcb(struct socket *so) 180 { 181 register struct tcpcb *tp; 182 183 tp = (struct tcpcb *)malloc(sizeof(*tp)); 184 if (tp == NULL) 185 return ((struct tcpcb *)0); 186 187 memset((char *) tp, 0, sizeof(struct tcpcb)); 188 tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp; 189 tp->t_maxseg = TCP_MSS; 190 191 tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; 192 tp->t_socket = so; 193 194 /* 195 * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no 196 * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives 197 * reasonable initial retransmit time. 198 */ 199 tp->t_srtt = TCPTV_SRTTBASE; 200 tp->t_rttvar = TCPTV_SRTTDFLT << 2; 201 tp->t_rttmin = TCPTV_MIN; 202 203 TCPT_RANGESET(tp->t_rxtcur, 204 ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1, 205 TCPTV_MIN, TCPTV_REXMTMAX); 206 207 tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; 208 tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; 209 tp->t_state = TCPS_CLOSED; 210 211 so->so_tcpcb = tp; 212 213 return (tp); 214 } 215 216 /* 217 * Drop a TCP connection, reporting 218 * the specified error. If connection is synchronized, 219 * then send a RST to peer. 220 */ 221 struct tcpcb *tcp_drop(struct tcpcb *tp, int err) 222 { 223 /* tcp_drop(tp, errno) 224 register struct tcpcb *tp; 225 int errno; 226 { 227 */ 228 229 DEBUG_CALL("tcp_drop"); 230 DEBUG_ARG("tp = %lx", (long)tp); 231 DEBUG_ARG("errno = %d", errno); 232 233 if (TCPS_HAVERCVDSYN(tp->t_state)) { 234 tp->t_state = TCPS_CLOSED; 235 (void) tcp_output(tp); 236 STAT(tcpstat.tcps_drops++); 237 } else 238 STAT(tcpstat.tcps_conndrops++); 239 /* if (errno == ETIMEDOUT && tp->t_softerror) 240 * errno = tp->t_softerror; 241 */ 242 /* so->so_error = errno; */ 243 return (tcp_close(tp)); 244 } 245 246 /* 247 * Close a TCP control block: 248 * discard all space held by the tcp 249 * discard internet protocol block 250 * wake up any sleepers 251 */ 252 struct tcpcb * 253 tcp_close(struct tcpcb *tp) 254 { 255 register struct tcpiphdr *t; 256 struct socket *so = tp->t_socket; 257 register struct mbuf *m; 258 259 DEBUG_CALL("tcp_close"); 260 DEBUG_ARG("tp = %lx", (long )tp); 261 262 /* free the reassembly queue, if any */ 263 t = tcpfrag_list_first(tp); 264 while (!tcpfrag_list_end(t, tp)) { 265 t = tcpiphdr_next(t); 266 m = tcpiphdr_prev(t)->ti_mbuf; 267 remque(tcpiphdr2qlink(tcpiphdr_prev(t))); 268 m_freem(m); 269 } 270 /* It's static */ 271 /* if (tp->t_template) 272 * (void) m_free(dtom(tp->t_template)); 273 */ 274 /* free(tp, M_PCB); */ 275 free(tp); 276 so->so_tcpcb = NULL; 277 soisfdisconnected(so); 278 /* clobber input socket cache if we're closing the cached connection */ 279 if (so == tcp_last_so) 280 tcp_last_so = &tcb; 281 closesocket(so->s); 282 sbfree(&so->so_rcv); 283 sbfree(&so->so_snd); 284 sofree(so); 285 STAT(tcpstat.tcps_closed++); 286 return ((struct tcpcb *)0); 287 } 288 289 #ifdef notdef 290 void 291 tcp_drain() 292 { 293 /* XXX */ 294 } 295 296 /* 297 * When a source quench is received, close congestion window 298 * to one segment. We will gradually open it again as we proceed. 299 */ 300 void 301 tcp_quench(i, errno) 302 303 int errno; 304 { 305 struct tcpcb *tp = intotcpcb(inp); 306 307 if (tp) 308 tp->snd_cwnd = tp->t_maxseg; 309 } 310 311 #endif /* notdef */ 312 313 /* 314 * TCP protocol interface to socket abstraction. 315 */ 316 317 /* 318 * User issued close, and wish to trail through shutdown states: 319 * if never received SYN, just forget it. If got a SYN from peer, 320 * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. 321 * If already got a FIN from peer, then almost done; go to LAST_ACK 322 * state. In all other cases, have already sent FIN to peer (e.g. 323 * after PRU_SHUTDOWN), and just have to play tedious game waiting 324 * for peer to send FIN or not respond to keep-alives, etc. 325 * We can let the user exit from the close as soon as the FIN is acked. 326 */ 327 void 328 tcp_sockclosed(struct tcpcb *tp) 329 { 330 331 DEBUG_CALL("tcp_sockclosed"); 332 DEBUG_ARG("tp = %lx", (long)tp); 333 334 switch (tp->t_state) { 335 336 case TCPS_CLOSED: 337 case TCPS_LISTEN: 338 case TCPS_SYN_SENT: 339 tp->t_state = TCPS_CLOSED; 340 tp = tcp_close(tp); 341 break; 342 343 case TCPS_SYN_RECEIVED: 344 case TCPS_ESTABLISHED: 345 tp->t_state = TCPS_FIN_WAIT_1; 346 break; 347 348 case TCPS_CLOSE_WAIT: 349 tp->t_state = TCPS_LAST_ACK; 350 break; 351 } 352 /* soisfdisconnecting(tp->t_socket); */ 353 if (tp && tp->t_state >= TCPS_FIN_WAIT_2) 354 soisfdisconnected(tp->t_socket); 355 if (tp) 356 tcp_output(tp); 357 } 358 359 /* 360 * Connect to a host on the Internet 361 * Called by tcp_input 362 * Only do a connect, the tcp fields will be set in tcp_input 363 * return 0 if there's a result of the connect, 364 * else return -1 means we're still connecting 365 * The return value is almost always -1 since the socket is 366 * nonblocking. Connect returns after the SYN is sent, and does 367 * not wait for ACK+SYN. 368 */ 369 int tcp_fconnect(struct socket *so) 370 { 371 int ret=0; 372 373 DEBUG_CALL("tcp_fconnect"); 374 DEBUG_ARG("so = %lx", (long )so); 375 376 if( (ret=so->s=socket(AF_INET,SOCK_STREAM,0)) >= 0) { 377 int opt, s=so->s; 378 struct sockaddr_in addr; 379 380 fd_nonblock(s); 381 opt = 1; 382 setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(opt )); 383 opt = 1; 384 setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt )); 385 386 addr.sin_family = AF_INET; 387 if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { 388 /* It's an alias */ 389 switch(ntohl(so->so_faddr.s_addr) & 0xff) { 390 case CTL_DNS: 391 addr.sin_addr = dns_addr; 392 break; 393 case CTL_ALIAS: 394 default: 395 addr.sin_addr = loopback_addr; 396 break; 397 } 398 } else 399 addr.sin_addr = so->so_faddr; 400 addr.sin_port = so->so_fport; 401 402 DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, " 403 "addr.sin_addr.s_addr=%.16s\n", 404 ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); 405 /* We don't care what port we get */ 406 ret = connect(s,(struct sockaddr *)&addr,sizeof (addr)); 407 408 /* 409 * If it's not in progress, it failed, so we just return 0, 410 * without clearing SS_NOFDREF 411 */ 412 soisfconnecting(so); 413 } 414 415 return(ret); 416 } 417 418 /* 419 * Accept the socket and connect to the local-host 420 * 421 * We have a problem. The correct thing to do would be 422 * to first connect to the local-host, and only if the 423 * connection is accepted, then do an accept() here. 424 * But, a) we need to know who's trying to connect 425 * to the socket to be able to SYN the local-host, and 426 * b) we are already connected to the foreign host by 427 * the time it gets to accept(), so... We simply accept 428 * here and SYN the local-host. 429 */ 430 void 431 tcp_connect(struct socket *inso) 432 { 433 struct socket *so; 434 struct sockaddr_in addr; 435 socklen_t addrlen = sizeof(struct sockaddr_in); 436 struct tcpcb *tp; 437 int s, opt; 438 439 DEBUG_CALL("tcp_connect"); 440 DEBUG_ARG("inso = %lx", (long)inso); 441 442 /* 443 * If it's an SS_ACCEPTONCE socket, no need to socreate() 444 * another socket, just use the accept() socket. 445 */ 446 if (inso->so_state & SS_FACCEPTONCE) { 447 /* FACCEPTONCE already have a tcpcb */ 448 so = inso; 449 } else { 450 if ((so = socreate()) == NULL) { 451 /* If it failed, get rid of the pending connection */ 452 closesocket(accept(inso->s,(struct sockaddr *)&addr,&addrlen)); 453 return; 454 } 455 if (tcp_attach(so) < 0) { 456 free(so); /* NOT sofree */ 457 return; 458 } 459 so->so_laddr = inso->so_laddr; 460 so->so_lport = inso->so_lport; 461 } 462 463 (void) tcp_mss(sototcpcb(so), 0); 464 465 if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) { 466 tcp_close(sototcpcb(so)); /* This will sofree() as well */ 467 return; 468 } 469 fd_nonblock(s); 470 opt = 1; 471 setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); 472 opt = 1; 473 setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); 474 opt = 1; 475 setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int)); 476 477 so->so_fport = addr.sin_port; 478 so->so_faddr = addr.sin_addr; 479 /* Translate connections from localhost to the real hostname */ 480 if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) 481 so->so_faddr = alias_addr; 482 483 /* Close the accept() socket, set right state */ 484 if (inso->so_state & SS_FACCEPTONCE) { 485 closesocket(so->s); /* If we only accept once, close the accept() socket */ 486 so->so_state = SS_NOFDREF; /* Don't select it yet, even though we have an FD */ 487 /* if it's not FACCEPTONCE, it's already NOFDREF */ 488 } 489 so->s = s; 490 491 so->so_iptos = tcp_tos(so); 492 tp = sototcpcb(so); 493 494 tcp_template(tp); 495 496 /* Compute window scaling to request. */ 497 /* while (tp->request_r_scale < TCP_MAX_WINSHIFT && 498 * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) 499 * tp->request_r_scale++; 500 */ 501 502 /* soisconnecting(so); */ /* NOFDREF used instead */ 503 STAT(tcpstat.tcps_connattempt++); 504 505 tp->t_state = TCPS_SYN_SENT; 506 tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; 507 tp->iss = tcp_iss; 508 tcp_iss += TCP_ISSINCR/2; 509 tcp_sendseqinit(tp); 510 tcp_output(tp); 511 } 512 513 /* 514 * Attach a TCPCB to a socket. 515 */ 516 int 517 tcp_attach(struct socket *so) 518 { 519 if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) 520 return -1; 521 522 insque(so, &tcb); 523 524 return 0; 525 } 526 527 /* 528 * Set the socket's type of service field 529 */ 530 static const struct tos_t tcptos[] = { 531 {0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */ 532 {21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */ 533 {0, 23, IPTOS_LOWDELAY, 0}, /* telnet */ 534 {0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */ 535 {0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT}, /* rlogin */ 536 {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT}, /* shell */ 537 {0, 544, IPTOS_LOWDELAY, EMU_KSH}, /* kshell */ 538 {0, 543, IPTOS_LOWDELAY, 0}, /* klogin */ 539 {0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */ 540 {0, 6668, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC undernet */ 541 {0, 7070, IPTOS_LOWDELAY, EMU_REALAUDIO }, /* RealAudio control */ 542 {0, 113, IPTOS_LOWDELAY, EMU_IDENT }, /* identd protocol */ 543 {0, 0, 0, 0} 544 }; 545 546 #ifdef CONFIG_QEMU 547 static 548 #endif 549 struct emu_t *tcpemu = NULL; 550 551 /* 552 * Return TOS according to the above table 553 */ 554 u_int8_t 555 tcp_tos(struct socket *so) 556 { 557 int i = 0; 558 struct emu_t *emup; 559 560 while(tcptos[i].tos) { 561 if ((tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) || 562 (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) { 563 so->so_emu = tcptos[i].emu; 564 return tcptos[i].tos; 565 } 566 i++; 567 } 568 569 /* Nope, lets see if there's a user-added one */ 570 for (emup = tcpemu; emup; emup = emup->next) { 571 if ((emup->fport && (ntohs(so->so_fport) == emup->fport)) || 572 (emup->lport && (ntohs(so->so_lport) == emup->lport))) { 573 so->so_emu = emup->emu; 574 return emup->tos; 575 } 576 } 577 578 return 0; 579 } 580 581 #if 0 582 int do_echo = -1; 583 #endif 584 585 /* 586 * Emulate programs that try and connect to us 587 * This includes ftp (the data connection is 588 * initiated by the server) and IRC (DCC CHAT and 589 * DCC SEND) for now 590 * 591 * NOTE: It's possible to crash SLiRP by sending it 592 * unstandard strings to emulate... if this is a problem, 593 * more checks are needed here 594 * 595 * XXX Assumes the whole command came in one packet 596 * 597 * XXX Some ftp clients will have their TOS set to 598 * LOWDELAY and so Nagel will kick in. Because of this, 599 * we'll get the first letter, followed by the rest, so 600 * we simply scan for ORT instead of PORT... 601 * DCC doesn't have this problem because there's other stuff 602 * in the packet before the DCC command. 603 * 604 * Return 1 if the mbuf m is still valid and should be 605 * sbappend()ed 606 * 607 * NOTE: if you return 0 you MUST m_free() the mbuf! 608 */ 609 int 610 tcp_emu(struct socket *so, struct mbuf *m) 611 { 612 u_int n1, n2, n3, n4, n5, n6; 613 char buff[257]; 614 u_int32_t laddr; 615 u_int lport; 616 char *bptr; 617 618 DEBUG_CALL("tcp_emu"); 619 DEBUG_ARG("so = %lx", (long)so); 620 DEBUG_ARG("m = %lx", (long)m); 621 622 switch(so->so_emu) { 623 int x, i; 624 625 case EMU_IDENT: 626 /* 627 * Identification protocol as per rfc-1413 628 */ 629 630 { 631 struct socket *tmpso; 632 struct sockaddr_in addr; 633 socklen_t addrlen = sizeof(struct sockaddr_in); 634 struct sbuf *so_rcv = &so->so_rcv; 635 636 memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); 637 so_rcv->sb_wptr += m->m_len; 638 so_rcv->sb_rptr += m->m_len; 639 m->m_data[m->m_len] = 0; /* NULL terminate */ 640 if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) { 641 if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) { 642 HTONS(n1); 643 HTONS(n2); 644 /* n2 is the one on our host */ 645 for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { 646 if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr && 647 tmpso->so_lport == n2 && 648 tmpso->so_faddr.s_addr == so->so_faddr.s_addr && 649 tmpso->so_fport == n1) { 650 if (getsockname(tmpso->s, 651 (struct sockaddr *)&addr, &addrlen) == 0) 652 n2 = ntohs(addr.sin_port); 653 break; 654 } 655 } 656 } 657 so_rcv->sb_cc = snprintf(so_rcv->sb_data, 658 so_rcv->sb_datalen, 659 "%d,%d\r\n", n1, n2); 660 so_rcv->sb_rptr = so_rcv->sb_data; 661 so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; 662 } 663 m_free(m); 664 return 0; 665 } 666 667 #if 0 668 case EMU_RLOGIN: 669 /* 670 * Rlogin emulation 671 * First we accumulate all the initial option negotiation, 672 * then fork_exec() rlogin according to the options 673 */ 674 { 675 int i, i2, n; 676 char *ptr; 677 char args[100]; 678 char term[100]; 679 struct sbuf *so_snd = &so->so_snd; 680 struct sbuf *so_rcv = &so->so_rcv; 681 682 /* First check if they have a priveladged port, or too much data has arrived */ 683 if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 || 684 (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) { 685 memcpy(so_snd->sb_wptr, "Permission denied\n", 18); 686 so_snd->sb_wptr += 18; 687 so_snd->sb_cc += 18; 688 tcp_sockclosed(sototcpcb(so)); 689 m_free(m); 690 return 0; 691 } 692 693 /* Append the current data */ 694 memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); 695 so_rcv->sb_wptr += m->m_len; 696 so_rcv->sb_rptr += m->m_len; 697 m_free(m); 698 699 /* 700 * Check if we have all the initial options, 701 * and build argument list to rlogin while we're here 702 */ 703 n = 0; 704 ptr = so_rcv->sb_data; 705 args[0] = 0; 706 term[0] = 0; 707 while (ptr < so_rcv->sb_wptr) { 708 if (*ptr++ == 0) { 709 n++; 710 if (n == 2) { 711 sprintf(args, "rlogin -l %s %s", 712 ptr, inet_ntoa(so->so_faddr)); 713 } else if (n == 3) { 714 i2 = so_rcv->sb_wptr - ptr; 715 for (i = 0; i < i2; i++) { 716 if (ptr[i] == '/') { 717 ptr[i] = 0; 718 #ifdef HAVE_SETENV 719 sprintf(term, "%s", ptr); 720 #else 721 sprintf(term, "TERM=%s", ptr); 722 #endif 723 ptr[i] = '/'; 724 break; 725 } 726 } 727 } 728 } 729 } 730 731 if (n != 4) 732 return 0; 733 734 /* We have it, set our term variable and fork_exec() */ 735 #ifdef HAVE_SETENV 736 setenv("TERM", term, 1); 737 #else 738 putenv(term); 739 #endif 740 fork_exec(so, args, 2); 741 term[0] = 0; 742 so->so_emu = 0; 743 744 /* And finally, send the client a 0 character */ 745 so_snd->sb_wptr[0] = 0; 746 so_snd->sb_wptr++; 747 so_snd->sb_cc++; 748 749 return 0; 750 } 751 752 case EMU_RSH: 753 /* 754 * rsh emulation 755 * First we accumulate all the initial option negotiation, 756 * then rsh_exec() rsh according to the options 757 */ 758 { 759 int n; 760 char *ptr; 761 char *user; 762 char *args; 763 struct sbuf *so_snd = &so->so_snd; 764 struct sbuf *so_rcv = &so->so_rcv; 765 766 /* First check if they have a priveladged port, or too much data has arrived */ 767 if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 || 768 (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) { 769 memcpy(so_snd->sb_wptr, "Permission denied\n", 18); 770 so_snd->sb_wptr += 18; 771 so_snd->sb_cc += 18; 772 tcp_sockclosed(sototcpcb(so)); 773 m_free(m); 774 return 0; 775 } 776 777 /* Append the current data */ 778 memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); 779 so_rcv->sb_wptr += m->m_len; 780 so_rcv->sb_rptr += m->m_len; 781 m_free(m); 782 783 /* 784 * Check if we have all the initial options, 785 * and build argument list to rlogin while we're here 786 */ 787 n = 0; 788 ptr = so_rcv->sb_data; 789 user=""; 790 args=""; 791 if (so->extra==NULL) { 792 struct socket *ns; 793 struct tcpcb* tp; 794 int port=atoi(ptr); 795 if (port <= 0) return 0; 796 if (port > 1023 || port < 512) { 797 memcpy(so_snd->sb_wptr, "Permission denied\n", 18); 798 so_snd->sb_wptr += 18; 799 so_snd->sb_cc += 18; 800 tcp_sockclosed(sototcpcb(so)); 801 return 0; 802 } 803 if ((ns=socreate()) == NULL) 804 return 0; 805 if (tcp_attach(ns)<0) { 806 free(ns); 807 return 0; 808 } 809 810 ns->so_laddr=so->so_laddr; 811 ns->so_lport=htons(port); 812 813 (void) tcp_mss(sototcpcb(ns), 0); 814 815 ns->so_faddr=so->so_faddr; 816 ns->so_fport=htons(IPPORT_RESERVED-1); /* Use a fake port. */ 817 818 if (ns->so_faddr.s_addr == 0 || 819 ns->so_faddr.s_addr == loopback_addr.s_addr) 820 ns->so_faddr = alias_addr; 821 822 ns->so_iptos = tcp_tos(ns); 823 tp = sototcpcb(ns); 824 825 tcp_template(tp); 826 827 /* Compute window scaling to request. */ 828 /* while (tp->request_r_scale < TCP_MAX_WINSHIFT && 829 * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) 830 * tp->request_r_scale++; 831 */ 832 833 /*soisfconnecting(ns);*/ 834 835 STAT(tcpstat.tcps_connattempt++); 836 837 tp->t_state = TCPS_SYN_SENT; 838 tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; 839 tp->iss = tcp_iss; 840 tcp_iss += TCP_ISSINCR/2; 841 tcp_sendseqinit(tp); 842 tcp_output(tp); 843 so->extra=ns; 844 } 845 while (ptr < so_rcv->sb_wptr) { 846 if (*ptr++ == 0) { 847 n++; 848 if (n == 2) { 849 user=ptr; 850 } else if (n == 3) { 851 args=ptr; 852 } 853 } 854 } 855 856 if (n != 4) 857 return 0; 858 859 rsh_exec(so,so->extra, user, inet_ntoa(so->so_faddr), args); 860 so->so_emu = 0; 861 so->extra=NULL; 862 863 /* And finally, send the client a 0 character */ 864 so_snd->sb_wptr[0] = 0; 865 so_snd->sb_wptr++; 866 so_snd->sb_cc++; 867 868 return 0; 869 } 870 871 case EMU_CTL: 872 { 873 int num; 874 struct sbuf *so_snd = &so->so_snd; 875 struct sbuf *so_rcv = &so->so_rcv; 876 877 /* 878 * If there is binary data here, we save it in so->so_m 879 */ 880 if (!so->so_m) { 881 int rxlen; 882 char *rxdata; 883 rxdata=mtod(m, char *); 884 for (rxlen=m->m_len; rxlen; rxlen--) { 885 if (*rxdata++ & 0x80) { 886 so->so_m = m; 887 return 0; 888 } 889 } 890 } /* if(so->so_m==NULL) */ 891 892 /* 893 * Append the line 894 */ 895 sbappendsb(so_rcv, m); 896 897 /* To avoid going over the edge of the buffer, we reset it */ 898 if (so_snd->sb_cc == 0) 899 so_snd->sb_wptr = so_snd->sb_rptr = so_snd->sb_data; 900 901 /* 902 * A bit of a hack: 903 * If the first packet we get here is 1 byte long, then it 904 * was done in telnet character mode, therefore we must echo 905 * the characters as they come. Otherwise, we echo nothing, 906 * because in linemode, the line is already echoed 907 * XXX two or more control connections won't work 908 */ 909 if (do_echo == -1) { 910 if (m->m_len == 1) do_echo = 1; 911 else do_echo = 0; 912 } 913 if (do_echo) { 914 sbappendsb(so_snd, m); 915 m_free(m); 916 tcp_output(sototcpcb(so)); /* XXX */ 917 } else 918 m_free(m); 919 920 num = 0; 921 while (num < so->so_rcv.sb_cc) { 922 if (*(so->so_rcv.sb_rptr + num) == '\n' || 923 *(so->so_rcv.sb_rptr + num) == '\r') { 924 int n; 925 926 *(so_rcv->sb_rptr + num) = 0; 927 if (ctl_password && !ctl_password_ok) { 928 /* Need a password */ 929 if (sscanf(so_rcv->sb_rptr, "pass %256s", buff) == 1) { 930 if (strcmp(buff, ctl_password) == 0) { 931 ctl_password_ok = 1; 932 n = sprintf(so_snd->sb_wptr, 933 "Password OK.\r\n"); 934 goto do_prompt; 935 } 936 } 937 n = sprintf(so_snd->sb_wptr, 938 "Error: Password required, log on with \"pass PASSWORD\"\r\n"); 939 goto do_prompt; 940 } 941 cfg_quitting = 0; 942 n = do_config(so_rcv->sb_rptr, so, PRN_SPRINTF); 943 if (!cfg_quitting) { 944 /* Register the printed data */ 945 do_prompt: 946 so_snd->sb_cc += n; 947 so_snd->sb_wptr += n; 948 /* Add prompt */ 949 n = sprintf(so_snd->sb_wptr, "Slirp> "); 950 so_snd->sb_cc += n; 951 so_snd->sb_wptr += n; 952 } 953 /* Drop so_rcv data */ 954 so_rcv->sb_cc = 0; 955 so_rcv->sb_wptr = so_rcv->sb_rptr = so_rcv->sb_data; 956 tcp_output(sototcpcb(so)); /* Send the reply */ 957 } 958 num++; 959 } 960 return 0; 961 } 962 #endif 963 case EMU_FTP: /* ftp */ 964 *(m->m_data+m->m_len) = 0; /* NUL terminate for strstr */ 965 if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) { 966 /* 967 * Need to emulate the PORT command 968 */ 969 x = sscanf(bptr, "ORT %u,%u,%u,%u,%u,%u\r\n%256[^\177]", 970 &n1, &n2, &n3, &n4, &n5, &n6, buff); 971 if (x < 6) 972 return 1; 973 974 laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); 975 lport = htons((n5 << 8) | (n6)); 976 977 if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 978 return 1; 979 980 n6 = ntohs(so->so_fport); 981 982 n5 = (n6 >> 8) & 0xff; 983 n6 &= 0xff; 984 985 laddr = ntohl(so->so_faddr.s_addr); 986 987 n1 = ((laddr >> 24) & 0xff); 988 n2 = ((laddr >> 16) & 0xff); 989 n3 = ((laddr >> 8) & 0xff); 990 n4 = (laddr & 0xff); 991 992 m->m_len = bptr - m->m_data; /* Adjust length */ 993 m->m_len += snprintf(bptr, m->m_hdr.mh_size - m->m_len, 994 "ORT %d,%d,%d,%d,%d,%d\r\n%s", 995 n1, n2, n3, n4, n5, n6, x==7?buff:""); 996 return 1; 997 } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { 998 /* 999 * Need to emulate the PASV response 1000 */ 1001 x = sscanf(bptr, "27 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n%256[^\177]", 1002 &n1, &n2, &n3, &n4, &n5, &n6, buff); 1003 if (x < 6) 1004 return 1; 1005 1006 laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); 1007 lport = htons((n5 << 8) | (n6)); 1008 1009 if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 1010 return 1; 1011 1012 n6 = ntohs(so->so_fport); 1013 1014 n5 = (n6 >> 8) & 0xff; 1015 n6 &= 0xff; 1016 1017 laddr = ntohl(so->so_faddr.s_addr); 1018 1019 n1 = ((laddr >> 24) & 0xff); 1020 n2 = ((laddr >> 16) & 0xff); 1021 n3 = ((laddr >> 8) & 0xff); 1022 n4 = (laddr & 0xff); 1023 1024 m->m_len = bptr - m->m_data; /* Adjust length */ 1025 m->m_len += snprintf(bptr, m->m_hdr.mh_size - m->m_len, 1026 "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", 1027 n1, n2, n3, n4, n5, n6, x==7?buff:""); 1028 1029 return 1; 1030 } 1031 1032 return 1; 1033 1034 case EMU_KSH: 1035 /* 1036 * The kshell (Kerberos rsh) and shell services both pass 1037 * a local port port number to carry signals to the server 1038 * and stderr to the client. It is passed at the beginning 1039 * of the connection as a NUL-terminated decimal ASCII string. 1040 */ 1041 so->so_emu = 0; 1042 for (lport = 0, i = 0; i < m->m_len-1; ++i) { 1043 if (m->m_data[i] < '0' || m->m_data[i] > '9') 1044 return 1; /* invalid number */ 1045 lport *= 10; 1046 lport += m->m_data[i] - '0'; 1047 } 1048 if (m->m_data[m->m_len-1] == '\0' && lport != 0 && 1049 (so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL) 1050 m->m_len = snprintf(m->m_data, m->m_hdr.mh_size, "%d", 1051 ntohs(so->so_fport)) + 1; 1052 return 1; 1053 1054 case EMU_IRC: 1055 /* 1056 * Need to emulate DCC CHAT, DCC SEND and DCC MOVE 1057 */ 1058 *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */ 1059 if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL) 1060 return 1; 1061 1062 /* The %256s is for the broken mIRC */ 1063 if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) { 1064 if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) 1065 return 1; 1066 1067 m->m_len = bptr - m->m_data; /* Adjust length */ 1068 m->m_len += snprintf(bptr, m->m_hdr.mh_size, 1069 "DCC CHAT chat %lu %u%c\n", 1070 (unsigned long)ntohl(so->so_faddr.s_addr), 1071 ntohs(so->so_fport), 1); 1072 } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { 1073 if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) 1074 return 1; 1075 1076 m->m_len = bptr - m->m_data; /* Adjust length */ 1077 m->m_len += snprintf(bptr, m->m_hdr.mh_size, 1078 "DCC SEND %s %lu %u %u%c\n", buff, 1079 (unsigned long)ntohl(so->so_faddr.s_addr), 1080 ntohs(so->so_fport), n1, 1); 1081 } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { 1082 if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) 1083 return 1; 1084 1085 m->m_len = bptr - m->m_data; /* Adjust length */ 1086 m->m_len += snprintf(bptr, m->m_hdr.mh_size, 1087 "DCC MOVE %s %lu %u %u%c\n", buff, 1088 (unsigned long)ntohl(so->so_faddr.s_addr), 1089 ntohs(so->so_fport), n1, 1); 1090 } 1091 return 1; 1092 1093 case EMU_REALAUDIO: 1094 /* 1095 * RealAudio emulation - JP. We must try to parse the incoming 1096 * data and try to find the two characters that contain the 1097 * port number. Then we redirect an udp port and replace the 1098 * number with the real port we got. 1099 * 1100 * The 1.0 beta versions of the player are not supported 1101 * any more. 1102 * 1103 * A typical packet for player version 1.0 (release version): 1104 * 1105 * 0000:50 4E 41 00 05 1106 * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .......glc..P 1107 * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH 1108 * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v 1109 * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB 1110 * 1111 * Now the port number 0x1BD7 is found at offset 0x04 of the 1112 * Now the port number 0x1BD7 is found at offset 0x04 of the 1113 * second packet. This time we received five bytes first and 1114 * then the rest. You never know how many bytes you get. 1115 * 1116 * A typical packet for player version 2.0 (beta): 1117 * 1118 * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA............ 1119 * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxc..Win2.0.0 1120 * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ 1121 * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas 1122 * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B 1123 * 1124 * Port number 0x1BC1 is found at offset 0x0d. 1125 * 1126 * This is just a horrible switch statement. Variable ra tells 1127 * us where we're going. 1128 */ 1129 1130 bptr = m->m_data; 1131 while (bptr < m->m_data + m->m_len) { 1132 u_short p; 1133 static int ra = 0; 1134 char ra_tbl[4]; 1135 1136 ra_tbl[0] = 0x50; 1137 ra_tbl[1] = 0x4e; 1138 ra_tbl[2] = 0x41; 1139 ra_tbl[3] = 0; 1140 1141 switch (ra) { 1142 case 0: 1143 case 2: 1144 case 3: 1145 if (*bptr++ != ra_tbl[ra]) { 1146 ra = 0; 1147 continue; 1148 } 1149 break; 1150 1151 case 1: 1152 /* 1153 * We may get 0x50 several times, ignore them 1154 */ 1155 if (*bptr == 0x50) { 1156 ra = 1; 1157 bptr++; 1158 continue; 1159 } else if (*bptr++ != ra_tbl[ra]) { 1160 ra = 0; 1161 continue; 1162 } 1163 break; 1164 1165 case 4: 1166 /* 1167 * skip version number 1168 */ 1169 bptr++; 1170 break; 1171 1172 case 5: 1173 /* 1174 * The difference between versions 1.0 and 1175 * 2.0 is here. For future versions of 1176 * the player this may need to be modified. 1177 */ 1178 if (*(bptr + 1) == 0x02) 1179 bptr += 8; 1180 else 1181 bptr += 4; 1182 break; 1183 1184 case 6: 1185 /* This is the field containing the port 1186 * number that RA-player is listening to. 1187 */ 1188 lport = (((u_char*)bptr)[0] << 8) 1189 + ((u_char *)bptr)[1]; 1190 if (lport < 6970) 1191 lport += 256; /* don't know why */ 1192 if (lport < 6970 || lport > 7170) 1193 return 1; /* failed */ 1194 1195 /* try to get udp port between 6970 - 7170 */ 1196 for (p = 6970; p < 7071; p++) { 1197 if (udp_listen( htons(p), 1198 so->so_laddr.s_addr, 1199 htons(lport), 1200 SS_FACCEPTONCE)) { 1201 break; 1202 } 1203 } 1204 if (p == 7071) 1205 p = 0; 1206 *(u_char *)bptr++ = (p >> 8) & 0xff; 1207 *(u_char *)bptr++ = p & 0xff; 1208 ra = 0; 1209 return 1; /* port redirected, we're done */ 1210 break; 1211 1212 default: 1213 ra = 0; 1214 } 1215 ra++; 1216 } 1217 return 1; 1218 1219 default: 1220 /* Ooops, not emulated, won't call tcp_emu again */ 1221 so->so_emu = 0; 1222 return 1; 1223 } 1224 } 1225 1226 /* 1227 * Do misc. config of SLiRP while its running. 1228 * Return 0 if this connections is to be closed, 1 otherwise, 1229 * return 2 if this is a command-line connection 1230 */ 1231 int 1232 tcp_ctl(struct socket *so) 1233 { 1234 struct sbuf *sb = &so->so_snd; 1235 int command; 1236 struct ex_list *ex_ptr; 1237 int do_pty; 1238 // struct socket *tmpso; 1239 1240 DEBUG_CALL("tcp_ctl"); 1241 DEBUG_ARG("so = %lx", (long )so); 1242 1243 #if 0 1244 /* 1245 * Check if they're authorised 1246 */ 1247 if (ctl_addr.s_addr && (ctl_addr.s_addr == -1 || (so->so_laddr.s_addr != ctl_addr.s_addr))) { 1248 sb->sb_cc = sprintf(sb->sb_wptr,"Error: Permission denied.\r\n"); 1249 sb->sb_wptr += sb->sb_cc; 1250 return 0; 1251 } 1252 #endif 1253 command = (ntohl(so->so_faddr.s_addr) & 0xff); 1254 1255 switch(command) { 1256 default: /* Check for exec's */ 1257 1258 /* 1259 * Check if it's pty_exec 1260 */ 1261 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { 1262 if (ex_ptr->ex_fport == so->so_fport && 1263 command == ex_ptr->ex_addr) { 1264 if (ex_ptr->ex_pty == 3) { 1265 so->s = -1; 1266 so->extra = (void *)ex_ptr->ex_exec; 1267 return 1; 1268 } 1269 do_pty = ex_ptr->ex_pty; 1270 goto do_exec; 1271 } 1272 } 1273 1274 /* 1275 * Nothing bound.. 1276 */ 1277 /* tcp_fconnect(so); */ 1278 1279 /* FALLTHROUGH */ 1280 case CTL_ALIAS: 1281 sb->sb_cc = snprintf(sb->sb_wptr, sb->sb_datalen - (sb->sb_wptr - sb->sb_data), 1282 "Error: No application configured.\r\n"); 1283 sb->sb_wptr += sb->sb_cc; 1284 return(0); 1285 1286 do_exec: 1287 DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec)); 1288 return(fork_exec(so, ex_ptr->ex_exec, do_pty)); 1289 1290 #if 0 1291 case CTL_CMD: 1292 for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { 1293 if (tmpso->so_emu == EMU_CTL && 1294 !(tmpso->so_tcpcb? 1295 (tmpso->so_tcpcb->t_state & (TCPS_TIME_WAIT|TCPS_LAST_ACK)) 1296 :0)) { 1297 /* Ooops, control connection already active */ 1298 sb->sb_cc = sprintf(sb->sb_wptr,"Sorry, already connected.\r\n"); 1299 sb->sb_wptr += sb->sb_cc; 1300 return 0; 1301 } 1302 } 1303 so->so_emu = EMU_CTL; 1304 ctl_password_ok = 0; 1305 sb->sb_cc = sprintf(sb->sb_wptr, "Slirp command-line ready (type \"help\" for help).\r\nSlirp> "); 1306 sb->sb_wptr += sb->sb_cc; 1307 do_echo=-1; 1308 return(2); 1309 #endif 1310 } 1311 } 1312