Esempio n. 1
0
/**
 * Sends rdate message to destination and retrieves date
 * @param dest the destination of the rdate message
 * @return aquired date for success, SYSERR for syntax error
 */
long getRdate(char *dest)
{
    ushort dev = 0;
    uchar buf[4];
    struct netaddr host;
    struct netaddr *localhost;
    struct netif *interface;


    bzero((uchar *)buf, 4);

    /* Open Device on rdate port */
    if ((ushort)SYSERR == (dev = udpAlloc()))
    {
        return SYSERR;
    }

    if (SYSERR == dot2ipv4(dest, &host))
    {
        return SYSERR;
    }

    /* Look up local ip info */
    interface = netLookup((ethertab[0].dev)->num);

    if (NULL == interface)
    {
        fprintf(stderr, "No network interface found\n");
        return 1;
    }

    localhost = &(interface->ip);

    if (SYSERR == open(dev, localhost, &host, NULL, UDP_PORT_RDATE))
    {
        return SYSERR;
    }

    /* Write Message to destination */
    if (SYSERR == write(dev, buf, 4))
    {
        return SYSERR;
    }

    /* If we read an invalid amount, then rdate failed */
    if (SYSERR == read(dev, buf, 4))
    {
        return SYSERR;
    }

    /* Close device after completion */
    if (SYSERR == (long)close(dev))
    {
        return SYSERR;
    }

    /* convert bytes to long */
    return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
}
Esempio n. 2
0
/**
 * Shell command (netup) to start a network interface.
 * @param nargs  number of arguments in args array
 * @param args   array of arguments
 * @return OK for success, SYSERR for syntax error
 */
shellcmd xsh_netup(int nargs, char *args[])
{
    int descrp;
    struct netaddr ip;
    struct netaddr mask;
    struct netaddr gateway;
    char *str_ip, *str_mask, *str_gateway;
    char nvramLookup[DEVMAXNAME + NVRAM_STRMAX];

    /* Enable interrupts */
    enable();

    /* Help */
    if ((2 == nargs) && (0 == strncmp(args[1], "--help", 7)))
    {
        usage(args[0]);
        return SHELL_OK;
    }

    /* Parse device */
    if (nargs > 1)
    {
        descrp = getdev(args[1]);
        if (SYSERR == descrp)
        {
            fprintf(stderr, "%s is not a valid device.\n", args[1]);
            return SHELL_ERROR;
        }
    }
    else
    {
        /* assume first ethernet interface */
        descrp = (ethertab[0].dev)->num;
    }

    if (5 == nargs)
    {
        /* grab string data */
        str_ip = args[2];
        str_mask = args[3];
        str_gateway = args[4];
    }
    else if (nargs < 3)
    {
        /* lookup information in nvram */
        bzero(nvramLookup, DEVMAXNAME + NVRAM_STRMAX);
        sprintf(nvramLookup, "%s_%s", (ethertab[0].dev)->name,
                NET_LAN_IPADDR);
#if NVRAM
        str_ip = nvramGet(nvramLookup);
        if (NULL == str_ip)
        {
            str_ip = nvramGet("lan_ipaddr");
        }
#else
        str_ip = NULL;
#endif                          /* NVRAM */

        bzero(nvramLookup, DEVMAXNAME + NVRAM_STRMAX);
        sprintf(nvramLookup, "%s_%s", (ethertab[0].dev)->name,
                NET_SUBNET_MASK);
#if NVRAM
        str_mask = nvramGet(nvramLookup);
        if (NULL == str_mask)
        {
            str_mask = nvramGet("lan_netmask");
        }
#else
        str_mask = NULL;
#endif                          /* NVRAM */

#if NVRAM
        str_gateway = nvramGet(NET_GATEWAY);
        if (NULL == str_gateway)
        {
            str_gateway = nvramGet("lan_gateway");
        }
#else
        str_gateway = NULL;
#endif                          /* NVRAM */
    }
    else
    {
        fprintf(stderr, "Invalid number of arguments\n");
        return SHELL_ERROR;
    }

    /* Make sure we have valid IPv4 style parameters */
    if (NULL == str_ip)
    {
        str_ip = "0.0.0.0";
    }

    if (NULL == str_mask)
    {
        str_mask = "0.0.0.0";
    }

    if (NULL == str_gateway)
    {
        str_gateway = "0.0.0.0";
    }

    /* Parse IP */
    if (SYSERR == dot2ipv4(str_ip, &ip))
    {
        fprintf(stderr, "%s is not a valid IPv4 address.\n", str_ip);
        return SHELL_ERROR;
    }

    /* Parse Mask */
    if (SYSERR == dot2ipv4(str_mask, &mask))
    {
        fprintf(stderr, "%s is not a valid IPv4 address mask.\n",
                str_mask);
        return SHELL_ERROR;
    }

    /* Parse Gateway */
    if (SYSERR == dot2ipv4(str_gateway, &gateway))
    {
        fprintf(stderr, "%s is not a valid IPv4 address.\n", str_gateway);
        return SHELL_ERROR;
    }

    if (SYSERR == netUp(descrp, &ip, &mask, &gateway))
    {
        fprintf(stderr, "Failed to start network interface on %s\n",
                args[1]);
        return SHELL_ERROR;
    }

    printf("%s is %s with netmask %s (gateway: %s)\n",
           devtab[descrp].name, str_ip, str_mask, str_gateway);

    return SHELL_OK;
}
Esempio n. 3
0
/**
 * @ingroup shell
 *
 * Shell command (telnet).
 * @param nargs  number of arguments in args array
 * @param args   array of arguments
 * @return 0 for success, 1 for error
 */
shellcmd xsh_telnet(int nargs, char *args[])
{
    int i;
    ushort port = 0;
    struct netaddr host;
    struct netaddr *localhost;
    struct netif *interface;

    tid_typ recvthr;
    tid_typ sendthr;
    int msg = 0;
    int dev;

    for (i = 1; i < nargs; i++)
    {
        /* Help */
        if (0 == strcmp(args[i], "--help"))
        {
            usage(args[0]);
            return 0;
        }

        /* Host */
        if (0 == host.len)
        {
            if (SYSERR == dot2ipv4(args[i], &host))
            {
                fprintf(stderr, "Invalid hostname\n");
                return 1;
            }
            continue;
        }

        /* Port */
        if (0 == port)
        {
            port = atoi(args[i]);
            if (port == 0)
            {
                fprintf(stderr, "Port must be greater than 0\n");
                return 1;
            }
            continue;
        }

        /* Otherwise */
        fprintf(stderr, "Invalid number of arguments\n");
        return 1;
    }

    /* Verify a valid number of arguments were processed */
    if (0 == host.len)
    {
        fprintf(stderr, "Invalid number of arguments\n");
        return 1;
    }

    /* Set default port if none is specified */
    if (port == 0)
    {
        port = TELNET_PORT;
    }

    /* Print that the client is trying to connect to the server */
    printf("Trying %s...\n", args[1]);

    interface = netLookup((ethertab[0].dev)->num);
    if (NULL == interface)
    {
        fprintf(stderr, "No network interface found\n");
        return 1;
    }
    localhost = &(interface->ip);

    /* Open connection */
#if NTCP
    dev = tcpAlloc();
#else
    dev = SYSERR;
#endif                          /* NTCP */
    if (SYSERR == dev)
    {
        fprintf(stderr, "Failed to allocate TCP device\n");
        return 1;
    }


    if (SYSERR == open(dev, localhost, &host, NULL, port, TCP_ACTIVE))
    {
        fprintf(stderr, "Failed to establish connection\n");
        return 1;
    }

    /* Display a connection prompt and tell the user how to quit */
    printf("Connected to %s.\nQuit character is '^]'.\n", args[1]);

    recvthr =
        create(telnetRecv, SHELL_CMDSTK, SHELL_CMDPRIO, "telnet_recv", 1,
               dev);
    sendthr =
        create(telnetSend, SHELL_CMDSTK, SHELL_CMDPRIO, "telnet_send", 1,
               dev);

    if ((SYSERR == recvthr) || (SYSERR == sendthr))
    {
        kill(recvthr);
        kill(sendthr);
        close(dev);
        return 1;
    }

    thrtab[recvthr].fdesc[0] = stdin;
    thrtab[recvthr].fdesc[1] = stdout;
    thrtab[recvthr].fdesc[2] = stderr;
    thrtab[sendthr].fdesc[0] = stdin;
    thrtab[sendthr].fdesc[1] = stdout;
    thrtab[sendthr].fdesc[2] = stderr;

    /* Start both threads */
    while (recvclr() != NOMSG);
    control(stdin, TTY_CTRL_SET_IFLAG, TTY_ECHO, NULL);
    control(stdin, TTY_CTRL_CLR_IFLAG, TTY_IRAW, NULL);
    ready(recvthr, RESCHED_YES);
    ready(sendthr, RESCHED_NO);

    /* Wait for one thread to die */
    while ((msg != recvthr) && (msg != sendthr))
    {
        msg = receive();
    }
    sleep(10);

    /* Kill both threads */
    kill(recvthr);
    kill(sendthr);

    close(dev);

    control(stdin, TTY_CTRL_SET_IFLAG, TTY_ECHO, NULL);
    control(stdin, TTY_CTRL_CLR_IFLAG, TTY_IRAW, NULL);

    return 0;
}
Esempio n. 4
0
/**
 * @ingroup shell
 *
 * Shell command (ping).
 * @param nargs  number of arguments in args array
 * @param args   array of arguments
 * @return OK for success, SYSERR for syntax error
 */
shellcmd xsh_ping(int nargs, char *args[])
{
    int i = 0;
    int interval = 1000, count = 10, recv = 0, echoq = 0;
    ulong rtt = 0, min = 0, max = 0, total = 0;
    ulong startsec = 0, startms = 0;
    struct netaddr target;
    struct packet *pkt = NULL;
    char str[50];

    /* Output help, if '--help' argument was supplied */
    if (nargs == 2 && strncmp(args[1], "--help", 7) == 0)
    {
        printf("Usage: ping <IP>\n\n");
        printf("Description:\n");
        printf("\tSend ICMP echo requests to network hosts\n");
        printf("Options:\n");
        printf("\t<IP>\t\tIP address\n");
        printf("\t-c count\tstop after sending count packets\n");
        printf
            ("\t-i interval\tsleep interval milliseconds between pings\n");
        printf("\t--help\t\tdisplay this help and exit\n");
        return OK;
    }

    /* Check for correct number of arguments */
    if (nargs < 2)
    {
        fprintf(stderr, "ping: too few arguments\n");
        fprintf(stderr, "Try 'ping --help' for more information\n");
        return SHELL_ERROR;
    }

    i = 1;
    while (i < nargs)
    {
        if (0 == strncmp(args[i], "-c", 3))
        {
            i++;
            if (i < nargs)
            {
                count = atoi(args[i]);
            }
            else
            {
                fprintf(stderr, "ping: -c requires integer argument\n");
                return SHELL_ERROR;
            }
        }
        else if (0 == strncmp(args[i], "-i", 3))
        {
            i++;
            if (i < nargs)
            {
                interval = atoi(args[i]);
            }
            else
            {
                fprintf(stderr, "ping: -i requires integer argument\n");
                return SHELL_ERROR;
            }
        }
        else if (SYSERR == dot2ipv4(args[i], &target))
        {
            fprintf(stderr, "ping: %s is not a valid IPv4 address.\n",
                    args[i]);
            return SHELL_ERROR;
        }
        i++;
    }

    netaddrsprintf(str, &target);
    if (0 == strncmp(str, "ERROR", 6))
    {
        fprintf(stderr, "ping: destination IP address required.\n");
        return SHELL_ERROR;
    }
    printf("PING %s\n", str);

    echoq = echoQueueAlloc();
    if (SYSERR == echoq)
    {
        printf("...No free echo queues!\n");
        return SHELL_ERROR;
    }

    startsec = clktime;
    startms = clkticks;

    for (i = 0; i < count; i++)
    {
        // Send ping packet
        if (SYSERR == icmpEchoRequest(&target, gettid(), i))
        {
            printf("...Failed to reach %s\n", str);
            return SHELL_ERROR;
        }

        sleep(interval);
        if (NOMSG != recvclr())
        {
            // pick reply packets off of the queue
            pkt = echoQueueGet(echoq);
            while ((NULL != (ulong)pkt) && (SYSERR != (ulong)pkt))
            {
                rtt = echoTripTime(pkt);
                total += rtt;
                if ((rtt < min) || (0 == min))
                {
                    min = rtt;
                }
                if (rtt > max)
                {
                    max = rtt;
                }

                echoPrintPkt(pkt, rtt);
                netFreebuf(pkt);
                recv++;
                pkt = echoQueueGet(echoq);
            }
        }
    }
    echoQueueDealloc(echoq);

    netaddrsprintf(str, &target);
    printf("--- %s ping statistics ---\n", str);
    printf("%d packets transmitted, %d received,", count, recv);
    printf(" %d%% packet loss,", (count - recv) * 100 / count);
    printf(" time %dms\n", (clktime - startsec) * 1000 +
           ((clkticks - startms) * 1000) / CLKTICKS_PER_SEC);
    printf("rtt min/avg/max = %d.%03d/", min / 1000, min % 1000);
    if (0 != recv)
    {
        printf("%d.%03d/", (total / recv) / 1000, (total / recv) % 1000);
    }
    else
    {
        printf("-/");
    }
    printf("%d.%03d ms\n", max / 1000, max % 1000);

    return SHELL_OK;
}
Esempio n. 5
0
/**
 * @ingroup shell
 *
 * Shell command (nc).
 * @param nargs  number of arguments in args array
 * @param args   array of arguments
 * @return 0 for success, 1 for error
 */
shellcmd xsh_nc(int nargs, char *args[])
{
    int a;
    ushort port;
    bool listen = FALSE;
    struct netaddr dst;
    struct netaddr src;
    tid_typ recvthr;
    tid_typ sendthr;
    int msg = 0;
    int dev;

    /* Output help, if '--help' argument was supplied */
    if (nargs == 2 && 0 == strncmp(args[1], "--help", 7))
    {
        usage(args[0]);
        return 0;
    }

    port = 0;
    dst.type = NULL;
    src.type = NULL;

    /* Parse arguments */
    for (a = 1; a < nargs; a++)
    {
        if (args[a][0] != '-')
        {
            if (!listen && NULL == dst.type)
            {
                if (!isdigit(args[a][0]))
                {
                    return argError(args[a]);
                }
                dot2ipv4(args[a], &dst);
            }
            else if (listen && NULL == src.type)
            {
                if (!isdigit(args[a][0]))
                {
                    return argError(args[a]);
                }
                dot2ipv4(args[a], &src);
            }
            else if (NULL == port)
            {
                if (!isdigit(args[a][0]))
                {
                    return argError(args[a]);
                }
                port = atoi(args[a]);
            }
        }
        else
        {
            switch (args[a][1])
            {
                /* Listen on port */
            case 'l':
                listen = TRUE;
                break;
                /* Source IP */
            case 's':
                a++;
                if (a >= nargs || !isdigit(args[a][0]))
                {
                    return argError(args[a - 1]);
                }
                dot2ipv4(args[a], &src);
                break;
            default:
                return argError(args[a]);
            }
        }
    }

    /* Verify arguments */
    if (NULL == src.type)
    {
        fprintf(stderr, "Source/listen IP address required\n");
        return 1;
    }
    if (NULL == port)
    {
        fprintf(stderr, "Invalid port\n");
        return 1;
    }
    if (!listen && NULL == dst.type)
    {
        fprintf(stderr, "Remote IP address required\n");
        return 1;
    }

    /* Allocate a TCP device */
#ifdef NTCP
    dev = tcpAlloc();
#else
    dev = SYSERR;
#endif                          /* NTCP */
    if (SYSERR == dev)
    {
        return connError();
    }

    if (listen)
    {
        if (SYSERR == open(dev, &src, NULL, port, NULL, TCP_PASSIVE))
        {
            close(dev);
            return connError();
        }
    }
    else
    {
        if (SYSERR == open(dev, &src, &dst, NULL, port, TCP_ACTIVE))
        {
            close(dev);
            return connError();
        }
    }

    recvthr =
        create(ncRecv, SHELL_CMDSTK, SHELL_CMDPRIO, "nc_recv", 1, dev);
    sendthr =
        create(ncSend, SHELL_CMDSTK, SHELL_CMDPRIO, "nc_send", 1, dev);
    if ((SYSERR == recvthr) || (SYSERR == sendthr))
    {
        kill(recvthr);
        kill(sendthr);
        close(dev);
        fprintf(stderr, "Failed to spawn threads");
        return 1;
    }
    thrtab[recvthr].fdesc[0] = stdin;
    thrtab[recvthr].fdesc[1] = stdout;
    thrtab[recvthr].fdesc[2] = stderr;
    thrtab[sendthr].fdesc[0] = stdin;
    thrtab[sendthr].fdesc[1] = stdout;
    thrtab[sendthr].fdesc[2] = stderr;

    /* Start both threads */
    while (recvclr() != NOMSG);
    ready(recvthr, RESCHED_YES);
    ready(sendthr, RESCHED_NO);

    /* Wait for one thread to die */
    while ((msg != recvthr) && (msg != sendthr))
    {
        msg = receive();
    }
    sleep(10);

    /* Kill both threads */
    kill(recvthr);
    kill(sendthr);

    close(dev);
    return 0;
}
Esempio n. 6
0
/**
 * @ingroup shell
 *
 * Shell command (route) displays routing information.
 * @param nargs number of arguments
 * @param args  array of arguments
 * @return non-zero value on error
 */
shellcmd xsh_route(int nargs, char *args[])
{
    int i;
    char c[32];
    device *pdev;
    struct netif *netptr;

    struct netaddr dst;
    struct netaddr mask;
    struct netaddr gateway;

    /* Check for correct number of arguments */
    if (nargs > 6)
    {
        fprintf(stderr, "%s: too many arguments\n", args[0]);
        fprintf(stderr, "Try '%s --help' for more information\n",
                args[0]);
        return SYSERR;
    }

    /* Output help, if '--help' argument was supplied */
    if (nargs == 2 && strcmp(args[1], "--help") == 0)
    {
        printf("\nUsage: %s ", args[0]);
        printf("[add <DESTINATION> <GATEWAY> <MASK> <INTERFACE>] ");
        printf("[del <DESTINATION>]\n\n");
        printf("Description:\n");
        printf("\tDisplays routing table\n");
        printf("Options:\n");
        printf("\tadd <DESTINATION> <GATEWAY> <MASK> <INTERFACE>\n");
        printf("\t\t\t\tadd route entry into table.\n");
        printf("\t\t\t\t(<INTERFACE> must be in all caps.)\n");
        printf("\tdel <DESTINATION>");
        printf("\tdelete route entry from table.\n");
        printf("\t--help\t\t\tdisplay this help and exit\n");
        return OK;
    }

    if (nargs == 6 && strcmp(args[1], "add") == 0)
    {
        /* Parse destination */
        if (strcmp(args[2], "default") == 0)
        {
            args[2] = "";
        }
        if (SYSERR == dot2ipv4(args[2], &dst))
        {
            fprintf(stderr, "%s is not a valid IPv4 address.\n", args[2]);
            return SYSERR;
        }

        /* Parse gateway */
        if (SYSERR == dot2ipv4(args[3], &gateway))
        {
            fprintf(stderr, "%s is not a valid IPv4 address.\n", args[3]);
            return SYSERR;
        }

        /* Parse mask */
        if (SYSERR == dot2ipv4(args[4], &mask))
        {
            fprintf(stderr, "%s is not a valid IPv4 address mask.\n",
                    args[4]);
            return SYSERR;
        }

        /* Parse interface */
#if NNETIF
        for (i = 0; i < NNETIF; i++)
        {
            if (NET_ALLOC == netiftab[i].state)
            {
                netptr = &netiftab[i];
                pdev = (device *)&devtab[netptr->dev];
                if (strcmp(pdev->name, args[5]) == 0)
                {
                    if (SYSERR == rtAdd(&dst, &gateway, &mask, netptr))
                    {
                        fprintf(stderr, "Failed to add route.\n");
                        return SYSERR;
                    }
                    return OK;
                }
            }
        }
#endif
        fprintf(stderr, "%s is not a valid network interface.\n",
                args[5]);
        return SYSERR;
    }
    else if (nargs == 3 && strcmp(args[1], "del") == 0)
    {
        /* Parse destination */
        if (strcmp(args[2], "default") == 0)
        {
            args[2] = "";
        }
        if (SYSERR == dot2ipv4(args[2], &dst))
        {
            fprintf(stderr, "%s is not a valid IPv4 address.\n", args[2]);
            return SYSERR;
        }

        if (SYSERR == rtRemove(&dst))
        {
            fprintf(stderr, "Failed to delete route.\n");
            return SYSERR;
        }
        return OK;
    }

    printf
        ("Destination     Gateway         Mask            Interface\r\n");

    for (i = 0; i < RT_NENTRY; i++)
    {
        if (RT_USED == rttab[i].state)
        {
            if (0 == rttab[i].masklen)
                sprintf(c, "default");
            else
                netaddrsprintf(c, &rttab[i].dst);
            printf("%-16s", c);

            netaddrsprintf(c, &rttab[i].gateway);
            if (strcmp(c, "NULL") == 0)
                sprintf(c, "*");
            printf("%-16s", c);

            netaddrsprintf(c, &rttab[i].mask);
            printf("%-16s", c);

            netptr = rttab[i].nif;
            pdev = (device *)&devtab[netptr->dev];
            printf("%s\r\n", pdev->name);
        }
    }

    return 0;
}
Esempio n. 7
0
/**
 * Shell command for VoIP functionality.
 * @param nargs number of arguments
 * @param args  array of arguments
 * @return OK for success, SYSERR for syntax error
 */
shellcmd xsh_voip(int nargs, char *args[])
{
    int i, rxPort = UDP_PORT, txPort = UDP_PORT;
    ushort uart = NULL, udpRx = NULL, udpTx = NULL;
    ushort mode = MODE_SERIAL, check = CHECK_BASIC;
    struct netaddr *localhost;
    struct netaddr host;
#ifdef ELOOP
    struct netaddr mask;
#endif
    struct netif *netptr;
    struct thrent *thrptr;

    if (nargs < 2)
    {
        fprintf(stderr, "%s: too few arguments\n", args[0]);
        fprintf(stderr, "Try '%s --help' for more information\n",
                args[0]);
        return SYSERR;
    }
    else if (nargs == 2 && strncmp(args[1], "--help", 6) == 0)
    {
        printf
            ("\nUsage: %s [-p <rx port> <tx port>] [-s] [serial] [localhost] [IP address]\n",
             args[0]);
        printf("Description:\n");
        printf("\tUses the second serial port and the network to ");
        printf("transmit and receive audio.\n");
        printf("Options:\n");
        printf
            ("\t-p\t\tSpecify UDP receive and transmit port numbers.\n");
        printf("\t-s\t\tEmbed sequence information in each packet.\n");
        printf("\tserial\t\tOperate in serial loopback mode.\n");
        printf("\tlocalhost\tOperate in network loopback mode.\n");
        printf("\tIP address\tSend and receive from this IP address.\n");
        return OK;
    }
    else
    {
        for (i = 1; i < nargs; i++)
        {
            if (strncmp(args[i], "-s", 2) == 0)
            {
                check = CHECK_SEQ;
            }
            else if (strncmp(args[i], "-p", 2) == 0)
            {
                if ((i + 2) < nargs)
                {
                    i++;
                    rxPort = atol(args[i]);
                    i++;
                    txPort = atol(args[i]);
                }
                else
                {
                    fprintf(stderr,
                            "Insufficient number of arguments for port numbers.\n");
                    return SYSERR;
                }
            }
            else if (strncmp(args[i], "serial", 6) == 0)
            {
                mode = MODE_SERIAL;
            }
            else if (strncmp(args[i], "localhost", 9) == 0)
            {
                mode = MODE_LOCAL;
            }
            else if (SYSERR != dot2ipv4(args[i], &host))
            {
                mode = MODE_IP;
            }
            else
            {
                fprintf(stderr,
                        "Failed to parse destination IP address.\n");
                return SYSERR;
            }
        }
    }

    enable();

#ifdef TTY1
    /* Kill the SHELL1 thread */
    for (i = 0; i < NTHREAD; i++)
    {
        thrptr = &thrtab[i];

        if (thrptr->state == THRFREE)
        {
            continue;
        }

        if (0 == strncmp(thrptr->name, "SHELL1", 6))
        {
            kill(i);
        }
    }

    /* Close TTY1 so we can use SERIAL1 */
    close(TTY1);
#else
    thrptr = NULL;
#endif                          /* TTY1 */

#ifdef SERIAL1
    uart = SERIAL1;
#else
    uart = SYSERR;
#endif                          /* SERIAL1 */
    if (SYSERR == (short)uart)
    {
        fprintf(stderr, "Failed to select a uart device.");
        return SYSERR;
    }

    switch (mode)
    {
    case MODE_SERIAL:
        ready(create
              ((void *)serial_loop, INITSTK, 20, "voip-serial", 1, uart),
              RESCHED_YES);
        return OK;
#ifdef ELOOP
    case MODE_LOCAL:
        if (SYSERR == open(ELOOP))
        {
            fprintf(stderr, "Failed to open loopback device.");
            return SYSERR;
        }
        dot2ipv4("127.0.0.1", &host);
        localhost = &host;
        dot2ipv4("255.255.255.0", &mask);
        if (SYSERR == netUp(ELOOP, &host, &mask, NULL))
        {
            close(ELOOP);
            fprintf(stderr,
                    "Failed to bring up network on loopback device.\n");
            return SYSERR;
        }
        break;
#endif                          /* ELOOP */
    case MODE_IP:
        netptr = netLookup((ethertab[0].dev)->num);
        if (NULL == netptr)
        {
            fprintf(stderr, "No network interface found.\n");
            return SYSERR;
        }
        localhost = &(netptr->ip);
        srand(localhost->addr[3]);      /* Seed the random number generator */
        break;
    default:
        return SYSERR;
    }

#ifdef NUDP
    if (UDP_PORT == rxPort && UDP_PORT == txPort)
    {
        /* If both ports are the default, use one UDP device */
        udpRx = udpAlloc();
        udpTx = udpRx;
    }
    else
    {
        /* Otherwise, use two UDP devices */
        udpRx = udpAlloc();
        udpTx = udpAlloc();
    }
#else
    udpRx = SYSERR;
    udpTx = SYSERR;
#endif                          /* NUDP */
    if (SYSERR == (short)udpRx || SYSERR == (short)udpTx)
    {
        fprintf(stderr, "Unable to allocate a UDP device.\n");
        return SYSERR;
    }

    if (udpRx == udpTx)
    {
        if (SYSERR == open(udpRx, localhost, &host, rxPort, txPort))
        {
            fprintf(stderr, "Failed to open UDP device.\n");
            return SYSERR;
        }
        printf("Opened a single UDP device.\n");
    }
    else
    {
        if (SYSERR == open(udpRx, localhost, NULL, rxPort, NULL))
        {
            fprintf(stderr, "Failed to open UDP device.\n");
            return SYSERR;
        }
        if (SYSERR == open(udpTx, localhost, &host, NULL, txPort))
        {
            fprintf(stderr, "Failed to open UDP device.\n");
            return SYSERR;
        }
        printf("Opened two UDP devices.\n");
    }

    switch (check)
    {
    case CHECK_BASIC:
        ready(create
              ((void *)basic_send, INITSTK, 20, "voip-send", 2, uart,
               udpTx), RESCHED_YES);
        ready(create
              ((void *)basic_receive, INITSTK, 20, "voip-receive", 2,
               uart, udpRx), RESCHED_YES);
        break;
    case CHECK_SEQ:
#ifdef NUDP
        control(udpRx, UDP_CTRL_SETFLAG, UDP_FLAG_NOBLOCK, NULL);
        control(udpTx, UDP_CTRL_SETFLAG, UDP_FLAG_NOBLOCK, NULL);
#endif                          /* NUDP */
        ready(create
              ((void *)seq_send, INITSTK, 20, "voip-send", 2, uart,
               udpTx), RESCHED_YES);
        ready(create
              ((void *)seq_receive, INITSTK, 20, "voip-receive", 2, uart,
               udpRx), RESCHED_YES);
        break;
    }
    return OK;
}