Annotation of qemu/slirp/misc.c, revision 1.1.1.11

1.1       root        1: /*
                      2:  * Copyright (c) 1995 Danny Gasparovski.
1.1.1.3   root        3:  *
1.1       root        4:  * Please read the file COPYRIGHT for the
                      5:  * terms and conditions of the copyright.
                      6:  */
                      7: 
                      8: #include <slirp.h>
1.1.1.5   root        9: #include <libslirp.h>
1.1       root       10: 
1.1.1.5   root       11: #include "monitor.h"
1.1       root       12: 
1.1.1.5   root       13: #ifdef DEBUG
                     14: int slirp_debug = DBG_CALL|DBG_MISC|DBG_ERROR;
1.1       root       15: #endif
                     16: 
                     17: struct quehead {
                     18:        struct quehead *qh_link;
                     19:        struct quehead *qh_rlink;
                     20: };
                     21: 
                     22: inline void
1.1.1.5   root       23: insque(void *a, void *b)
1.1       root       24: {
                     25:        register struct quehead *element = (struct quehead *) a;
                     26:        register struct quehead *head = (struct quehead *) b;
                     27:        element->qh_link = head->qh_link;
                     28:        head->qh_link = (struct quehead *)element;
                     29:        element->qh_rlink = (struct quehead *)head;
                     30:        ((struct quehead *)(element->qh_link))->qh_rlink
                     31:        = (struct quehead *)element;
                     32: }
                     33: 
                     34: inline void
1.1.1.5   root       35: remque(void *a)
1.1       root       36: {
                     37:   register struct quehead *element = (struct quehead *) a;
                     38:   ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
                     39:   ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
                     40:   element->qh_rlink = NULL;
                     41: }
                     42: 
1.1.1.5   root       43: int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec,
                     44:              struct in_addr addr, int port)
1.1       root       45: {
                     46:        struct ex_list *tmp_ptr;
1.1.1.3   root       47: 
1.1       root       48:        /* First, check if the port is "bound" */
                     49:        for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
1.1.1.5   root       50:                if (port == tmp_ptr->ex_fport &&
                     51:                    addr.s_addr == tmp_ptr->ex_addr.s_addr)
                     52:                        return -1;
1.1       root       53:        }
1.1.1.3   root       54: 
1.1       root       55:        tmp_ptr = *ex_ptr;
                     56:        *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list));
                     57:        (*ex_ptr)->ex_fport = port;
                     58:        (*ex_ptr)->ex_addr = addr;
                     59:        (*ex_ptr)->ex_pty = do_pty;
1.1.1.4   root       60:        (*ex_ptr)->ex_exec = (do_pty == 3) ? exec : strdup(exec);
1.1       root       61:        (*ex_ptr)->ex_next = tmp_ptr;
                     62:        return 0;
                     63: }
                     64: 
                     65: #ifndef HAVE_STRERROR
                     66: 
                     67: /*
                     68:  * For systems with no strerror
                     69:  */
                     70: 
                     71: extern int sys_nerr;
                     72: extern char *sys_errlist[];
                     73: 
                     74: char *
                     75: strerror(error)
                     76:        int error;
                     77: {
                     78:        if (error < sys_nerr)
                     79:           return sys_errlist[error];
                     80:        else
                     81:           return "Unknown error.";
                     82: }
                     83: 
                     84: #endif
                     85: 
                     86: 
                     87: #ifdef _WIN32
                     88: 
                     89: int
1.1.1.3   root       90: fork_exec(struct socket *so, const char *ex, int do_pty)
1.1       root       91: {
                     92:     /* not implemented */
                     93:     return 0;
                     94: }
                     95: 
                     96: #else
                     97: 
                     98: /*
                     99:  * XXX This is ugly
                    100:  * We create and bind a socket, then fork off to another
                    101:  * process, which connects to this socket, after which we
                    102:  * exec the wanted program.  If something (strange) happens,
                    103:  * the accept() call could block us forever.
1.1.1.3   root      104:  *
1.1       root      105:  * do_pty = 0   Fork/exec inetd style
                    106:  * do_pty = 1   Fork/exec using slirp.telnetd
                    107:  * do_ptr = 2   Fork/exec using pty
                    108:  */
                    109: int
1.1.1.3   root      110: fork_exec(struct socket *so, const char *ex, int do_pty)
1.1       root      111: {
                    112:        int s;
                    113:        struct sockaddr_in addr;
1.1.1.4   root      114:        socklen_t addrlen = sizeof(addr);
1.1       root      115:        int opt;
1.1.1.3   root      116:         int master = -1;
1.1.1.4   root      117:        const char *argv[256];
1.1       root      118:        /* don't want to clobber the original */
                    119:        char *bptr;
1.1.1.3   root      120:        const char *curarg;
1.1       root      121:        int c, i, ret;
1.1.1.10  root      122:        pid_t pid;
1.1.1.3   root      123: 
1.1       root      124:        DEBUG_CALL("fork_exec");
                    125:        DEBUG_ARG("so = %lx", (long)so);
                    126:        DEBUG_ARG("ex = %lx", (long)ex);
                    127:        DEBUG_ARG("do_pty = %lx", (long)do_pty);
1.1.1.3   root      128: 
1.1       root      129:        if (do_pty == 2) {
1.1.1.3   root      130:                 return 0;
1.1       root      131:        } else {
                    132:                addr.sin_family = AF_INET;
                    133:                addr.sin_port = 0;
                    134:                addr.sin_addr.s_addr = INADDR_ANY;
1.1.1.3   root      135: 
1.1.1.6   root      136:                if ((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
1.1       root      137:                    bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
                    138:                    listen(s, 1) < 0) {
                    139:                        lprint("Error: inet socket: %s\n", strerror(errno));
                    140:                        closesocket(s);
1.1.1.3   root      141: 
1.1       root      142:                        return 0;
                    143:                }
                    144:        }
1.1.1.3   root      145: 
1.1.1.10  root      146:        pid = fork();
                    147:        switch(pid) {
1.1       root      148:         case -1:
                    149:                lprint("Error: fork failed: %s\n", strerror(errno));
                    150:                close(s);
                    151:                if (do_pty == 2)
                    152:                   close(master);
                    153:                return 0;
1.1.1.3   root      154: 
1.1       root      155:         case 0:
1.1.1.10  root      156:                 setsid();
                    157: 
1.1       root      158:                /* Set the DISPLAY */
                    159:                if (do_pty == 2) {
                    160:                        (void) close(master);
                    161: #ifdef TIOCSCTTY /* XXXXX */
                    162:                        ioctl(s, TIOCSCTTY, (char *)NULL);
                    163: #endif
                    164:                } else {
                    165:                        getsockname(s, (struct sockaddr *)&addr, &addrlen);
                    166:                        close(s);
                    167:                        /*
                    168:                         * Connect to the socket
                    169:                         * XXX If any of these fail, we're in trouble!
                    170:                         */
1.1.1.6   root      171:                        s = qemu_socket(AF_INET, SOCK_STREAM, 0);
1.1       root      172:                        addr.sin_addr = loopback_addr;
                    173:                         do {
                    174:                             ret = connect(s, (struct sockaddr *)&addr, addrlen);
                    175:                         } while (ret < 0 && errno == EINTR);
                    176:                }
1.1.1.3   root      177: 
1.1       root      178:                dup2(s, 0);
                    179:                dup2(s, 1);
                    180:                dup2(s, 2);
1.1.1.3   root      181:                for (s = getdtablesize() - 1; s >= 3; s--)
1.1       root      182:                   close(s);
1.1.1.3   root      183: 
1.1       root      184:                i = 0;
1.1.1.11! root      185:                bptr = g_strdup(ex); /* No need to free() this */
1.1       root      186:                if (do_pty == 1) {
                    187:                        /* Setup "slirp.telnetd -x" */
                    188:                        argv[i++] = "slirp.telnetd";
                    189:                        argv[i++] = "-x";
                    190:                        argv[i++] = bptr;
                    191:                } else
                    192:                   do {
                    193:                        /* Change the string into argv[] */
                    194:                        curarg = bptr;
                    195:                        while (*bptr != ' ' && *bptr != (char)0)
                    196:                           bptr++;
                    197:                        c = *bptr;
                    198:                        *bptr++ = (char)0;
                    199:                        argv[i++] = strdup(curarg);
                    200:                   } while (c);
1.1.1.3   root      201: 
1.1.1.5   root      202:                 argv[i] = NULL;
1.1.1.4   root      203:                execvp(argv[0], (char **)argv);
1.1.1.3   root      204: 
1.1       root      205:                /* Ooops, failed, let's tell the user why */
1.1.1.8   root      206:         fprintf(stderr, "Error: execvp of %s failed: %s\n",
                    207:                 argv[0], strerror(errno));
1.1       root      208:                close(0); close(1); close(2); /* XXX */
                    209:                exit(1);
1.1.1.3   root      210: 
1.1       root      211:         default:
1.1.1.10  root      212:                qemu_add_child_watch(pid);
1.1       root      213:                if (do_pty == 2) {
                    214:                        close(s);
                    215:                        so->s = master;
                    216:                } else {
                    217:                        /*
                    218:                         * XXX this could block us...
                    219:                         * XXX Should set a timer here, and if accept() doesn't
                    220:                         * return after X seconds, declare it a failure
                    221:                         * The only reason this will block forever is if socket()
                    222:                         * of connect() fail in the child process
                    223:                         */
                    224:                         do {
                    225:                             so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
                    226:                         } while (so->s < 0 && errno == EINTR);
                    227:                         closesocket(s);
                    228:                        opt = 1;
                    229:                        setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
                    230:                        opt = 1;
                    231:                        setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
                    232:                }
                    233:                fd_nonblock(so->s);
1.1.1.3   root      234: 
1.1       root      235:                /* Append the telnet options now */
1.1.1.5   root      236:                 if (so->so_m != NULL && do_pty == 1)  {
1.1       root      237:                        sbappend(so, so->so_m);
1.1.1.5   root      238:                         so->so_m = NULL;
1.1       root      239:                }
1.1.1.3   root      240: 
1.1       root      241:                return 1;
                    242:        }
                    243: }
                    244: #endif
                    245: 
                    246: #ifndef HAVE_STRDUP
                    247: char *
                    248: strdup(str)
                    249:        const char *str;
                    250: {
                    251:        char *bptr;
1.1.1.3   root      252: 
1.1       root      253:        bptr = (char *)malloc(strlen(str)+1);
                    254:        strcpy(bptr, str);
1.1.1.3   root      255: 
1.1       root      256:        return bptr;
                    257: }
                    258: #endif
                    259: 
1.1.1.5   root      260: #include "monitor.h"
1.1.1.3   root      261: 
                    262: void lprint(const char *format, ...)
                    263: {
                    264:     va_list args;
                    265: 
                    266:     va_start(args, format);
1.1.1.8   root      267:     monitor_vprintf(default_mon, format, args);
1.1.1.3   root      268:     va_end(args);
                    269: }
1.1       root      270: 
                    271: void
1.1.1.5   root      272: u_sleep(int usec)
1.1       root      273: {
                    274:        struct timeval t;
                    275:        fd_set fdset;
1.1.1.3   root      276: 
1.1       root      277:        FD_ZERO(&fdset);
1.1.1.3   root      278: 
1.1       root      279:        t.tv_sec = 0;
                    280:        t.tv_usec = usec * 1000;
1.1.1.3   root      281: 
1.1       root      282:        select(0, &fdset, &fdset, &fdset, &t);
                    283: }
                    284: 
                    285: /*
                    286:  * Set fd blocking and non-blocking
                    287:  */
                    288: 
                    289: void
1.1.1.5   root      290: fd_nonblock(int fd)
1.1       root      291: {
                    292: #ifdef FIONBIO
1.1.1.5   root      293: #ifdef _WIN32
                    294:         unsigned long opt = 1;
                    295: #else
                    296:         int opt = 1;
                    297: #endif
1.1.1.3   root      298: 
1.1       root      299:        ioctlsocket(fd, FIONBIO, &opt);
                    300: #else
                    301:        int opt;
1.1.1.3   root      302: 
1.1       root      303:        opt = fcntl(fd, F_GETFL, 0);
                    304:        opt |= O_NONBLOCK;
                    305:        fcntl(fd, F_SETFL, opt);
                    306: #endif
                    307: }
                    308: 
                    309: void
1.1.1.5   root      310: fd_block(int fd)
1.1       root      311: {
                    312: #ifdef FIONBIO
1.1.1.5   root      313: #ifdef _WIN32
                    314:         unsigned long opt = 0;
                    315: #else
1.1       root      316:        int opt = 0;
1.1.1.5   root      317: #endif
1.1.1.3   root      318: 
1.1       root      319:        ioctlsocket(fd, FIONBIO, &opt);
                    320: #else
                    321:        int opt;
1.1.1.3   root      322: 
1.1       root      323:        opt = fcntl(fd, F_GETFL, 0);
                    324:        opt &= ~O_NONBLOCK;
                    325:        fcntl(fd, F_SETFL, opt);
                    326: #endif
                    327: }
                    328: 
1.1.1.5   root      329: void slirp_connection_info(Slirp *slirp, Monitor *mon)
1.1       root      330: {
1.1.1.5   root      331:     const char * const tcpstates[] = {
                    332:         [TCPS_CLOSED]       = "CLOSED",
                    333:         [TCPS_LISTEN]       = "LISTEN",
                    334:         [TCPS_SYN_SENT]     = "SYN_SENT",
                    335:         [TCPS_SYN_RECEIVED] = "SYN_RCVD",
                    336:         [TCPS_ESTABLISHED]  = "ESTABLISHED",
                    337:         [TCPS_CLOSE_WAIT]   = "CLOSE_WAIT",
                    338:         [TCPS_FIN_WAIT_1]   = "FIN_WAIT_1",
                    339:         [TCPS_CLOSING]      = "CLOSING",
                    340:         [TCPS_LAST_ACK]     = "LAST_ACK",
                    341:         [TCPS_FIN_WAIT_2]   = "FIN_WAIT_2",
                    342:         [TCPS_TIME_WAIT]    = "TIME_WAIT",
                    343:     };
                    344:     struct in_addr dst_addr;
                    345:     struct sockaddr_in src;
                    346:     socklen_t src_len;
                    347:     uint16_t dst_port;
                    348:     struct socket *so;
                    349:     const char *state;
                    350:     char buf[20];
                    351:     int n;
                    352: 
                    353:     monitor_printf(mon, "  Protocol[State]    FD  Source Address  Port   "
                    354:                         "Dest. Address  Port RecvQ SendQ\n");
                    355: 
                    356:     for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
                    357:         if (so->so_state & SS_HOSTFWD) {
                    358:             state = "HOST_FORWARD";
                    359:         } else if (so->so_tcpcb) {
                    360:             state = tcpstates[so->so_tcpcb->t_state];
                    361:         } else {
                    362:             state = "NONE";
1.1       root      363:         }
1.1.1.5   root      364:         if (so->so_state & (SS_HOSTFWD | SS_INCOMING)) {
                    365:             src_len = sizeof(src);
                    366:             getsockname(so->s, (struct sockaddr *)&src, &src_len);
                    367:             dst_addr = so->so_laddr;
                    368:             dst_port = so->so_lport;
                    369:         } else {
                    370:             src.sin_addr = so->so_laddr;
                    371:             src.sin_port = so->so_lport;
                    372:             dst_addr = so->so_faddr;
                    373:             dst_port = so->so_fport;
1.1       root      374:         }
1.1.1.5   root      375:         n = snprintf(buf, sizeof(buf), "  TCP[%s]", state);
                    376:         memset(&buf[n], ' ', 19 - n);
                    377:         buf[19] = 0;
                    378:         monitor_printf(mon, "%s %3d %15s %5d ", buf, so->s,
                    379:                        src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
                    380:                        ntohs(src.sin_port));
                    381:         monitor_printf(mon, "%15s %5d %5d %5d\n",
                    382:                        inet_ntoa(dst_addr), ntohs(dst_port),
                    383:                        so->so_rcv.sb_cc, so->so_snd.sb_cc);
                    384:     }
1.1.1.3   root      385: 
1.1.1.5   root      386:     for (so = slirp->udb.so_next; so != &slirp->udb; so = so->so_next) {
                    387:         if (so->so_state & SS_HOSTFWD) {
                    388:             n = snprintf(buf, sizeof(buf), "  UDP[HOST_FORWARD]");
                    389:             src_len = sizeof(src);
                    390:             getsockname(so->s, (struct sockaddr *)&src, &src_len);
                    391:             dst_addr = so->so_laddr;
                    392:             dst_port = so->so_lport;
                    393:         } else {
                    394:             n = snprintf(buf, sizeof(buf), "  UDP[%d sec]",
                    395:                          (so->so_expire - curtime) / 1000);
                    396:             src.sin_addr = so->so_laddr;
                    397:             src.sin_port = so->so_lport;
                    398:             dst_addr = so->so_faddr;
                    399:             dst_port = so->so_fport;
                    400:         }
                    401:         memset(&buf[n], ' ', 19 - n);
                    402:         buf[19] = 0;
                    403:         monitor_printf(mon, "%s %3d %15s %5d ", buf, so->s,
                    404:                        src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
                    405:                        ntohs(src.sin_port));
                    406:         monitor_printf(mon, "%15s %5d %5d %5d\n",
                    407:                        inet_ntoa(dst_addr), ntohs(dst_port),
                    408:                        so->so_rcv.sb_cc, so->so_snd.sb_cc);
                    409:     }
1.1.1.10  root      410: 
                    411:     for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so->so_next) {
                    412:         n = snprintf(buf, sizeof(buf), "  ICMP[%d sec]",
                    413:                      (so->so_expire - curtime) / 1000);
                    414:         src.sin_addr = so->so_laddr;
                    415:         dst_addr = so->so_faddr;
                    416:         memset(&buf[n], ' ', 19 - n);
                    417:         buf[19] = 0;
                    418:         monitor_printf(mon, "%s %3d %15s  -    ", buf, so->s,
                    419:                        src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
                    420:         monitor_printf(mon, "%15s  -    %5d %5d\n", inet_ntoa(dst_addr),
                    421:                        so->so_rcv.sb_cc, so->so_snd.sb_cc);
                    422:     }
1.1       root      423: }

unix.superglobalmegacorp.com