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

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.3   root      122: 
1.1       root      123:        DEBUG_CALL("fork_exec");
                    124:        DEBUG_ARG("so = %lx", (long)so);
                    125:        DEBUG_ARG("ex = %lx", (long)ex);
                    126:        DEBUG_ARG("do_pty = %lx", (long)do_pty);
1.1.1.3   root      127: 
1.1       root      128:        if (do_pty == 2) {
1.1.1.3   root      129:                 return 0;
1.1       root      130:        } else {
                    131:                addr.sin_family = AF_INET;
                    132:                addr.sin_port = 0;
                    133:                addr.sin_addr.s_addr = INADDR_ANY;
1.1.1.3   root      134: 
1.1.1.6 ! root      135:                if ((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
1.1       root      136:                    bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
                    137:                    listen(s, 1) < 0) {
                    138:                        lprint("Error: inet socket: %s\n", strerror(errno));
                    139:                        closesocket(s);
1.1.1.3   root      140: 
1.1       root      141:                        return 0;
                    142:                }
                    143:        }
1.1.1.3   root      144: 
1.1       root      145:        switch(fork()) {
                    146:         case -1:
                    147:                lprint("Error: fork failed: %s\n", strerror(errno));
                    148:                close(s);
                    149:                if (do_pty == 2)
                    150:                   close(master);
                    151:                return 0;
1.1.1.3   root      152: 
1.1       root      153:         case 0:
                    154:                /* Set the DISPLAY */
                    155:                if (do_pty == 2) {
                    156:                        (void) close(master);
                    157: #ifdef TIOCSCTTY /* XXXXX */
                    158:                        (void) setsid();
                    159:                        ioctl(s, TIOCSCTTY, (char *)NULL);
                    160: #endif
                    161:                } else {
                    162:                        getsockname(s, (struct sockaddr *)&addr, &addrlen);
                    163:                        close(s);
                    164:                        /*
                    165:                         * Connect to the socket
                    166:                         * XXX If any of these fail, we're in trouble!
                    167:                         */
1.1.1.6 ! root      168:                        s = qemu_socket(AF_INET, SOCK_STREAM, 0);
1.1       root      169:                        addr.sin_addr = loopback_addr;
                    170:                         do {
                    171:                             ret = connect(s, (struct sockaddr *)&addr, addrlen);
                    172:                         } while (ret < 0 && errno == EINTR);
                    173:                }
1.1.1.3   root      174: 
1.1       root      175:                dup2(s, 0);
                    176:                dup2(s, 1);
                    177:                dup2(s, 2);
1.1.1.3   root      178:                for (s = getdtablesize() - 1; s >= 3; s--)
1.1       root      179:                   close(s);
1.1.1.3   root      180: 
1.1       root      181:                i = 0;
                    182:                bptr = strdup(ex); /* No need to free() this */
                    183:                if (do_pty == 1) {
                    184:                        /* Setup "slirp.telnetd -x" */
                    185:                        argv[i++] = "slirp.telnetd";
                    186:                        argv[i++] = "-x";
                    187:                        argv[i++] = bptr;
                    188:                } else
                    189:                   do {
                    190:                        /* Change the string into argv[] */
                    191:                        curarg = bptr;
                    192:                        while (*bptr != ' ' && *bptr != (char)0)
                    193:                           bptr++;
                    194:                        c = *bptr;
                    195:                        *bptr++ = (char)0;
                    196:                        argv[i++] = strdup(curarg);
                    197:                   } while (c);
1.1.1.3   root      198: 
1.1.1.5   root      199:                 argv[i] = NULL;
1.1.1.4   root      200:                execvp(argv[0], (char **)argv);
1.1.1.3   root      201: 
1.1       root      202:                /* Ooops, failed, let's tell the user why */
                    203:                  {
                    204:                          char buff[256];
1.1.1.3   root      205: 
1.1.1.4   root      206:                          snprintf(buff, sizeof(buff),
                    207:                                    "Error: execvp of %s failed: %s\n",
                    208:                                    argv[0], strerror(errno));
1.1       root      209:                          write(2, buff, strlen(buff)+1);
                    210:                  }
                    211:                close(0); close(1); close(2); /* XXX */
                    212:                exit(1);
1.1.1.3   root      213: 
1.1       root      214:         default:
                    215:                if (do_pty == 2) {
                    216:                        close(s);
                    217:                        so->s = master;
                    218:                } else {
                    219:                        /*
                    220:                         * XXX this could block us...
                    221:                         * XXX Should set a timer here, and if accept() doesn't
                    222:                         * return after X seconds, declare it a failure
                    223:                         * The only reason this will block forever is if socket()
                    224:                         * of connect() fail in the child process
                    225:                         */
                    226:                         do {
                    227:                             so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
                    228:                         } while (so->s < 0 && errno == EINTR);
                    229:                         closesocket(s);
                    230:                        opt = 1;
                    231:                        setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
                    232:                        opt = 1;
                    233:                        setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
                    234:                }
                    235:                fd_nonblock(so->s);
1.1.1.3   root      236: 
1.1       root      237:                /* Append the telnet options now */
1.1.1.5   root      238:                 if (so->so_m != NULL && do_pty == 1)  {
1.1       root      239:                        sbappend(so, so->so_m);
1.1.1.5   root      240:                         so->so_m = NULL;
1.1       root      241:                }
1.1.1.3   root      242: 
1.1       root      243:                return 1;
                    244:        }
                    245: }
                    246: #endif
                    247: 
                    248: #ifndef HAVE_STRDUP
                    249: char *
                    250: strdup(str)
                    251:        const char *str;
                    252: {
                    253:        char *bptr;
1.1.1.3   root      254: 
1.1       root      255:        bptr = (char *)malloc(strlen(str)+1);
                    256:        strcpy(bptr, str);
1.1.1.3   root      257: 
1.1       root      258:        return bptr;
                    259: }
                    260: #endif
                    261: 
1.1.1.5   root      262: #include "monitor.h"
1.1.1.3   root      263: 
                    264: void lprint(const char *format, ...)
                    265: {
                    266:     va_list args;
                    267: 
                    268:     va_start(args, format);
1.1.1.5   root      269:     monitor_vprintf(cur_mon, format, args);
1.1.1.3   root      270:     va_end(args);
                    271: }
1.1       root      272: 
                    273: #ifdef BAD_SPRINTF
                    274: 
                    275: #undef vsprintf
                    276: #undef sprintf
                    277: 
                    278: /*
                    279:  * Some BSD-derived systems have a sprintf which returns char *
                    280:  */
                    281: 
                    282: int
                    283: vsprintf_len(string, format, args)
                    284:        char *string;
                    285:        const char *format;
                    286:        va_list args;
                    287: {
                    288:        vsprintf(string, format, args);
                    289:        return strlen(string);
                    290: }
                    291: 
                    292: int
                    293: #ifdef __STDC__
                    294: sprintf_len(char *string, const char *format, ...)
                    295: #else
                    296: sprintf_len(va_alist) va_dcl
                    297: #endif
                    298: {
                    299:        va_list args;
                    300: #ifdef __STDC__
                    301:        va_start(args, format);
                    302: #else
                    303:        char *string;
                    304:        char *format;
                    305:        va_start(args);
                    306:        string = va_arg(args, char *);
                    307:        format = va_arg(args, char *);
                    308: #endif
                    309:        vsprintf(string, format, args);
                    310:        return strlen(string);
                    311: }
                    312: 
                    313: #endif
                    314: 
                    315: void
1.1.1.5   root      316: u_sleep(int usec)
1.1       root      317: {
                    318:        struct timeval t;
                    319:        fd_set fdset;
1.1.1.3   root      320: 
1.1       root      321:        FD_ZERO(&fdset);
1.1.1.3   root      322: 
1.1       root      323:        t.tv_sec = 0;
                    324:        t.tv_usec = usec * 1000;
1.1.1.3   root      325: 
1.1       root      326:        select(0, &fdset, &fdset, &fdset, &t);
                    327: }
                    328: 
                    329: /*
                    330:  * Set fd blocking and non-blocking
                    331:  */
                    332: 
                    333: void
1.1.1.5   root      334: fd_nonblock(int fd)
1.1       root      335: {
                    336: #ifdef FIONBIO
1.1.1.5   root      337: #ifdef _WIN32
                    338:         unsigned long opt = 1;
                    339: #else
                    340:         int opt = 1;
                    341: #endif
1.1.1.3   root      342: 
1.1       root      343:        ioctlsocket(fd, FIONBIO, &opt);
                    344: #else
                    345:        int opt;
1.1.1.3   root      346: 
1.1       root      347:        opt = fcntl(fd, F_GETFL, 0);
                    348:        opt |= O_NONBLOCK;
                    349:        fcntl(fd, F_SETFL, opt);
                    350: #endif
                    351: }
                    352: 
                    353: void
1.1.1.5   root      354: fd_block(int fd)
1.1       root      355: {
                    356: #ifdef FIONBIO
1.1.1.5   root      357: #ifdef _WIN32
                    358:         unsigned long opt = 0;
                    359: #else
1.1       root      360:        int opt = 0;
1.1.1.5   root      361: #endif
1.1.1.3   root      362: 
1.1       root      363:        ioctlsocket(fd, FIONBIO, &opt);
                    364: #else
                    365:        int opt;
1.1.1.3   root      366: 
1.1       root      367:        opt = fcntl(fd, F_GETFL, 0);
                    368:        opt &= ~O_NONBLOCK;
                    369:        fcntl(fd, F_SETFL, opt);
                    370: #endif
                    371: }
                    372: 
1.1.1.5   root      373: void slirp_connection_info(Slirp *slirp, Monitor *mon)
1.1       root      374: {
1.1.1.5   root      375:     const char * const tcpstates[] = {
                    376:         [TCPS_CLOSED]       = "CLOSED",
                    377:         [TCPS_LISTEN]       = "LISTEN",
                    378:         [TCPS_SYN_SENT]     = "SYN_SENT",
                    379:         [TCPS_SYN_RECEIVED] = "SYN_RCVD",
                    380:         [TCPS_ESTABLISHED]  = "ESTABLISHED",
                    381:         [TCPS_CLOSE_WAIT]   = "CLOSE_WAIT",
                    382:         [TCPS_FIN_WAIT_1]   = "FIN_WAIT_1",
                    383:         [TCPS_CLOSING]      = "CLOSING",
                    384:         [TCPS_LAST_ACK]     = "LAST_ACK",
                    385:         [TCPS_FIN_WAIT_2]   = "FIN_WAIT_2",
                    386:         [TCPS_TIME_WAIT]    = "TIME_WAIT",
                    387:     };
                    388:     struct in_addr dst_addr;
                    389:     struct sockaddr_in src;
                    390:     socklen_t src_len;
                    391:     uint16_t dst_port;
                    392:     struct socket *so;
                    393:     const char *state;
                    394:     char buf[20];
                    395:     int n;
                    396: 
                    397:     monitor_printf(mon, "  Protocol[State]    FD  Source Address  Port   "
                    398:                         "Dest. Address  Port RecvQ SendQ\n");
                    399: 
                    400:     for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
                    401:         if (so->so_state & SS_HOSTFWD) {
                    402:             state = "HOST_FORWARD";
                    403:         } else if (so->so_tcpcb) {
                    404:             state = tcpstates[so->so_tcpcb->t_state];
                    405:         } else {
                    406:             state = "NONE";
1.1       root      407:         }
1.1.1.5   root      408:         if (so->so_state & (SS_HOSTFWD | SS_INCOMING)) {
                    409:             src_len = sizeof(src);
                    410:             getsockname(so->s, (struct sockaddr *)&src, &src_len);
                    411:             dst_addr = so->so_laddr;
                    412:             dst_port = so->so_lport;
                    413:         } else {
                    414:             src.sin_addr = so->so_laddr;
                    415:             src.sin_port = so->so_lport;
                    416:             dst_addr = so->so_faddr;
                    417:             dst_port = so->so_fport;
1.1       root      418:         }
1.1.1.5   root      419:         n = snprintf(buf, sizeof(buf), "  TCP[%s]", state);
                    420:         memset(&buf[n], ' ', 19 - n);
                    421:         buf[19] = 0;
                    422:         monitor_printf(mon, "%s %3d %15s %5d ", buf, so->s,
                    423:                        src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
                    424:                        ntohs(src.sin_port));
                    425:         monitor_printf(mon, "%15s %5d %5d %5d\n",
                    426:                        inet_ntoa(dst_addr), ntohs(dst_port),
                    427:                        so->so_rcv.sb_cc, so->so_snd.sb_cc);
                    428:     }
1.1.1.3   root      429: 
1.1.1.5   root      430:     for (so = slirp->udb.so_next; so != &slirp->udb; so = so->so_next) {
                    431:         if (so->so_state & SS_HOSTFWD) {
                    432:             n = snprintf(buf, sizeof(buf), "  UDP[HOST_FORWARD]");
                    433:             src_len = sizeof(src);
                    434:             getsockname(so->s, (struct sockaddr *)&src, &src_len);
                    435:             dst_addr = so->so_laddr;
                    436:             dst_port = so->so_lport;
                    437:         } else {
                    438:             n = snprintf(buf, sizeof(buf), "  UDP[%d sec]",
                    439:                          (so->so_expire - curtime) / 1000);
                    440:             src.sin_addr = so->so_laddr;
                    441:             src.sin_port = so->so_lport;
                    442:             dst_addr = so->so_faddr;
                    443:             dst_port = so->so_fport;
                    444:         }
                    445:         memset(&buf[n], ' ', 19 - n);
                    446:         buf[19] = 0;
                    447:         monitor_printf(mon, "%s %3d %15s %5d ", buf, so->s,
                    448:                        src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
                    449:                        ntohs(src.sin_port));
                    450:         monitor_printf(mon, "%15s %5d %5d %5d\n",
                    451:                        inet_ntoa(dst_addr), ntohs(dst_port),
                    452:                        so->so_rcv.sb_cc, so->so_snd.sb_cc);
                    453:     }
1.1       root      454: }

unix.superglobalmegacorp.com