Revision 5fafdf24 slirp/tcp_subr.c

b/slirp/tcp_subr.c
37 37
/*
38 38
 * Changes and additions relating to SLiRP
39 39
 * Copyright (c) 1995 Danny Gasparovski.
40
 * 
41
 * Please read the file COPYRIGHT for the 
40
 *
41
 * Please read the file COPYRIGHT for the
42 42
 * terms and conditions of the copyright.
43 43
 */
44 44

  
......
60 60
{
61 61
	tcp_iss = 1;		/* wrong */
62 62
	tcb.so_next = tcb.so_prev = &tcb;
63
	
63

  
64 64
	/* tcp_rcvspace = our Window we advertise to the remote */
65 65
	tcp_rcvspace = TCP_RCVSPACE;
66 66
	tcp_sndspace = TCP_SNDSPACE;
67
	
67

  
68 68
	/* Make sure tcp_sndspace is at least 2*MSS */
69 69
	if (tcp_sndspace < 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr)))
70 70
		tcp_sndspace = 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr));
......
92 92
	n->ti_dst = so->so_laddr;
93 93
	n->ti_sport = so->so_fport;
94 94
	n->ti_dport = so->so_lport;
95
	
95

  
96 96
	n->ti_seq = 0;
97 97
	n->ti_ack = 0;
98 98
	n->ti_x2 = 0;
......
134 134
	DEBUG_ARG("ack = %u", ack);
135 135
	DEBUG_ARG("seq = %u", seq);
136 136
	DEBUG_ARG("flags = %x", flags);
137
	
137

  
138 138
	if (tp)
139 139
		win = sbspace(&tp->t_socket->so_rcv);
140 140
	if (m == 0) {
......
150 150
		ti = mtod(m, struct tcpiphdr *);
151 151
		flags = TH_ACK;
152 152
	} else {
153
		/* 
153
		/*
154 154
		 * ti points into m so the next line is just making
155 155
		 * the mbuf point to ti
156 156
		 */
157 157
		m->m_data = (caddr_t)ti;
158
		
158
	
159 159
		m->m_len = sizeof (struct tcpiphdr);
160 160
		tlen = 0;
161 161
#define xchg(a,b,type) { type t; t=a; a=b; b=t; }
......
183 183
	ti->ti_sum = cksum(m, tlen);
184 184
	((struct ip *)ti)->ip_len = tlen;
185 185

  
186
	if(flags & TH_RST) 
186
	if(flags & TH_RST)
187 187
	  ((struct ip *)ti)->ip_ttl = MAXTTL;
188
	else 
188
	else
189 189
	  ((struct ip *)ti)->ip_ttl = ip_defttl;
190
	
190

  
191 191
	(void) ip_output((struct socket *)0, m);
192 192
}
193 193

  
......
201 201
	struct socket *so;
202 202
{
203 203
	register struct tcpcb *tp;
204
	
204

  
205 205
	tp = (struct tcpcb *)malloc(sizeof(*tp));
206 206
	if (tp == NULL)
207 207
		return ((struct tcpcb *)0);
208
	
208

  
209 209
	memset((char *) tp, 0, sizeof(struct tcpcb));
210 210
	tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp;
211 211
	tp->t_maxseg = tcp_mssdflt;
212
	
212

  
213 213
	tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
214 214
	tp->t_socket = so;
215
	
215

  
216 216
	/*
217 217
	 * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no
218 218
	 * rtt estimate.  Set rttvar so that srtt + 2 * rttvar gives
......
222 222
	tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2;
223 223
	tp->t_rttmin = TCPTV_MIN;
224 224

  
225
	TCPT_RANGESET(tp->t_rxtcur, 
225
	TCPT_RANGESET(tp->t_rxtcur,
226 226
	    ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1,
227 227
	    TCPTV_MIN, TCPTV_REXMTMAX);
228 228

  
229 229
	tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
230 230
	tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
231 231
	tp->t_state = TCPS_CLOSED;
232
	
232

  
233 233
	so->so_tcpcb = tp;
234 234

  
235 235
	return (tp);
......
240 240
 * the specified error.  If connection is synchronized,
241 241
 * then send a RST to peer.
242 242
 */
243
struct tcpcb *tcp_drop(struct tcpcb *tp, int err) 
243
struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
244 244
{
245 245
/* tcp_drop(tp, errno)
246 246
	register struct tcpcb *tp;
......
251 251
	DEBUG_CALL("tcp_drop");
252 252
	DEBUG_ARG("tp = %lx", (long)tp);
253 253
	DEBUG_ARG("errno = %d", errno);
254
	
254

  
255 255
	if (TCPS_HAVERCVDSYN(tp->t_state)) {
256 256
		tp->t_state = TCPS_CLOSED;
257 257
		(void) tcp_output(tp);
......
281 281

  
282 282
	DEBUG_CALL("tcp_close");
283 283
	DEBUG_ARG("tp = %lx", (long )tp);
284
	
284

  
285 285
	/* free the reassembly queue, if any */
286 286
	t = (struct tcpiphdr *) tp->seg_next;
287 287
	while (t != (struct tcpiphdr *)tp) {
......
356 356

  
357 357
	DEBUG_CALL("tcp_sockclosed");
358 358
	DEBUG_ARG("tp = %lx", (long)tp);
359
	
359

  
360 360
	switch (tp->t_state) {
361 361

  
362 362
	case TCPS_CLOSED:
......
382 382
		tcp_output(tp);
383 383
}
384 384

  
385
/* 
385
/*
386 386
 * Connect to a host on the Internet
387 387
 * Called by tcp_input
388 388
 * Only do a connect, the tcp fields will be set in tcp_input
389 389
 * return 0 if there's a result of the connect,
390 390
 * else return -1 means we're still connecting
391 391
 * The return value is almost always -1 since the socket is
392
 * nonblocking.  Connect returns after the SYN is sent, and does 
392
 * nonblocking.  Connect returns after the SYN is sent, and does
393 393
 * not wait for ACK+SYN.
394 394
 */
395 395
int tcp_fconnect(so)
396 396
     struct socket *so;
397 397
{
398 398
  int ret=0;
399
  
399
 
400 400
  DEBUG_CALL("tcp_fconnect");
401 401
  DEBUG_ARG("so = %lx", (long )so);
402 402

  
......
409 409
    setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(opt ));
410 410
    opt = 1;
411 411
    setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt ));
412
    
412
   
413 413
    addr.sin_family = AF_INET;
414 414
    if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) {
415 415
      /* It's an alias */
......
425 425
    } else
426 426
      addr.sin_addr = so->so_faddr;
427 427
    addr.sin_port = so->so_fport;
428
    
428
   
429 429
    DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, "
430
		"addr.sin_addr.s_addr=%.16s\n", 
430
		"addr.sin_addr.s_addr=%.16s\n",
431 431
		ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
432 432
    /* We don't care what port we get */
433 433
    ret = connect(s,(struct sockaddr *)&addr,sizeof (addr));
434
    
434
   
435 435
    /*
436 436
     * If it's not in progress, it failed, so we just return 0,
437 437
     * without clearing SS_NOFDREF
......
444 444

  
445 445
/*
446 446
 * Accept the socket and connect to the local-host
447
 * 
447
 *
448 448
 * We have a problem. The correct thing to do would be
449 449
 * to first connect to the local-host, and only if the
450 450
 * connection is accepted, then do an accept() here.
451
 * But, a) we need to know who's trying to connect 
451
 * But, a) we need to know who's trying to connect
452 452
 * to the socket to be able to SYN the local-host, and
453 453
 * b) we are already connected to the foreign host by
454 454
 * the time it gets to accept(), so... We simply accept
455 455
 * here and SYN the local-host.
456
 */ 
456
 */
457 457
void
458 458
tcp_connect(inso)
459 459
	struct socket *inso;
......
466 466

  
467 467
	DEBUG_CALL("tcp_connect");
468 468
	DEBUG_ARG("inso = %lx", (long)inso);
469
	
469

  
470 470
	/*
471 471
	 * If it's an SS_ACCEPTONCE socket, no need to socreate()
472 472
	 * another socket, just use the accept() socket.
......
487 487
		so->so_laddr = inso->so_laddr;
488 488
		so->so_lport = inso->so_lport;
489 489
	}
490
	
490

  
491 491
	(void) tcp_mss(sototcpcb(so), 0);
492 492

  
493 493
	if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) {
......
501 501
	setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
502 502
	opt = 1;
503 503
	setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int));
504
	
504

  
505 505
	so->so_fport = addr.sin_port;
506 506
	so->so_faddr = addr.sin_addr;
507 507
	/* Translate connections from localhost to the real hostname */
508 508
	if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr)
509 509
	   so->so_faddr = alias_addr;
510
	
510

  
511 511
	/* Close the accept() socket, set right state */
512 512
	if (inso->so_state & SS_FACCEPTONCE) {
513 513
		closesocket(so->s); /* If we only accept once, close the accept() socket */
......
515 515
					   /* if it's not FACCEPTONCE, it's already NOFDREF */
516 516
	}
517 517
	so->s = s;
518
	
518

  
519 519
	so->so_iptos = tcp_tos(so);
520 520
	tp = sototcpcb(so);
521 521

  
522 522
	tcp_template(tp);
523
	
523

  
524 524
	/* Compute window scaling to request.  */
525 525
/*	while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
526 526
 *		(TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
......
529 529

  
530 530
/*	soisconnecting(so); */ /* NOFDREF used instead */
531 531
	tcpstat.tcps_connattempt++;
532
	
532

  
533 533
	tp->t_state = TCPS_SYN_SENT;
534 534
	tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
535
	tp->iss = tcp_iss; 
535
	tp->iss = tcp_iss;
536 536
	tcp_iss += TCP_ISSINCR/2;
537 537
	tcp_sendseqinit(tp);
538 538
	tcp_output(tp);
......
547 547
{
548 548
	if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL)
549 549
	   return -1;
550
	
550

  
551 551
	insque(so, &tcb);
552 552

  
553 553
	return 0;
......
573 573
};
574 574

  
575 575
struct emu_t *tcpemu = 0;
576
		
576
	
577 577
/*
578 578
 * Return TOS according to the above table
579 579
 */
......
583 583
{
584 584
	int i = 0;
585 585
	struct emu_t *emup;
586
	
586

  
587 587
	while(tcptos[i].tos) {
588 588
		if ((tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) ||
589 589
		    (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) {
......
592 592
		}
593 593
		i++;
594 594
	}
595
	
595

  
596 596
	/* Nope, lets see if there's a user-added one */
597 597
	for (emup = tcpemu; emup; emup = emup->next) {
598 598
		if ((emup->fport && (ntohs(so->so_fport) == emup->fport)) ||
......
601 601
			return emup->tos;
602 602
		}
603 603
	}
604
	
604

  
605 605
	return 0;
606 606
}
607 607

  
......
612 612
 * This includes ftp (the data connection is
613 613
 * initiated by the server) and IRC (DCC CHAT and
614 614
 * DCC SEND) for now
615
 * 
615
 *
616 616
 * NOTE: It's possible to crash SLiRP by sending it
617 617
 * unstandard strings to emulate... if this is a problem,
618 618
 * more checks are needed here
619 619
 *
620 620
 * XXX Assumes the whole command came in one packet
621
 *					    
621
 *					   
622 622
 * XXX Some ftp clients will have their TOS set to
623 623
 * LOWDELAY and so Nagel will kick in.  Because of this,
624 624
 * we'll get the first letter, followed by the rest, so
625 625
 * we simply scan for ORT instead of PORT...
626 626
 * DCC doesn't have this problem because there's other stuff
627 627
 * in the packet before the DCC command.
628
 * 
629
 * Return 1 if the mbuf m is still valid and should be 
628
 *
629
 * Return 1 if the mbuf m is still valid and should be
630 630
 * sbappend()ed
631
 * 
631
 *
632 632
 * NOTE: if you return 0 you MUST m_free() the mbuf!
633 633
 */
634 634
int
......
641 641
	u_int32_t laddr;
642 642
	u_int lport;
643 643
	char *bptr;
644
	
644

  
645 645
	DEBUG_CALL("tcp_emu");
646 646
	DEBUG_ARG("so = %lx", (long)so);
647 647
	DEBUG_ARG("m = %lx", (long)m);
648
	
648

  
649 649
	switch(so->so_emu) {
650 650
		int x, i;
651
		
651
	
652 652
	 case EMU_IDENT:
653 653
		/*
654 654
		 * Identification protocol as per rfc-1413
655 655
		 */
656
		
656
	
657 657
		{
658 658
			struct socket *tmpso;
659 659
			struct sockaddr_in addr;
660 660
			int addrlen = sizeof(struct sockaddr_in);
661 661
			struct sbuf *so_rcv = &so->so_rcv;
662
			
662
		
663 663
			memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
664 664
			so_rcv->sb_wptr += m->m_len;
665 665
			so_rcv->sb_rptr += m->m_len;
......
688 688
			m_free(m);
689 689
			return 0;
690 690
		}
691
		
691
	
692 692
#if 0
693 693
	 case EMU_RLOGIN:
694 694
		/*
......
703 703
			char term[100];
704 704
			struct sbuf *so_snd = &so->so_snd;
705 705
			struct sbuf *so_rcv = &so->so_rcv;
706
			
706
		
707 707
			/* First check if they have a priveladged port, or too much data has arrived */
708 708
			if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 ||
709 709
			    (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) {
......
714 714
				m_free(m);
715 715
				return 0;
716 716
			}
717
			
717
		
718 718
			/* Append the current data */
719 719
			memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
720 720
			so_rcv->sb_wptr += m->m_len;
721 721
			so_rcv->sb_rptr += m->m_len;
722 722
			m_free(m);
723
			
723
		
724 724
			/*
725 725
			 * Check if we have all the initial options,
726 726
			 * and build argument list to rlogin while we're here
......
752 752
					}
753 753
				}
754 754
			}
755
			
755
		
756 756
			if (n != 4)
757 757
			   return 0;
758
			
758
		
759 759
			/* We have it, set our term variable and fork_exec() */
760 760
#ifdef HAVE_SETENV
761 761
			setenv("TERM", term, 1);
......
765 765
			fork_exec(so, args, 2);
766 766
			term[0] = 0;
767 767
			so->so_emu = 0;
768
			
768
		
769 769
			/* And finally, send the client a 0 character */
770 770
			so_snd->sb_wptr[0] = 0;
771 771
			so_snd->sb_wptr++;
772 772
			so_snd->sb_cc++;
773
			
773
		
774 774
			return 0;
775 775
		}
776
		
776
	
777 777
	 case EMU_RSH:
778 778
		/*
779 779
		 * rsh emulation
......
787 787
			char *args;
788 788
			struct sbuf *so_snd = &so->so_snd;
789 789
			struct sbuf *so_rcv = &so->so_rcv;
790
			
790
		
791 791
			/* First check if they have a priveladged port, or too much data has arrived */
792 792
			if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 ||
793 793
			    (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) {
......
798 798
				m_free(m);
799 799
				return 0;
800 800
			}
801
			
801
		
802 802
			/* Append the current data */
803 803
			memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
804 804
			so_rcv->sb_wptr += m->m_len;
805 805
			so_rcv->sb_rptr += m->m_len;
806 806
			m_free(m);
807
			
807
		
808 808
			/*
809 809
			 * Check if we have all the initial options,
810 810
			 * and build argument list to rlogin while we're here
......
840 840
				ns->so_faddr=so->so_faddr;
841 841
				ns->so_fport=htons(IPPORT_RESERVED-1); /* Use a fake port. */
842 842

  
843
				if (ns->so_faddr.s_addr == 0 || 
843
				if (ns->so_faddr.s_addr == 0 ||
844 844
					ns->so_faddr.s_addr == loopback_addr.s_addr)
845 845
                  ns->so_faddr = alias_addr;
846 846

  
847 847
				ns->so_iptos = tcp_tos(ns);
848 848
				tp = sototcpcb(ns);
849
                
849
               
850 850
				tcp_template(tp);
851
                
851
               
852 852
				/* Compute window scaling to request.  */
853 853
				/*	while (tp->request_r_scale < TCP_MAX_WINSHIFT &&
854 854
				 *		(TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat)
......
858 858
                /*soisfconnecting(ns);*/
859 859

  
860 860
				tcpstat.tcps_connattempt++;
861
					
861
				
862 862
				tp->t_state = TCPS_SYN_SENT;
863 863
				tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
864
				tp->iss = tcp_iss; 
864
				tp->iss = tcp_iss;
865 865
				tcp_iss += TCP_ISSINCR/2;
866 866
				tcp_sendseqinit(tp);
867 867
				tcp_output(tp);
......
877 877
                }
878 878
              }
879 879
			}
880
			
880
		
881 881
			if (n != 4)
882 882
              return 0;
883
			
883
		
884 884
			rsh_exec(so,so->extra, user, inet_ntoa(so->so_faddr), args);
885 885
			so->so_emu = 0;
886 886
			so->extra=NULL;
887
			
887
		
888 888
			/* And finally, send the client a 0 character */
889 889
			so_snd->sb_wptr[0] = 0;
890 890
			so_snd->sb_wptr++;
891 891
			so_snd->sb_cc++;
892
			
892
		
893 893
			return 0;
894 894
		}
895 895

  
......
898 898
			int num;
899 899
			struct sbuf *so_snd = &so->so_snd;
900 900
			struct sbuf *so_rcv = &so->so_rcv;
901
			
901
		
902 902
			/*
903 903
			 * If there is binary data here, we save it in so->so_m
904 904
			 */
......
913 913
			    }
914 914
			  }
915 915
			} /* if(so->so_m==NULL) */
916
			
916
		
917 917
			/*
918 918
			 * Append the line
919 919
			 */
920 920
			sbappendsb(so_rcv, m);
921
			
921
		
922 922
			/* To avoid going over the edge of the buffer, we reset it */
923 923
			if (so_snd->sb_cc == 0)
924 924
			   so_snd->sb_wptr = so_snd->sb_rptr = so_snd->sb_data;
925
			
925
		
926 926
			/*
927 927
			 * A bit of a hack:
928 928
			 * If the first packet we get here is 1 byte long, then it
......
941 941
			  tcp_output(sototcpcb(so)); /* XXX */
942 942
			} else
943 943
			  m_free(m);
944
			
944
		
945 945
			num = 0;
946 946
			while (num < so->so_rcv.sb_cc) {
947 947
				if (*(so->so_rcv.sb_rptr + num) == '\n' ||
948 948
				    *(so->so_rcv.sb_rptr + num) == '\r') {
949 949
					int n;
950
					
950
				
951 951
					*(so_rcv->sb_rptr + num) = 0;
952 952
					if (ctl_password && !ctl_password_ok) {
953 953
						/* Need a password */
......
984 984
			}
985 985
			return 0;
986 986
		}
987
#endif		
987
#endif	
988 988
        case EMU_FTP: /* ftp */
989 989
		*(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */
990 990
		if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) {
991 991
			/*
992 992
			 * Need to emulate the PORT command
993
			 */			
994
			x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]", 
993
			 */		
994
			x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]",
995 995
				   &n1, &n2, &n3, &n4, &n5, &n6, buff);
996 996
			if (x < 6)
997 997
			   return 1;
998
			
998
		
999 999
			laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
1000 1000
			lport = htons((n5 << 8) | (n6));
1001
			
1001
		
1002 1002
			if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL)
1003 1003
			   return 1;
1004
			
1004
		
1005 1005
			n6 = ntohs(so->so_fport);
1006
			
1006
		
1007 1007
			n5 = (n6 >> 8) & 0xff;
1008 1008
			n6 &= 0xff;
1009
			
1009
		
1010 1010
			laddr = ntohl(so->so_faddr.s_addr);
1011
			
1011
		
1012 1012
			n1 = ((laddr >> 24) & 0xff);
1013 1013
			n2 = ((laddr >> 16) & 0xff);
1014 1014
			n3 = ((laddr >> 8)  & 0xff);
1015 1015
			n4 =  (laddr & 0xff);
1016
			
1016
		
1017 1017
			m->m_len = bptr - m->m_data; /* Adjust length */
1018
			m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s", 
1018
			m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s",
1019 1019
					    n1, n2, n3, n4, n5, n6, x==7?buff:"");
1020 1020
			return 1;
1021 1021
		} else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) {
......
1026 1026
				   &n1, &n2, &n3, &n4, &n5, &n6, buff);
1027 1027
			if (x < 6)
1028 1028
			   return 1;
1029
			
1029
		
1030 1030
			laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4));
1031 1031
			lport = htons((n5 << 8) | (n6));
1032
			
1032
		
1033 1033
			if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL)
1034 1034
			   return 1;
1035
			
1035
		
1036 1036
			n6 = ntohs(so->so_fport);
1037
			
1037
		
1038 1038
			n5 = (n6 >> 8) & 0xff;
1039 1039
			n6 &= 0xff;
1040
			
1040
		
1041 1041
			laddr = ntohl(so->so_faddr.s_addr);
1042
			
1042
		
1043 1043
			n1 = ((laddr >> 24) & 0xff);
1044 1044
			n2 = ((laddr >> 16) & 0xff);
1045 1045
			n3 = ((laddr >> 8)  & 0xff);
1046 1046
			n4 =  (laddr & 0xff);
1047
			
1047
		
1048 1048
			m->m_len = bptr - m->m_data; /* Adjust length */
1049 1049
			m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s",
1050 1050
					    n1, n2, n3, n4, n5, n6, x==7?buff:"");
1051
			
1051
		
1052 1052
			return 1;
1053 1053
		}
1054
		
1054
	
1055 1055
		return 1;
1056
				   
1056
				  
1057 1057
	 case EMU_KSH:
1058 1058
		/*
1059 1059
		 * The kshell (Kerberos rsh) and shell services both pass
......
1072 1072
		    (so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL)
1073 1073
			m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1;
1074 1074
		return 1;
1075
		
1075
	
1076 1076
	 case EMU_IRC:
1077 1077
		/*
1078 1078
		 * Need to emulate DCC CHAT, DCC SEND and DCC MOVE
......
1080 1080
		*(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */
1081 1081
		if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL)
1082 1082
			 return 1;
1083
		
1083
	
1084 1084
		/* The %256s is for the broken mIRC */
1085 1085
		if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) {
1086 1086
			if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
1087 1087
				return 1;
1088
			
1088
		
1089 1089
			m->m_len = bptr - m->m_data; /* Adjust length */
1090 1090
			m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n",
1091 1091
			     (unsigned long)ntohl(so->so_faddr.s_addr),
......
1093 1093
		} else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
1094 1094
			if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
1095 1095
				return 1;
1096
			
1096
		
1097 1097
			m->m_len = bptr - m->m_data; /* Adjust length */
1098
			m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n", 
1098
			m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n",
1099 1099
			      buff, (unsigned long)ntohl(so->so_faddr.s_addr),
1100 1100
			      ntohs(so->so_fport), n1, 1);
1101 1101
		} else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) {
1102 1102
			if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL)
1103 1103
				return 1;
1104
			
1104
		
1105 1105
			m->m_len = bptr - m->m_data; /* Adjust length */
1106 1106
			m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n",
1107 1107
			      buff, (unsigned long)ntohl(so->so_faddr.s_addr),
......
1110 1110
		return 1;
1111 1111

  
1112 1112
	 case EMU_REALAUDIO:
1113
                /* 
1113
                /*
1114 1114
		 * RealAudio emulation - JP. We must try to parse the incoming
1115 1115
		 * data and try to find the two characters that contain the
1116 1116
		 * port number. Then we redirect an udp port and replace the
......
1118 1118
		 *
1119 1119
		 * The 1.0 beta versions of the player are not supported
1120 1120
		 * any more.
1121
		 * 
1121
		 *
1122 1122
		 * A typical packet for player version 1.0 (release version):
1123
		 *        
1124
		 * 0000:50 4E 41 00 05 
1123
		 *       
1124
		 * 0000:50 4E 41 00 05
1125 1125
		 * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....?..g?l?c..P
1126 1126
		 * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH
1127 1127
		 * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v
1128 1128
		 * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB
1129
		 *         
1129
		 *        
1130 1130
		 * Now the port number 0x1BD7 is found at offset 0x04 of the
1131 1131
		 * Now the port number 0x1BD7 is found at offset 0x04 of the
1132 1132
		 * second packet. This time we received five bytes first and
1133 1133
		 * then the rest. You never know how many bytes you get.
1134 1134
		 *
1135 1135
		 * A typical packet for player version 2.0 (beta):
1136
		 *        
1136
		 *       
1137 1137
		 * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........?.
1138 1138
		 * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .gux?c..Win2.0.0
1139 1139
		 * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/
1140 1140
		 * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas
1141 1141
		 * 0040:65 2E 72 61 79 53 00 00 06 36 42                e.rayS...6B
1142
		 *        
1142
		 *       
1143 1143
		 * Port number 0x1BC1 is found at offset 0x0d.
1144
		 *      
1144
		 *     
1145 1145
		 * This is just a horrible switch statement. Variable ra tells
1146 1146
		 * us where we're going.
1147 1147
		 */
1148
		
1148
	
1149 1149
		bptr = m->m_data;
1150 1150
		while (bptr < m->m_data + m->m_len) {
1151 1151
			u_short p;
1152 1152
			static int ra = 0;
1153
			char ra_tbl[4]; 
1154
			
1153
			char ra_tbl[4];
1154
		
1155 1155
			ra_tbl[0] = 0x50;
1156 1156
			ra_tbl[1] = 0x4e;
1157 1157
			ra_tbl[2] = 0x41;
1158 1158
			ra_tbl[3] = 0;
1159
			
1159
		
1160 1160
			switch (ra) {
1161 1161
			 case 0:
1162 1162
			 case 2:
......
1166 1166
					continue;
1167 1167
				}
1168 1168
				break;
1169
				
1169
			
1170 1170
			 case 1:
1171 1171
				/*
1172 1172
				 * We may get 0x50 several times, ignore them
......
1180 1180
					continue;
1181 1181
				}
1182 1182
				break;
1183
				
1184
			 case 4: 
1185
				/* 
1183
			
1184
			 case 4:
1185
				/*
1186 1186
				 * skip version number
1187 1187
				 */
1188 1188
				bptr++;
1189 1189
				break;
1190
				
1191
			 case 5: 
1190
			
1191
			 case 5:
1192 1192
				/*
1193 1193
				 * The difference between versions 1.0 and
1194 1194
				 * 2.0 is here. For future versions of
......
1198 1198
				   bptr += 8;
1199 1199
				else
1200 1200
				   bptr += 4;
1201
				break;                          
1202
				
1201
				break;                         
1202
			
1203 1203
			 case 6:
1204 1204
				/* This is the field containing the port
1205 1205
				 * number that RA-player is listening to.
1206 1206
				 */
1207
				lport = (((u_char*)bptr)[0] << 8) 
1207
				lport = (((u_char*)bptr)[0] << 8)
1208 1208
				+ ((u_char *)bptr)[1];
1209
				if (lport < 6970)      
1209
				if (lport < 6970)     
1210 1210
				   lport += 256;   /* don't know why */
1211 1211
				if (lport < 6970 || lport > 7170)
1212 1212
				   return 1;       /* failed */
1213
				
1213
			
1214 1214
				/* try to get udp port between 6970 - 7170 */
1215 1215
				for (p = 6970; p < 7071; p++) {
1216 1216
					if (udp_listen( htons(p),
......
1224 1224
				   p = 0;
1225 1225
				*(u_char *)bptr++ = (p >> 8) & 0xff;
1226 1226
				*(u_char *)bptr++ = p & 0xff;
1227
				ra = 0; 
1227
				ra = 0;
1228 1228
				return 1;   /* port redirected, we're done */
1229
				break;  
1230
				
1229
				break; 
1230
			
1231 1231
			 default:
1232
				ra = 0;                         
1232
				ra = 0;                        
1233 1233
			}
1234 1234
			ra++;
1235 1235
		}
1236
		return 1;                                
1237
		
1236
		return 1;                               
1237
	
1238 1238
	 default:
1239 1239
		/* Ooops, not emulated, won't call tcp_emu again */
1240 1240
		so->so_emu = 0;
......
1256 1256
 	struct ex_list *ex_ptr;
1257 1257
	int do_pty;
1258 1258
        //	struct socket *tmpso;
1259
	
1259

  
1260 1260
	DEBUG_CALL("tcp_ctl");
1261 1261
	DEBUG_ARG("so = %lx", (long )so);
1262
	
1262

  
1263 1263
#if 0
1264 1264
	/*
1265 1265
	 * Check if they're authorised
......
1269 1269
		sb->sb_wptr += sb->sb_cc;
1270 1270
		return 0;
1271 1271
	}
1272
#endif	
1272
#endif
1273 1273
	command = (ntohl(so->so_faddr.s_addr) & 0xff);
1274
	
1274

  
1275 1275
	switch(command) {
1276 1276
	default: /* Check for exec's */
1277
		
1277
	
1278 1278
		/*
1279 1279
		 * Check if it's pty_exec
1280 1280
		 */
......
1285 1285
				goto do_exec;
1286 1286
			}
1287 1287
		}
1288
		
1288
	
1289 1289
		/*
1290 1290
		 * Nothing bound..
1291 1291
		 */
1292 1292
		/* tcp_fconnect(so); */
1293
		
1293
	
1294 1294
		/* FALLTHROUGH */
1295 1295
	case CTL_ALIAS:
1296 1296
	  sb->sb_cc = sprintf(sb->sb_wptr,
......
1301 1301
	do_exec:
1302 1302
		DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec));
1303 1303
		return(fork_exec(so, ex_ptr->ex_exec, do_pty));
1304
		
1304
	
1305 1305
#if 0
1306 1306
	case CTL_CMD:
1307 1307
	   for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) {
1308
	     if (tmpso->so_emu == EMU_CTL && 
1309
		 !(tmpso->so_tcpcb? 
1308
	     if (tmpso->so_emu == EMU_CTL &&
1309
		 !(tmpso->so_tcpcb?
1310 1310
		   (tmpso->so_tcpcb->t_state & (TCPS_TIME_WAIT|TCPS_LAST_ACK))
1311 1311
		   :0)) {
1312 1312
	       /* Ooops, control connection already active */

Also available in: Unified diff