Changeset 14329 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Nov 18, 2008 9:59:24 PM (16 years ago)
- Location:
- trunk/src/VBox/Devices/Network/slirp
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/libslirp.h
r14204 r14329 78 78 #endif 79 79 80 /* 81 * Return the timeout. 82 */ 83 unsigned int slirp_get_timeout_ms(PNATState pData); 84 80 85 #ifdef __cplusplus 81 86 } -
trunk/src/VBox/Devices/Network/slirp/misc.c
r14090 r14329 223 223 224 224 225 #ifdef _WIN32226 227 int228 fork_exec(PNATState pData, struct socket *so, char *ex, int do_pty)229 {230 /* not implemented */231 return 0;232 }233 234 #else235 236 /*237 * XXX This is ugly238 * We create and bind a socket, then fork off to another239 * process, which connects to this socket, after which we240 * exec the wanted program. If something (strange) happens,241 * the accept() call could block us forever.242 *243 * do_pty = 0 Fork/exec inetd style244 * do_pty = 1 Fork/exec using slirp.telnetd245 * do_ptr = 2 Fork/exec using pty246 */247 int248 fork_exec(PNATState pData, struct socket *so, char *ex, int do_pty)249 {250 int s;251 struct sockaddr_in addr;252 socklen_t addrlen = sizeof(addr);253 int opt;254 int master;255 char *argv[256];256 #if 0257 char buff[256];258 #endif259 /* don't want to clobber the original */260 char *bptr;261 char *curarg;262 int c, i, ret;263 264 DEBUG_CALL("fork_exec");265 DEBUG_ARG("so = %lx", (long)so);266 DEBUG_ARG("ex = %lx", (long)ex);267 DEBUG_ARG("do_pty = %lx", (long)do_pty);268 269 if (do_pty == 2) {270 AssertRelease(do_pty != 2);271 /* shut up gcc */272 s = 0;273 master = 0;274 } else {275 addr.sin_family = AF_INET;276 addr.sin_port = 0;277 addr.sin_addr.s_addr = INADDR_ANY;278 279 if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||280 bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||281 listen(s, 1) < 0) {282 lprint("Error: inet socket: %s\n", strerror(errno));283 closesocket(s);284 285 return 0;286 }287 }288 289 switch(fork()) {290 case -1:291 lprint("Error: fork failed: %s\n", strerror(errno));292 close(s);293 if (do_pty == 2)294 close(master);295 return 0;296 297 case 0:298 /* Set the DISPLAY */299 if (do_pty == 2) {300 (void) close(master);301 #ifdef TIOCSCTTY /* XXXXX */302 (void) setsid();303 ioctl(s, TIOCSCTTY, (char *)NULL);304 #endif305 } else {306 getsockname(s, (struct sockaddr *)&addr, &addrlen);307 close(s);308 /*309 * Connect to the socket310 * XXX If any of these fail, we're in trouble!311 */312 s = socket(AF_INET, SOCK_STREAM, 0);313 addr.sin_addr = loopback_addr;314 do {315 ret = connect(s, (struct sockaddr *)&addr, addrlen);316 } while (ret < 0 && errno == EINTR);317 }318 319 #if 0320 if (x_port >= 0) {321 #ifdef HAVE_SETENV322 sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);323 setenv("DISPLAY", buff, 1);324 #else325 sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);326 putenv(buff);327 #endif328 }329 #endif330 dup2(s, 0);331 dup2(s, 1);332 dup2(s, 2);333 for (s = 3; s <= 255; s++)334 close(s);335 336 i = 0;337 bptr = strdup(ex); /* No need to free() this */338 if (do_pty == 1) {339 /* Setup "slirp.telnetd -x" */340 argv[i++] = "slirp.telnetd";341 argv[i++] = "-x";342 argv[i++] = bptr;343 } else344 do {345 /* Change the string into argv[] */346 curarg = bptr;347 while (*bptr != ' ' && *bptr != (char)0)348 bptr++;349 c = *bptr;350 *bptr++ = (char)0;351 argv[i++] = strdup(curarg);352 } while (c);353 354 argv[i] = 0;355 execvp(argv[0], argv);356 357 /* Ooops, failed, let's tell the user why */358 {359 char buff[256];360 361 sprintf(buff, "Error: execvp of %s failed: %s\n",362 argv[0], strerror(errno));363 write(2, buff, strlen(buff)+1);364 }365 close(0); close(1); close(2); /* XXX */366 exit(1);367 368 default:369 if (do_pty == 2) {370 close(s);371 so->s = master;372 } else {373 /*374 * XXX this could block us...375 * XXX Should set a timer here, and if accept() doesn't376 * return after X seconds, declare it a failure377 * The only reason this will block forever is if socket()378 * of connect() fail in the child process379 */380 do {381 so->s = accept(s, (struct sockaddr *)&addr, &addrlen);382 } while (so->s < 0 && errno == EINTR);383 closesocket(s);384 opt = 1;385 setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));386 opt = 1;387 setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));388 }389 fd_nonblock(so->s);390 391 /* Append the telnet options now */392 if (so->so_m != 0 && do_pty == 1) {393 sbappend(pData, so, so->so_m);394 so->so_m = 0;395 }396 397 return 1;398 }399 }400 #endif401 402 225 #ifndef HAVE_STRDUP 403 226 char * -
trunk/src/VBox/Devices/Network/slirp/slirp.c
r14232 r14329 1012 1012 } 1013 1013 #endif 1014 1015 unsigned int slirp_get_timeout_ms(PNATState pData) 1016 { 1017 if (link_up) 1018 { 1019 if (time_fasttimo) 1020 return 2; 1021 if (do_slowtimo) 1022 return 500; 1023 } 1024 return 0; 1025 } -
trunk/src/VBox/Devices/Network/slirp/socket.h
r14180 r14329 68 68 #define SS_FWDRAIN 0x040 /* We received a FIN, drain data and set SS_FCANTSENDMORE */ 69 69 70 #define SS_CTL 0x080 70 /* #define SS_CTL 0x080 */ 71 71 #define SS_FACCEPTCONN 0x100 /* Socket is accepting connections from a host on the internet */ 72 72 #define SS_FACCEPTONCE 0x200 /* If set, the SS_FACCEPTCONN socket will die after one accept */ -
trunk/src/VBox/Devices/Network/slirp/tcp_input.c
r14309 r14329 812 812 */ 813 813 814 /*815 * If this is destined for the control address, then flag to816 * tcp_ctl once connected, otherwise connect817 */818 if ((so->so_faddr.s_addr&htonl(pData->netmask)) == special_addr.s_addr) {819 int lastbyte=ntohl(so->so_faddr.s_addr) & ~pData->netmask;820 if (lastbyte!=CTL_ALIAS && lastbyte!=CTL_DNS) {821 #if 0822 if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) {823 /* Command or exec adress */824 so->so_state |= SS_CTL;825 } else826 #endif827 {828 /* May be an add exec */829 struct ex_list *ex_ptr;830 for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {831 if(ex_ptr->ex_fport == so->so_fport &&832 lastbyte == ex_ptr->ex_addr) {833 so->so_state |= SS_CTL;834 break;835 }836 }837 }838 if(so->so_state & SS_CTL) goto cont_input;839 }840 /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */841 }842 843 814 if (so->so_emu & EMU_NOCONNECT) { 844 815 so->so_emu &= ~EMU_NOCONNECT; … … 1211 1182 */ 1212 1183 tp->snd_una=ti->ti_ack; 1213 if (so->so_state & SS_CTL) { 1214 /* So tcp_ctl reports the right state */ 1215 ret = tcp_ctl(pData, so); 1216 if (ret == 1) { 1217 soisfconnected(so); 1218 so->so_state &= ~SS_CTL; /* success XXX */ 1219 } else if (ret == 2) { 1220 so->so_state = SS_NOFDREF; /* CTL_CMD */ 1221 } else { 1222 needoutput = 1; 1223 tp->t_state = TCPS_FIN_WAIT_1; 1224 } 1225 } else { 1226 soisfconnected(so); 1227 } 1184 soisfconnected(so); 1228 1185 1229 1186 /* Do window scaling? */ -
trunk/src/VBox/Devices/Network/slirp/tcp_subr.c
r14309 r14329 1233 1233 } 1234 1234 1235 /*1236 * Do misc. config of SLiRP while its running.1237 * Return 0 if this connections is to be closed, 1 otherwise,1238 * return 2 if this is a command-line connection1239 */1240 int1241 tcp_ctl(PNATState pData, struct socket *so)1242 {1243 struct sbuf *sb = &so->so_snd;1244 int command;1245 struct ex_list *ex_ptr;1246 int do_pty;1247 /* struct socket *tmpso; */1248 1249 DEBUG_CALL("tcp_ctl");1250 DEBUG_ARG("so = %lx", (long )so);1251 1252 #if 01253 /*1254 * Check if they're authorised1255 */1256 if (ctl_addr.s_addr && (ctl_addr.s_addr == -1 || (so->so_laddr.s_addr != ctl_addr.s_addr))) {1257 sb->sb_cc = sprintf(sb->sb_wptr,"Error: Permission denied.\r\n");1258 sb->sb_wptr += sb->sb_cc;1259 return 0;1260 }1261 #endif1262 command = (ntohl(so->so_faddr.s_addr) & 0xff);1263 1264 switch(command) {1265 default: /* Check for exec's */1266 1267 /*1268 * Check if it's pty_exec1269 */1270 for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {1271 if (ex_ptr->ex_fport == so->so_fport &&1272 command == ex_ptr->ex_addr) {1273 do_pty = ex_ptr->ex_pty;1274 goto do_exec;1275 }1276 }1277 1278 /*1279 * Nothing bound..1280 */1281 /* tcp_fconnect(so); */1282 1283 /* FALLTHROUGH */1284 case CTL_ALIAS:1285 sb->sb_cc = sprintf(sb->sb_wptr,1286 "Error: No application configured.\r\n");1287 sb->sb_wptr += sb->sb_cc;1288 return(0);1289 1290 do_exec:1291 DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec));1292 return(fork_exec(pData, so, ex_ptr->ex_exec, do_pty));1293 1294 #if 01295 case CTL_CMD:1296 for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) {1297 if (tmpso->so_emu == EMU_CTL &&1298 !(tmpso->so_tcpcb?1299 (tmpso->so_tcpcb->t_state & (TCPS_TIME_WAIT|TCPS_LAST_ACK))1300 :0)) {1301 /* Ooops, control connection already active */1302 sb->sb_cc = sprintf(sb->sb_wptr,"Sorry, already connected.\r\n");1303 sb->sb_wptr += sb->sb_cc;1304 return 0;1305 }1306 }1307 so->so_emu = EMU_CTL;1308 ctl_password_ok = 0;1309 sb->sb_cc = sprintf(sb->sb_wptr, "Slirp command-line ready (type \"help\" for help).\r\nSlirp> ");1310 sb->sb_wptr += sb->sb_cc;1311 do_echo=-1;1312 return(2);1313 #endif1314 }1315 }1316 1317 1235 #if SIZEOF_CHAR_P != 4 1318 1236 /**
Note:
See TracChangeset
for help on using the changeset viewer.