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 #define WANT_SYS_IOCTL_H 42 #include <slirp.h> 43 #include "proxy_common.h" 44 45 /* patchable/settable parameters for tcp */ 46 /* Don't do rfc1323 performance enhancements */ 47 #define TCP_DO_RFC1323 0 48 49 /* 50 * Tcp initialization 51 */ 52 void 53 tcp_init(void) 54 { 55 tcp_iss = 1; /* wrong */ 56 tcb.so_next = tcb.so_prev = &tcb; 57 } 58 59 /* 60 * Create template to be used to send tcp packets on a connection. 61 * Call after host entry created, fills 62 * in a skeletal tcp/ip header, minimizing the amount of work 63 * necessary when the connection is used. 64 */ 65 /* struct tcpiphdr * */ 66 void 67 tcp_template(struct tcpcb *tp) 68 { 69 struct socket *so = tp->t_socket; 70 register struct tcpiphdr *n = &tp->t_template; 71 72 n->ti_mbuf = NULL; 73 n->ti_x1 = 0; 74 n->ti_pr = IPPROTO_TCP; 75 n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); 76 n->ti_src = ip_seth(so->so_faddr_ip); 77 n->ti_dst = ip_seth(so->so_laddr_ip); 78 n->ti_sport = port_seth(so->so_faddr_port); 79 n->ti_dport = port_seth(so->so_laddr_port); 80 81 n->ti_seq = 0; 82 n->ti_ack = 0; 83 n->ti_x2 = 0; 84 n->ti_off = 5; 85 n->ti_flags = 0; 86 n->ti_win = 0; 87 n->ti_sum = 0; 88 n->ti_urp = 0; 89 } 90 91 /* 92 * Send a single message to the TCP at address specified by 93 * the given TCP/IP header. If m == 0, then we make a copy 94 * of the tcpiphdr at ti and send directly to the addressed host. 95 * This is used to force keep alive messages out using the TCP 96 * template for a connection tp->t_template. If flags are given 97 * then we send a message back to the TCP which originated the 98 * segment ti, and discard the mbuf containing it and any other 99 * attached mbufs. 100 * 101 * In any case the ack and sequence number of the transmitted 102 * segment are as specified by the parameters. 103 */ 104 void 105 tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m, 106 tcp_seq ack, tcp_seq seq, int flags) 107 { 108 register int tlen; 109 int win = 0; 110 111 DEBUG_CALL("tcp_respond"); 112 DEBUG_ARG("tp = %lx", (long)tp); 113 DEBUG_ARG("ti = %lx", (long)ti); 114 DEBUG_ARG("m = %lx", (long)m); 115 DEBUG_ARG("ack = %u", ack); 116 DEBUG_ARG("seq = %u", seq); 117 DEBUG_ARG("flags = %x", flags); 118 119 if (tp) 120 win = sbspace(&tp->t_socket->so_rcv); 121 if (m == NULL) { 122 if ((m = m_get()) == NULL) 123 return; 124 #ifdef TCP_COMPAT_42 125 tlen = 1; 126 #else 127 tlen = 0; 128 #endif 129 m->m_data += IF_MAXLINKHDR; 130 *mtod(m, struct tcpiphdr *) = *ti; 131 ti = mtod(m, struct tcpiphdr *); 132 flags = TH_ACK; 133 } else { 134 /* 135 * ti points into m so the next line is just making 136 * the mbuf point to ti 137 */ 138 m->m_data = (caddr_t)ti; 139 140 m->m_len = sizeof (struct tcpiphdr); 141 tlen = 0; 142 #define xchg(a,b,type) { type t; t=a; a=b; b=t; } 143 xchg(ti->ti_dst, ti->ti_src, ipaddr_t); 144 xchg(ti->ti_dport, ti->ti_sport, port_t); 145 #undef xchg 146 } 147 ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen)); 148 tlen += sizeof (struct tcpiphdr); 149 m->m_len = tlen; 150 151 ti->ti_mbuf = NULL; 152 ti->ti_x1 = 0; 153 ti->ti_seq = htonl(seq); 154 ti->ti_ack = htonl(ack); 155 ti->ti_x2 = 0; 156 ti->ti_off = sizeof (struct tcphdr) >> 2; 157 ti->ti_flags = flags; 158 if (tp) 159 ti->ti_win = htons((u_int16_t) (win >> tp->rcv_scale)); 160 else 161 ti->ti_win = htons((u_int16_t)win); 162 ti->ti_urp = 0; 163 ti->ti_sum = 0; 164 ti->ti_sum = cksum(m, tlen); 165 ((struct ip *)ti)->ip_len = tlen; 166 167 if(flags & TH_RST) 168 ((struct ip *)ti)->ip_ttl = MAXTTL; 169 else 170 ((struct ip *)ti)->ip_ttl = IPDEFTTL; 171 172 (void) ip_output((struct socket *)0, m); 173 } 174 175 /* 176 * Create a new TCP control block, making an 177 * empty reassembly queue and hooking it to the argument 178 * protocol control block. 179 */ 180 struct tcpcb * 181 tcp_newtcpcb(struct socket *so) 182 { 183 register struct tcpcb *tp; 184 185 tp = (struct tcpcb *)malloc(sizeof(*tp)); 186 if (tp == NULL) 187 return ((struct tcpcb *)0); 188 189 memset((char *) tp, 0, sizeof(struct tcpcb)); 190 tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp; 191 tp->t_maxseg = TCP_MSS; 192 193 tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; 194 tp->t_socket = so; 195 196 /* 197 * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no 198 * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives 199 * reasonable initial retransmit time. 200 */ 201 tp->t_srtt = TCPTV_SRTTBASE; 202 tp->t_rttvar = TCPTV_SRTTDFLT << 2; 203 tp->t_rttmin = TCPTV_MIN; 204 205 TCPT_RANGESET(tp->t_rxtcur, 206 ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1, 207 TCPTV_MIN, TCPTV_REXMTMAX); 208 209 tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; 210 tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; 211 tp->t_state = TCPS_CLOSED; 212 213 so->so_tcpcb = tp; 214 215 return (tp); 216 } 217 218 /* 219 * Drop a TCP connection, reporting 220 * the specified error. If connection is synchronized, 221 * then send a RST to peer. 222 */ 223 struct tcpcb *tcp_drop(struct tcpcb *tp, int err) 224 { 225 /* tcp_drop(tp, errno) 226 register struct tcpcb *tp; 227 int errno; 228 { 229 */ 230 231 DEBUG_CALL("tcp_drop"); 232 DEBUG_ARG("tp = %lx", (long)tp); 233 DEBUG_ARG("errno = %d", errno); 234 235 if (TCPS_HAVERCVDSYN(tp->t_state)) { 236 tp->t_state = TCPS_CLOSED; 237 (void) tcp_output(tp); 238 STAT(tcpstat.tcps_drops++); 239 } else 240 STAT(tcpstat.tcps_conndrops++); 241 /* if (errno == ETIMEDOUT && tp->t_softerror) 242 * errno = tp->t_softerror; 243 */ 244 /* so->so_error = errno; */ 245 return (tcp_close(tp)); 246 } 247 248 /* 249 * Close a TCP control block: 250 * discard all space held by the tcp 251 * discard internet protocol block 252 * wake up any sleepers 253 */ 254 struct tcpcb * 255 tcp_close(struct tcpcb *tp) 256 { 257 register struct tcpiphdr *t; 258 struct socket *so = tp->t_socket; 259 register struct mbuf *m; 260 261 DEBUG_CALL("tcp_close"); 262 DEBUG_ARG("tp = %lx", (long )tp); 263 264 /* free the reassembly queue, if any */ 265 t = tcpfrag_list_first(tp); 266 while (!tcpfrag_list_end(t, tp)) { 267 t = tcpiphdr_next(t); 268 m = tcpiphdr_prev(t)->ti_mbuf; 269 remque(tcpiphdr2qlink(tcpiphdr_prev(t))); 270 m_freem(m); 271 } 272 /* It's static */ 273 /* if (tp->t_template) 274 * (void) m_free(dtom(tp->t_template)); 275 */ 276 /* free(tp, M_PCB); */ 277 free(tp); 278 so->so_tcpcb = NULL; 279 soisfdisconnected(so); 280 /* clobber input socket cache if we're closing the cached connection */ 281 if (so == tcp_last_so) 282 tcp_last_so = &tcb; 283 socket_close(so->s); 284 sbfree(&so->so_rcv); 285 sbfree(&so->so_snd); 286 sofree(so); 287 STAT(tcpstat.tcps_closed++); 288 return ((struct tcpcb *)0); 289 } 290 291 #ifdef notdef 292 void 293 tcp_drain() 294 { 295 /* XXX */ 296 } 297 298 /* 299 * When a source quench is received, close congestion window 300 * to one segment. We will gradually open it again as we proceed. 301 */ 302 void 303 tcp_quench(i, errno) 304 305 int errno; 306 { 307 struct tcpcb *tp = intotcpcb(inp); 308 309 if (tp) 310 tp->snd_cwnd = tp->t_maxseg; 311 } 312 313 #endif /* notdef */ 314 315 /* 316 * TCP protocol interface to socket abstraction. 317 */ 318 319 /* 320 * User issued close, and wish to trail through shutdown states: 321 * if never received SYN, just forget it. If got a SYN from peer, 322 * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. 323 * If already got a FIN from peer, then almost done; go to LAST_ACK 324 * state. In all other cases, have already sent FIN to peer (e.g. 325 * after PRU_SHUTDOWN), and just have to play tedious game waiting 326 * for peer to send FIN or not respond to keep-alives, etc. 327 * We can let the user exit from the close as soon as the FIN is acked. 328 */ 329 void 330 tcp_sockclosed(struct tcpcb *tp) 331 { 332 333 DEBUG_CALL("tcp_sockclosed"); 334 DEBUG_ARG("tp = %lx", (long)tp); 335 336 switch (tp->t_state) { 337 338 case TCPS_CLOSED: 339 case TCPS_LISTEN: 340 case TCPS_SYN_SENT: 341 tp->t_state = TCPS_CLOSED; 342 tp = tcp_close(tp); 343 break; 344 345 case TCPS_SYN_RECEIVED: 346 case TCPS_ESTABLISHED: 347 tp->t_state = TCPS_FIN_WAIT_1; 348 break; 349 350 case TCPS_CLOSE_WAIT: 351 tp->t_state = TCPS_LAST_ACK; 352 break; 353 } 354 /* soisfdisconnecting(tp->t_socket); */ 355 if (tp && tp->t_state >= TCPS_FIN_WAIT_2) 356 soisfdisconnected(tp->t_socket); 357 if (tp) 358 tcp_output(tp); 359 } 360 361 static void 362 tcp_proxy_event( struct socket* so, 363 int s, 364 ProxyEvent event ) 365 { 366 so->so_state &= ~SS_PROXIFIED; 367 368 if (event == PROXY_EVENT_CONNECTED) { 369 so->s = s; 370 so->so_state &= ~(SS_ISFCONNECTING); 371 } 372 else { 373 so->so_state = SS_NOFDREF; 374 } 375 376 /* continue the connect */ 377 tcp_input(NULL, sizeof(struct ip), so); 378 } 379 380 381 /* Tests if an IP address corresponds to a special Qemu service (eg, the DNS 382 * server or the gateway - see ctl.h) and if so, rewrites it with the real 383 * address of the service. 384 */ 385 int is_qemu_special_address(unsigned long dst_addr, unsigned long *redir_addr) 386 { 387 if ((dst_addr & 0xffffff00) == special_addr_ip) { 388 /* It's an alias */ 389 390 int last_byte = dst_addr & 0xff; 391 392 if (CTL_IS_DNS(last_byte)) 393 *redir_addr = dns_addr[last_byte - CTL_DNS]; 394 else 395 *redir_addr = loopback_addr_ip; 396 397 return 1; 398 } 399 return 0; 400 } 401 402 403 /* 404 * Connect to a host on the Internet 405 * Called by tcp_input 406 * Only do a connect, the tcp fields will be set in tcp_input 407 * return 0 if there's a result of the connect, 408 * else return -1 means we're still connecting 409 * The return value is almost always -1 since the socket is 410 * nonblocking. Connect returns after the SYN is sent, and does 411 * not wait for ACK+SYN. 412 */ 413 int tcp_fconnect(struct socket *so) 414 { 415 int ret=0; 416 int try_proxy = 0; 417 SockAddress sockaddr; 418 unsigned long sock_ip; 419 int sock_port; 420 int redirect_happened = 0; /* for logging new src ip/port after connect */ 421 422 DEBUG_CALL("tcp_fconnect"); 423 DEBUG_ARG("so = %lx", (long )so); 424 425 /* when true, a connection that otherwise would be dropped will instead be 426 * redirected to the sink ('-net-forward-tcp2sink') */ 427 int forward_dropped_to_sink = 0; 428 time_t timestamp = time(NULL); 429 430 /*-------------------------------------------------------------*/ 431 /* User mode network stack restrictions */ 432 if (slirp_should_drop(so->so_faddr_ip, so->so_faddr_port, IPPROTO_TCP)) { 433 434 /* If forwarding to sink is enabled, don't actually drop it */ 435 if (slirp_should_forward_dropped_tcp2sink()) { 436 slirp_drop_log( 437 "About to be dropped TCP allowed to sink: " 438 "0x%08lx:0x%04x -> 0x%08lx:0x%04x %ld\n", 439 so->so_laddr_ip, 440 so->so_laddr_port, 441 so->so_faddr_ip, 442 so->so_faddr_port, 443 timestamp 444 ); 445 forward_dropped_to_sink = 1; 446 } 447 else { 448 slirp_drop_log( 449 "Dropped TCP: 0x%08lx:0x%04x -> 0x%08lx:0x%04x %ld\n", 450 so->so_laddr_ip, 451 so->so_laddr_port, 452 so->so_faddr_ip, 453 so->so_faddr_port, 454 timestamp 455 ); 456 //errno = ENETUNREACH; 457 errno = ECONNREFUSED; 458 return -1; 459 } 460 } else { 461 slirp_drop_log( 462 "Allowed TCP: 0x%08lx:0x%04x -> 0x%08lx:0x%04x %ld\n", 463 so->so_laddr_ip, 464 so->so_laddr_port, 465 so->so_faddr_ip, 466 so->so_faddr_port, 467 timestamp 468 ); 469 } 470 /*-------------------------------------------------------------*/ 471 472 if ((ret=so->s=socket_create_inet(SOCKET_STREAM)) >= 0) 473 { 474 int s = so->s; 475 476 socket_set_nonblock(s); 477 socket_set_xreuseaddr(s); 478 socket_set_oobinline(s); 479 480 481 if (forward_dropped_to_sink) { 482 483 /* This connection would normally be dropped, but since forwarding of 484 * dropped connections is enabled, redirect it to the sink */ 485 sock_ip = slirp_get_tcp_sink_ip(); 486 sock_port= slirp_get_tcp_sink_port(); 487 redirect_happened = 1; 488 } 489 else { /* An allowed connection */ 490 491 unsigned long faddr; 492 int fport; 493 494 /* Determine if the connection should be redirected 495 * due to a -net-forward rule */ 496 /* faddr and fport are modified only on success */ 497 if (slirp_should_net_forward(so->so_faddr_ip, so->so_faddr_port, 498 &faddr, &fport)) { 499 redirect_happened = 1; 500 sock_ip = faddr; /* forced dst addr */ 501 sock_port= fport; /* forced dst port */ 502 } 503 /* Determine if this is a connection to a special qemu service, 504 * and change the destination address accordingly. 505 * 'faddr' is modified only on success */ 506 else if (is_qemu_special_address(so->so_faddr_ip, &faddr)) { 507 508 /* We keep the original destination port. If a special service 509 * listens on a different port than the standard, then appropriate 510 * forwarding should be set up using -net-forward, e.g., as it is 511 * the case with Mawler's DNS traffic, which is redirected to the 512 * special DNS port: 513 * -net-forward 0.0.0.0:0.0.0.0:53:127.0.0.1:21737 */ 514 515 sock_ip = faddr; /* real DNS/gateway addr */ 516 sock_port= so->so_faddr_port;/* original dst port */ 517 518 } 519 /* A normal connection - keep the original destination addr/port */ 520 else { 521 522 try_proxy = 1; 523 524 sock_ip = so->so_faddr_ip; /* original dst addr */ 525 sock_port= so->so_faddr_port; /* original dst port */ 526 } 527 } 528 529 DEBUG_MISC((dfd, " connect()ing, addr=%s, proxy=%d\n", 530 sock_address_to_string(&sockaddr), try_proxy)); 531 532 sock_address_init_inet( &sockaddr, sock_ip, sock_port ); 533 534 if (try_proxy) { 535 if (!proxy_manager_add(&sockaddr, SOCKET_STREAM, 536 (ProxyEventFunc) tcp_proxy_event, so)) { 537 soisfconnecting(so); 538 so->s = -1; 539 so->so_state |= SS_PROXIFIED; 540 return 0; 541 } 542 } 543 544 /* We don't care what port we get */ 545 socket_connect(s, &sockaddr); 546 547 if (redirect_happened) { 548 SockAddress local_addr; 549 if (socket_get_address(s, &local_addr)) { 550 fprintf (stderr, 551 "Warning: tcp_fconnect: could not get socket name\n"); 552 } 553 slirp_drop_log( 554 "Redirected TCP: orig 0x%08lx:0x%04x -> 0x%08lx:0x%04x " 555 "new 0x%08lx:0x%04x -> 0x%08lx:0x%04x %ld\n", 556 so->so_laddr_ip, so->so_laddr_port, 557 so->so_faddr_ip, so->so_laddr_port, 558 sock_address_get_ip(&local_addr), 559 sock_address_get_port(&local_addr), 560 sock_ip, sock_port, timestamp 561 ); 562 } 563 564 /* 565 * If it's not in progress, it failed, so we just return 0, 566 * without clearing SS_NOFDREF 567 */ 568 soisfconnecting(so); 569 } 570 571 return(ret); 572 } 573 574 /* 575 * Accept the socket and connect to the local-host 576 * 577 * We have a problem. The correct thing to do would be 578 * to first connect to the local-host, and only if the 579 * connection is accepted, then do an accept() here. 580 * But, a) we need to know who's trying to connect 581 * to the socket to be able to SYN the local-host, and 582 * b) we are already connected to the foreign host by 583 * the time it gets to accept(), so... We simply accept 584 * here and SYN the local-host. 585 */ 586 void 587 tcp_connect(struct socket *inso) 588 { 589 struct socket *so; 590 SockAddress addr; 591 uint32_t addr_ip; 592 struct tcpcb *tp; 593 int s; 594 595 DEBUG_CALL("tcp_connect"); 596 DEBUG_ARG("inso = %lx", (long)inso); 597 598 /* 599 * If it's an SS_ACCEPTONCE socket, no need to socreate() 600 * another socket, just use the accept() socket. 601 */ 602 if (inso->so_state & SS_FACCEPTONCE) { 603 /* FACCEPTONCE already have a tcpcb */ 604 so = inso; 605 } else { 606 if ((so = socreate()) == NULL) { 607 /* If it failed, get rid of the pending connection */ 608 socket_close(socket_accept(inso->s, NULL)); 609 return; 610 } 611 if (tcp_attach(so) < 0) { 612 free(so); /* NOT sofree */ 613 return; 614 } 615 so->so_laddr_ip = inso->so_laddr_ip; 616 so->so_laddr_port = inso->so_laddr_port; 617 } 618 619 (void) tcp_mss(sototcpcb(so), 0); 620 621 if ((s = socket_accept(inso->s, &addr)) < 0) { 622 tcp_close(sototcpcb(so)); /* This will sofree() as well */ 623 return; 624 } 625 socket_set_nonblock(s); 626 socket_set_xreuseaddr(s); 627 socket_set_oobinline(s); 628 socket_set_nodelay(s); 629 630 so->so_faddr_port = sock_address_get_port(&addr); 631 632 addr_ip = sock_address_get_ip(&addr); 633 634 so->so_faddr_ip = addr_ip; 635 /* Translate connections from localhost to the real hostname */ 636 if (addr_ip == 0 || addr_ip == loopback_addr_ip) 637 so->so_faddr_ip = alias_addr_ip; 638 639 /* Close the accept() socket, set right state */ 640 if (inso->so_state & SS_FACCEPTONCE) { 641 socket_close(so->s); /* If we only accept once, close the accept() socket */ 642 so->so_state = SS_NOFDREF; /* Don't select it yet, even though we have an FD */ 643 /* if it's not FACCEPTONCE, it's already NOFDREF */ 644 } 645 so->s = s; 646 647 so->so_iptos = tcp_tos(so); 648 tp = sototcpcb(so); 649 650 tcp_template(tp); 651 652 /* Compute window scaling to request. */ 653 /* while (tp->request_r_scale < TCP_MAX_WINSHIFT && 654 * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) 655 * tp->request_r_scale++; 656 */ 657 658 /* soisconnecting(so); */ /* NOFDREF used instead */ 659 STAT(tcpstat.tcps_connattempt++); 660 661 tp->t_state = TCPS_SYN_SENT; 662 tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; 663 tp->iss = tcp_iss; 664 tcp_iss += TCP_ISSINCR/2; 665 tcp_sendseqinit(tp); 666 tcp_output(tp); 667 } 668 669 /* 670 * Attach a TCPCB to a socket. 671 */ 672 int 673 tcp_attach(struct socket *so) 674 { 675 if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) 676 return -1; 677 678 insque(so, &tcb); 679 680 return 0; 681 } 682 683 /* 684 * Set the socket's type of service field 685 */ 686 static const struct tos_t tcptos[] = { 687 {0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */ 688 {21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */ 689 {0, 23, IPTOS_LOWDELAY, 0}, /* telnet */ 690 {0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */ 691 {0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT}, /* rlogin */ 692 {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT}, /* shell */ 693 {0, 544, IPTOS_LOWDELAY, EMU_KSH}, /* kshell */ 694 {0, 543, IPTOS_LOWDELAY, 0}, /* klogin */ 695 {0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */ 696 {0, 6668, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC undernet */ 697 {0, 7070, IPTOS_LOWDELAY, EMU_REALAUDIO }, /* RealAudio control */ 698 {0, 113, IPTOS_LOWDELAY, EMU_IDENT }, /* identd protocol */ 699 {0, 0, 0, 0} 700 }; 701 702 #ifdef CONFIG_QEMU 703 static 704 #endif 705 struct emu_t *tcpemu = NULL; 706 707 /* 708 * Return TOS according to the above table 709 */ 710 u_int8_t 711 tcp_tos(struct socket *so) 712 { 713 int i = 0; 714 struct emu_t *emup; 715 716 while(tcptos[i].tos) { 717 if ((tcptos[i].fport && so->so_faddr_port == tcptos[i].fport) || 718 (tcptos[i].lport && so->so_laddr_port == tcptos[i].lport)) { 719 so->so_emu = tcptos[i].emu; 720 return tcptos[i].tos; 721 } 722 i++; 723 } 724 725 /* Nope, lets see if there's a user-added one */ 726 for (emup = tcpemu; emup; emup = emup->next) { 727 if ((emup->fport && (so->so_faddr_port == emup->fport)) || 728 (emup->lport && (so->so_laddr_port == emup->lport))) { 729 so->so_emu = emup->emu; 730 return emup->tos; 731 } 732 } 733 return 0; 734 } 735 736 #if 0 737 int do_echo = -1; 738 #endif 739 740 /* 741 * Emulate programs that try and connect to us 742 * This includes ftp (the data connection is 743 * initiated by the server) and IRC (DCC CHAT and 744 * DCC SEND) for now 745 * 746 * NOTE: It's possible to crash SLiRP by sending it 747 * unstandard strings to emulate... if this is a problem, 748 * more checks are needed here 749 * 750 * XXX Assumes the whole command came in one packet 751 * 752 * XXX Some ftp clients will have their TOS set to 753 * LOWDELAY and so Nagel will kick in. Because of this, 754 * we'll get the first letter, followed by the rest, so 755 * we simply scan for ORT instead of PORT... 756 * DCC doesn't have this problem because there's other stuff 757 * in the packet before the DCC command. 758 * 759 * Return 1 if the mbuf m is still valid and should be 760 * sbappend()ed 761 * 762 * NOTE: if you return 0 you MUST m_free() the mbuf! 763 */ 764 int 765 tcp_emu(struct socket *so, struct mbuf *m) 766 { 767 u_int n1, n2, n3, n4, n5, n6; 768 char buff[257]; 769 u_int32_t laddr; 770 u_int lport; 771 char *bptr; 772 773 DEBUG_CALL("tcp_emu"); 774 DEBUG_ARG("so = %lx", (long)so); 775 DEBUG_ARG("m = %lx", (long)m); 776 777 switch(so->so_emu) { 778 int x, i; 779 780 case EMU_IDENT: 781 /* 782 * Identification protocol as per rfc-1413 783 */ 784 785 { 786 struct socket *tmpso; 787 SockAddress addr; 788 struct sbuf *so_rcv = &so->so_rcv; 789 790 memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); 791 so_rcv->sb_wptr += m->m_len; 792 so_rcv->sb_rptr += m->m_len; 793 m->m_data[m->m_len] = 0; /* NULL terminate */ 794 if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) { 795 if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) { 796 /* n2 is the one on our host */ 797 for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { 798 if (tmpso->so_laddr_ip == so->so_laddr_ip && 799 tmpso->so_laddr_port == n2 && 800 tmpso->so_faddr_ip == so->so_faddr_ip && 801 tmpso->so_faddr_port == n1) { 802 if (socket_get_address(tmpso->s, &addr) == 0) 803 n2 = sock_address_get_port(&addr); 804 break; 805 } 806 } 807 } 808 so_rcv->sb_cc = snprintf(so_rcv->sb_data, 809 so_rcv->sb_datalen, 810 "%d,%d\r\n", n1, n2); 811 so_rcv->sb_rptr = so_rcv->sb_data; 812 so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; 813 } 814 m_free(m); 815 return 0; 816 } 817 818 case EMU_FTP: /* ftp */ 819 *(m->m_data+m->m_len) = 0; /* NUL terminate for strstr */ 820 if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) { 821 /* 822 * Need to emulate the PORT command 823 */ 824 x = sscanf(bptr, "ORT %u,%u,%u,%u,%u,%u\r\n%256[^\177]", 825 &n1, &n2, &n3, &n4, &n5, &n6, buff); 826 if (x < 6) 827 return 1; 828 829 laddr = (n1 << 24) | (n2 << 16) | (n3 << 8) | (n4); 830 lport = (n5 << 8) | (n6); 831 832 if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 833 return 1; 834 835 n6 = so->so_faddr_port; 836 837 n5 = (n6 >> 8) & 0xff; 838 n6 &= 0xff; 839 840 laddr = so->so_faddr_ip; 841 842 n1 = ((laddr >> 24) & 0xff); 843 n2 = ((laddr >> 16) & 0xff); 844 n3 = ((laddr >> 8) & 0xff); 845 n4 = (laddr & 0xff); 846 847 m->m_len = bptr - m->m_data; /* Adjust length */ 848 m->m_len += snprintf(bptr, m->m_hdr.mh_size - m->m_len, 849 "ORT %d,%d,%d,%d,%d,%d\r\n%s", 850 n1, n2, n3, n4, n5, n6, x==7?buff:""); 851 return 1; 852 } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { 853 /* 854 * Need to emulate the PASV response 855 */ 856 x = sscanf(bptr, "27 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n%256[^\177]", 857 &n1, &n2, &n3, &n4, &n5, &n6, buff); 858 if (x < 6) 859 return 1; 860 861 laddr = (n1 << 24) | (n2 << 16) | (n3 << 8) | (n4); 862 lport = (n5 << 8) | (n6); 863 864 if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 865 return 1; 866 867 n6 = so->so_faddr_port; 868 869 n5 = (n6 >> 8) & 0xff; 870 n6 &= 0xff; 871 872 laddr = so->so_faddr_ip; 873 874 n1 = ((laddr >> 24) & 0xff); 875 n2 = ((laddr >> 16) & 0xff); 876 n3 = ((laddr >> 8) & 0xff); 877 n4 = (laddr & 0xff); 878 879 m->m_len = bptr - m->m_data; /* Adjust length */ 880 m->m_len += snprintf(bptr, m->m_hdr.mh_size - m->m_len, 881 "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", 882 n1, n2, n3, n4, n5, n6, x==7?buff:""); 883 884 return 1; 885 } 886 887 return 1; 888 889 case EMU_KSH: 890 /* 891 * The kshell (Kerberos rsh) and shell services both pass 892 * a local port port number to carry signals to the server 893 * and stderr to the client. It is passed at the beginning 894 * of the connection as a NUL-terminated decimal ASCII string. 895 */ 896 so->so_emu = 0; 897 for (lport = 0, i = 0; i < m->m_len-1; ++i) { 898 if (m->m_data[i] < '0' || m->m_data[i] > '9') 899 return 1; /* invalid number */ 900 lport *= 10; 901 lport += m->m_data[i] - '0'; 902 } 903 if (m->m_data[m->m_len-1] == '\0' && lport != 0 && 904 (so = solisten(0, so->so_laddr_ip, lport, SS_FACCEPTONCE)) != NULL) 905 m->m_len = snprintf(m->m_data, m->m_hdr.mh_size, "%d", 906 so->so_faddr_port) + 1; 907 return 1; 908 909 case EMU_IRC: 910 /* 911 * Need to emulate DCC CHAT, DCC SEND and DCC MOVE 912 */ 913 *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */ 914 if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL) 915 return 1; 916 917 /* The %256s is for the broken mIRC */ 918 if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) { 919 if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 920 return 1; 921 922 m->m_len = bptr - m->m_data; /* Adjust length */ 923 m->m_len += snprintf(bptr, m->m_hdr.mh_size, 924 "DCC CHAT chat %lu %u%c\n", 925 (unsigned long) so->so_faddr_ip, 926 so->so_faddr_port, 1); 927 } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { 928 if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 929 return 1; 930 931 m->m_len = bptr - m->m_data; /* Adjust length */ 932 m->m_len += snprintf(bptr, m->m_hdr.mh_size, 933 "DCC SEND %s %u %u %u%c\n", buff, 934 so->so_faddr_ip, so->so_faddr_port, n1, 1); 935 } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { 936 if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) 937 return 1; 938 939 m->m_len = bptr - m->m_data; /* Adjust length */ 940 m->m_len += snprintf(bptr, m->m_hdr.mh_size, 941 "DCC MOVE %s %lu %u %u%c\n", buff, 942 (unsigned long)so->so_faddr_ip, 943 so->so_faddr_port, n1, 1); 944 } 945 return 1; 946 947 case EMU_REALAUDIO: 948 /* 949 * RealAudio emulation - JP. We must try to parse the incoming 950 * data and try to find the two characters that contain the 951 * port number. Then we redirect an udp port and replace the 952 * number with the real port we got. 953 * 954 * The 1.0 beta versions of the player are not supported 955 * any more. 956 * 957 * A typical packet for player version 1.0 (release version): 958 * 959 * 0000:50 4E 41 00 05 960 * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .......glc..P 961 * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH 962 * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v 963 * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB 964 * 965 * Now the port number 0x1BD7 is found at offset 0x04 of the 966 * Now the port number 0x1BD7 is found at offset 0x04 of the 967 * second packet. This time we received five bytes first and 968 * then the rest. You never know how many bytes you get. 969 * 970 * A typical packet for player version 2.0 (beta): 971 * 972 * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA............ 973 * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxc..Win2.0.0 974 * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ 975 * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas 976 * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B 977 * 978 * Port number 0x1BC1 is found at offset 0x0d. 979 * 980 * This is just a horrible switch statement. Variable ra tells 981 * us where we're going. 982 */ 983 984 bptr = m->m_data; 985 while (bptr < m->m_data + m->m_len) { 986 u_short p; 987 static int ra = 0; 988 char ra_tbl[4]; 989 990 ra_tbl[0] = 0x50; 991 ra_tbl[1] = 0x4e; 992 ra_tbl[2] = 0x41; 993 ra_tbl[3] = 0; 994 995 switch (ra) { 996 case 0: 997 case 2: 998 case 3: 999 if (*bptr++ != ra_tbl[ra]) { 1000 ra = 0; 1001 continue; 1002 } 1003 break; 1004 1005 case 1: 1006 /* 1007 * We may get 0x50 several times, ignore them 1008 */ 1009 if (*bptr == 0x50) { 1010 ra = 1; 1011 bptr++; 1012 continue; 1013 } else if (*bptr++ != ra_tbl[ra]) { 1014 ra = 0; 1015 continue; 1016 } 1017 break; 1018 1019 case 4: 1020 /* 1021 * skip version number 1022 */ 1023 bptr++; 1024 break; 1025 1026 case 5: 1027 /* 1028 * The difference between versions 1.0 and 1029 * 2.0 is here. For future versions of 1030 * the player this may need to be modified. 1031 */ 1032 if (*(bptr + 1) == 0x02) 1033 bptr += 8; 1034 else 1035 bptr += 4; 1036 break; 1037 1038 case 6: 1039 /* This is the field containing the port 1040 * number that RA-player is listening to. 1041 */ 1042 lport = (((u_char*)bptr)[0] << 8) 1043 + ((u_char *)bptr)[1]; 1044 if (lport < 6970) 1045 lport += 256; /* don't know why */ 1046 if (lport < 6970 || lport > 7170) 1047 return 1; /* failed */ 1048 1049 /* try to get udp port between 6970 - 7170 */ 1050 for (p = 6970; p < 7071; p++) { 1051 if (udp_listen( p, 1052 so->so_laddr_ip, 1053 lport, 1054 SS_FACCEPTONCE)) { 1055 break; 1056 } 1057 } 1058 if (p == 7071) 1059 p = 0; 1060 *(u_char *)bptr++ = (p >> 8) & 0xff; 1061 *(u_char *)bptr++ = p & 0xff; 1062 ra = 0; 1063 return 1; /* port redirected, we're done */ 1064 break; 1065 1066 default: 1067 ra = 0; 1068 } 1069 ra++; 1070 } 1071 return 1; 1072 1073 default: 1074 /* Ooops, not emulated, won't call tcp_emu again */ 1075 so->so_emu = 0; 1076 return 1; 1077 } 1078 } 1079 1080 /* 1081 * Do misc. config of SLiRP while its running. 1082 * Return 0 if this connections is to be closed, 1 otherwise, 1083 * return 2 if this is a command-line connection 1084 */ 1085 int 1086 tcp_ctl(struct socket *so) 1087 { 1088 struct sbuf *sb = &so->so_snd; 1089 int command; 1090 struct ex_list *ex_ptr; 1091 int do_pty; 1092 // struct socket *tmpso; 1093 1094 DEBUG_CALL("tcp_ctl"); 1095 DEBUG_ARG("so = %lx", (long )so); 1096 1097 #if 0 1098 /* 1099 * Check if they're authorised 1100 */ 1101 if (ctl_addr_ip && (ctl_addr_ip == -1 || (so->so_laddr_ip != ctl_addr_ip))) { 1102 sb->sb_cc = sprintf(sb->sb_wptr,"Error: Permission denied.\r\n"); 1103 sb->sb_wptr += sb->sb_cc; 1104 return 0; 1105 } 1106 #endif 1107 command = (so->so_faddr_ip & 0xff); 1108 1109 switch(command) { 1110 default: /* Check for exec's */ 1111 1112 /* 1113 * Check if it's pty_exec 1114 */ 1115 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { 1116 if (ex_ptr->ex_fport == so->so_faddr_port && 1117 command == ex_ptr->ex_addr) { 1118 if (ex_ptr->ex_pty == 3) { 1119 so->s = -1; 1120 so->extra = (void *)ex_ptr->ex_exec; 1121 return 1; 1122 } 1123 do_pty = ex_ptr->ex_pty; 1124 goto do_exec; 1125 } 1126 } 1127 1128 /* 1129 * Nothing bound.. 1130 */ 1131 /* tcp_fconnect(so); */ 1132 1133 /* FALLTHROUGH */ 1134 case CTL_ALIAS: 1135 sb->sb_cc = snprintf(sb->sb_wptr, sb->sb_datalen - (sb->sb_wptr - sb->sb_data), 1136 "Error: No application configured.\r\n"); 1137 sb->sb_wptr += sb->sb_cc; 1138 return(0); 1139 1140 do_exec: 1141 DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec)); 1142 return(fork_exec(so, ex_ptr->ex_exec, do_pty)); 1143 1144 #if 0 1145 case CTL_CMD: 1146 for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { 1147 if (tmpso->so_emu == EMU_CTL && 1148 !(tmpso->so_tcpcb? 1149 (tmpso->so_tcpcb->t_state & (TCPS_TIME_WAIT|TCPS_LAST_ACK)) 1150 :0)) { 1151 /* Ooops, control connection already active */ 1152 sb->sb_cc = sprintf(sb->sb_wptr,"Sorry, already connected.\r\n"); 1153 sb->sb_wptr += sb->sb_cc; 1154 return 0; 1155 } 1156 } 1157 so->so_emu = EMU_CTL; 1158 ctl_password_ok = 0; 1159 sb->sb_cc = sprintf(sb->sb_wptr, "Slirp command-line ready (type \"help\" for help).\r\nSlirp> "); 1160 sb->sb_wptr += sb->sb_cc; 1161 do_echo=-1; 1162 return(2); 1163 #endif 1164 } 1165 } 1166