Exemple #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];
}
Exemple #2
0
/**
 * HTTP server thread
 * @param host IP address of interface on which to listen
 * @param gentcpdev the allocated tcp device for general listening
 * @return OK or SYSERR
 */
thread httpServer(int netDescrp, int gentcpdev)
{
    tid_typ shelltid, killtid;
    int tcpdev, httpdev;
    char thrname[TNMLEN];
    bool noGenHTTP;
    struct netaddr *host;
    struct netif *nif;

    enable();

    noGenHTTP = FALSE;
    wait(maxhttp);              /* Make sure max HTTP threads not reached */

    /* Allocate HTTP device */
    httpdev = httpAlloc();

    /* Received bad http device, close out allocated resources */
    if (isbadhttp(httpdev))
    {
        printf("failed to allocate proper HTTP device\n");
        signal(maxhttp);
        return SYSERR;
    }

    /* Back up the general tcpdev number */
    tcpdev = gentcpdev;

    /* Look up the network descriptor */
    nif = netLookup(netDescrp);
    if (SYSERR == (int)nif)
    {
        fprintf(stderr, "%s is not associated with an active network",
                devtab[netDescrp].name);
        fprintf(stderr, " interface.\n");
        return SYSERR;
    }
    host = &(nif->ip);

    /* Open HTTP device */
    if (SYSERR == (long)open(httpdev, tcpdev))
    {
        fprintf(stderr, "httpOpen SYSERR\n");
        close(tcpdev);
        close(httpdev);
        return SYSERR;
    }

    /* Create web shell */
    sprintf(thrname, "XWebShell_%d\0", (devtab[tcpdev].minor));
    shelltid = create((void *)shell, INITSTK, INITPRIO, thrname, 3,
                      httpdev, httpdev, DEVNULL);
    if (isbadtid(shelltid))
    {
        fprintf(stderr, "shell creation bad tid\n");
        close(httpdev);
        close(tcpdev);
        return SYSERR;
    }

    /* Spawn thread that will wait for kill httpserver thread signal */
    sprintf(thrname, "XWebKillerD_%d\0", (devtab[tcpdev].minor));
    killtid = create((void *)killHttpServer, INITSTK, INITPRIO, thrname,
                     3, httpdev, shelltid, tcpdev);

    /* Ready spawned threads */
    ready(shelltid, RESCHED_NO);
    ready(killtid, RESCHED_NO);

    /* Open TCP device */
    if (SYSERR ==
        (long)open(tcpdev, host, NULL, HTTP_LOCAL_PORT, NULL,
                   TCP_PASSIVE))
    {
        int temp;
        sleep(TCP_TWOMSL + 500);
        if (SYSERR ==
            (temp = (long)open(tcpdev, host, NULL, HTTP_LOCAL_PORT, NULL,
                               TCP_PASSIVE)))
        {
            fprintf(CONSOLE, "open returns: %d\n", temp);
            fprintf(stderr, "tcpOpen SYSERR, devnum: %d\n", tcpdev);
            kill(shelltid);
            close(tcpdev);
            close(httpdev);
            return SYSERR;
        }
        fprintf(CONSOLE, "open returns: %d\n", temp);
    }

    /* Allocate TCP device */
    gentcpdev = tcpAlloc();
    if (isbadtcp(gentcpdev))
    {
        /* Wait for a free http device */
        wait(maxhttp);

        /* Acquire a TCP device through allocation */
        while ((ushort)SYSERR == (gentcpdev = tcpAlloc()))
        {
            /* Do nothing, yield processor */
            yield();
        }

        /* Everything acquired, spawn general http device listener */
        if (semcount(activeXWeb) <= 0)
        {
            sprintf(thrname, "XWeb_%d\0", (devtab[gentcpdev].minor));
            ready(create((void *)httpServer, INITSTK, INITPRIO,
                         thrname, 2, netDescrp, gentcpdev), RESCHED_NO);
        }

        /* Did not consume http device, just waited for availability */
        signal(maxhttp);
    }
    else
    {
        sprintf(thrname, "XWeb_%d\0", (devtab[gentcpdev].minor));
        ready(create((void *)httpServer, INITSTK, INITPRIO,
                     thrname, 2, netDescrp, gentcpdev), RESCHED_NO);
    }

    return OK;
}
Exemple #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;
}
Exemple #4
0
/**
 * @ingroup dhcpc
 *
 * DHCP (Dynamic Host Configuration Protocol) client for IPv4 autoconfiguration.
 *
 * TODO: This function returns immediately once the IP address has been
 * assigned.  It does not handle renewing leases.
 *
 * @param[in] descrp
 *      Device descriptor for the network device on which to open the DHCP
 *      client on.  This must be a network device that is open but has no
 *      network interface brought up on it.
 * @param[in] timeout
 *      Seconds to wait before timing out (must be a positive integer).
 * @param[out] data
 *      On success, this structure is filled in with the information about the
 *      IPv4 configuration.  At least the @ref dhcpData::ip "ip" and @ref
 *      dhcpData::mask "mask" members will be valid.  The @ref dhcpData::gateway
 *      "gateway", @ref dhcpData::bootfile "bootfile", and @ref
 *      dhcpData::next_server "next_server" members are optional and will be
 *      left as all 0's if not provided.
 *
 * @return
 *      ::OK if successful; ::SYSERR if sending a DHCPDISCOVER packet failed or
 *      if a parameter was invalid; ::TIMEOUT if timed out.
 */
syscall dhcpClient(int descrp, uint timeout, struct dhcpData *data)
{
    int retval;
    uint recvTimeout = 2000;  /* Milliseconds to wait before timing out a
                                 given receive (not the whole client)  */
    uint delay = 1000;  /* Milliseconds to wait after non-timeout error */
    ulong starttime = clktime;

    /* Check for invalid parameters.  */
#if NETHER
    if (descrp < ETH0 || descrp >= ETH0 + NETHER)
#endif
    {
        DHCP_TRACE("Bad device descriptor.\n");
        return SYSERR;
    }

    if (0 == timeout)
    {
        DHCP_TRACE("Timeout cannot be zero.\n");
        return SYSERR;
    }

    if (NULL == data)
    {
        DHCP_TRACE("No data buffer provided.\n");
        return SYSERR;
    }

    if (NULL != netLookup(descrp))
    {
        DHCP_TRACE("Network interface is up on device.\n");
        return SYSERR;
    }

    bzero(data, sizeof(*data));
    data->state = DHCPC_STATE_INIT;

    while (clktime <= starttime + timeout)
    {
        switch (data->state)
        {
        case DHCPC_STATE_INIT:
            /* Initialize transfer data.  */

            data->cxid = rand();          /* Choose random context ID */
            data->starttime = clktime;    /* Set starting time   */

            data->clientIpv4Addr = 0;     /* Client IP address is unknown  */
            data->serverIpv4Addr = 0;     /* Server IP address is unknown  */

            /* Client hardware address is known; get it from network device.  */
            if (SYSERR == control(descrp, NET_GET_HWADDR,
                                  (long)data->clientHwAddr, 0))
            {
                DHCP_TRACE("Failed to get client hardware address");
                return SYSERR;
            }

            /* Server hardware address is unknown  */
            bzero(data->serverHwAddr, ETH_ADDR_LEN);

            /* Broadcast DHCPDISCOVER.  */
            DHCP_TRACE("Sending DHCPDISCOVER");
            retval = dhcpSendRequest(descrp, data);

            if (OK == retval)
            {
                DHCP_TRACE("Sent DHCPDISCOVER");
                data->state = DHCPC_STATE_SELECTING;
            }
            else
            {
                DHCP_TRACE("Failed to send DHCPDISCOVER; returning failure");
                return SYSERR;
            }
            break;

        case DHCPC_STATE_SELECTING:
            /* Wait for DHCPOFFER from any server.  */
            DHCP_TRACE("Waiting for DHCPOFFER");
            retval = dhcpRecvReply(descrp, data, recvTimeout);

            if (OK != retval)
            {
                DHCP_TRACE("Failed to receive DHCPOFFER");
                data->state = DHCPC_STATE_INIT;
                if (TIMEOUT != retval)
                {
                    sleep(delay);
                }
                break;
            }

            /* Send DHCPREQUEST to the server based on the DHCPOFFER.  */
            DHCP_TRACE("Sending DHCPREQUEST");
            retval = dhcpSendRequest(descrp, data);

            if (OK == retval)
            {
                DHCP_TRACE("Sent DHCPREQUEST");
                data->state = DHCPC_STATE_REQUESTING;
            }
            else
            {
                DHCP_TRACE("Failed to send DHCPREQUEST");
                data->state = DHCPC_STATE_INIT;
                sleep(delay);
            }
            break;

        case DHCPC_STATE_REQUESTING:
            /* Wait for DHCPACK from the server to whom we sent the DHCPREQUEST.
             * */
            DHCP_TRACE("Waiting for DHCPACK");
            retval = dhcpRecvReply(descrp, data, recvTimeout);

            if (OK == retval)
            {
                DHCP_TRACE("Received DHCPACK");
                data->state = DHCPC_STATE_BOUND;
                return OK;
            }
            else
            {
                DHCP_TRACE("Failed to receive DHCPACK");
                data->state = DHCPC_STATE_INIT;
                if (TIMEOUT != retval)
                {
                    sleep(delay);
                }
            }
            break;
        }
    }
    return TIMEOUT;
}
Exemple #5
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;
}
Exemple #6
0
static void kexec_from_network(int netdev, char *boot)
{
#if defined(WITH_DHCPC) && NETHER != 0
    struct dhcpData data;
    int result;
    const struct netaddr *gatewayptr;
    struct netif *nif;
    void *kernel;
    uint size;
    char str_ip[20];
    char str_mask[20];
    char str_gateway[20];
    const char *netdevname = devtab[netdev].name;

    /* Bring network interface (if any) down.  */
    netDown(netdev);

    /* Run DHCP client on the device for at most 10 seconds.  */
    printf("Running DHCP on %s\n", netdevname);
    result = dhcpClient(netdev, 10, &data);
    if (OK != result)
    {
        fprintf(stderr, "ERROR: DHCP failed.\n");
        return;
    }

    /* Ensure the DHCP server provided the boot filename and TFTP server IP
     * address.  */
    if (('\0' == data.bootfile[0] || 0 == data.next_server.type) && boot == NULL)
    {
        fprintf(stderr, "ERROR: DHCP server did not provide boot file "
                "and TFTP server address.\n");
        return;
    }

    /* Bring up the network interface.  */
    netaddrsprintf(str_ip, &data.ip);
    netaddrsprintf(str_mask, &data.mask);
    if (0 != data.gateway.len)
    {
        netaddrsprintf(str_gateway, &data.gateway);
        printf("Bringing up %s as %s with mask %s (gateway %s)\n",
               netdevname, str_ip, str_mask, str_gateway);
        gatewayptr = &data.gateway;
    }
    else
    {
        printf("Bringing up %s as %s with mask %s (no gateway)\n",
               netdevname, str_ip, str_mask);
        gatewayptr = NULL;
    }
    result = netUp(netdev, &data.ip, &data.mask, gatewayptr);
    if (OK != result)
    {
        fprintf(stderr, "ERROR: failed to bring up %s.\n", netdevname);
        return;
    }
    nif = netLookup(netdev);

    /* Download new kernel using TFTP.  */
    netaddrsprintf(str_ip, &data.next_server);
	 if (boot == NULL) {
    	printf("Downloading bootfile \"%s\" from TFTP server %s\n",
      	     data.bootfile, str_ip);
    	kernel = (void*)tftpGetIntoBuffer(data.bootfile, &nif->ip,
                                        &data.next_server, &size);
	 }else {
    	printf("Downloading bootfile \"%s\" from TFTP server %s\n",
      	     boot, str_ip);
    	kernel = (void*)tftpGetIntoBuffer(boot, &nif->ip,
                                        &data.next_server, &size);
	 }

    if (SYSERR == (int)kernel)
    {
        fprintf(stderr, "ERROR: TFTP failed.\n");
        return;
    }

    /* Execute the new kernel.  */
    printf("Executing new kernel (size=%u)\n", size);
    sleep(100);  /* Wait just a fraction of a second for printf()s to finish
                    (no guarantees though).  */
    kexec(kernel, size);

    fprintf(stderr, "ERROR: kexec() returned!\n");

#else /* WITH_DHCPC && NETHER != 0 */
    fprintf(stderr,
            "ERROR: Network boot is not supported in this configuration.\n"
            "       Please make sure you have enabled one or more network\n"
            "       devices, along with the DHCP and TFTP clients.\n");
#endif /* !(WITH_DHCPC && NETHER != 0) */
}