Revision 3b46e624 slirp/tcp_subr.c

b/slirp/tcp_subr.c
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; }
......
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 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
......
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
 */
......
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
......
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
......
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 864
				tp->iss = tcp_iss;
......
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
			 */		
993
			 */
994 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 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:"");
......
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 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),
......
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),
......
1120 1120
		 * any more.
1121 1121
		 *
1122 1122
		 * A typical packet for player version 1.0 (release version):
1123
		 *       
1123
		 *
1124 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 1153
			char ra_tbl[4];
1154
		
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
			
1183

  
1184 1184
			 case 4:
1185 1185
				/*
1186 1186
				 * skip version number
1187 1187
				 */
1188 1188
				bptr++;
1189 1189
				break;
1190
			
1190

  
1191 1191
			 case 5:
1192 1192
				/*
1193 1193
				 * The difference between versions 1.0 and
......
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 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),
......
1226 1226
				*(u_char *)bptr++ = p & 0xff;
1227 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;
......
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) {

Also available in: Unified diff