Example #1
0
static int
tftp_ack(int *err)
{
    struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data;
    // ACK last packet so server can shut down
    if (tftp_stream.packets_received > 0) {
        hdr->th_opcode = htons(ACK);
        hdr->th_block = htons((cyg_uint16)tftp_stream.last_good_block & 0xFFFF);
        if (__udp_sendto(tftp_stream.data, 4 /* FIXME */, 
                         &tftp_stream.from_addr, &tftp_stream.local_addr) < 0) {
            // Problem sending ACK
            *err = TFTP_NETERR;
            return -1;
        }
    }
    return 0;
}
Example #2
0
File: dns.c Project: perryhg/terkos
/* Send the query to the server and read the response back. Return -1
   if it fails, otherwise put the response back in msg and return the
   length of the response. */
static int 
send_recv(char * msg, int len, int msglen)
{
    struct dns_header *dns_hdr;
    int finished = false;
    int read = 0;

    dns_hdr = (struct dns_header *) msg;

    do { 
        int len_togo = len;
        struct timeval timeout;
        struct sockaddr_in local_addr, from_addr;

        memset((char *)&local_addr, 0, sizeof(local_addr));
        local_addr.sin_family = AF_INET;
        local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        local_addr.sin_port = htons(get_port++);

        if (__udp_sendto(msg, len_togo, &server, &local_addr) < 0)
            return -1;

        memset((char *)&from_addr, 0, sizeof(from_addr));

        timeout.tv_sec = CYGNUM_REDBOOT_NETWORKING_DNS_TIMEOUT;
        timeout.tv_usec = 0;

        read = __udp_recvfrom(msg, len, &from_addr, &local_addr, &timeout);
        if (read < 0)
            return -1;

        /* Reply to an old query. Ignore it */
        if (ntohs(dns_hdr->id) != (id-1)) {
            continue;
        }
        finished = true;
    } while (!finished);

    return read;
}
Example #3
0
int
tftp_stream_open(connection_info_t *info,
                 int *err)
{
    struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data;
    char *cp, *fp;
    char test_buf;

    if (!have_net || tftp_stream.open) {
        *err = TFTP_INVALID;  // Already open
        return -1;
    }

    // Create initial request
    hdr->th_opcode = htons(RRQ);  // Read file
    cp = (char *)&hdr->th_stuff;
    fp = info->filename;
    while (*fp) *cp++ = *fp++;
    *cp++ = '\0';
    // Since this is used for downloading data, OCTET (binary) is the
    // only mode that makes sense.
    fp = "OCTET";
    while (*fp) *cp++ = *fp++;
    *cp++ = '\0';

    memset((char *)&tftp_stream.local_addr, 0, sizeof(tftp_stream.local_addr));
    tftp_stream.local_addr.sin_family = AF_INET;
    tftp_stream.local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    tftp_stream.local_addr.sin_port = htons(get_port++);

    if (info->server->sin_port == 0) {
        info->server->sin_port = htons(TFTP_PORT);
    } else {
        info->server->sin_port = htons(info->server->sin_port);
    }

    // Send request - note: RFC 1350 (TFTP rev 2) indicates that this should be
    // only as long as required to hold the request, with the nul terminator.
    // Some servers silently go to lunch if the request is not the correct size.
    if (__udp_sendto(tftp_stream.data, cp-(char *)hdr, 
                     info->server, &tftp_stream.local_addr) < 0) {
        // Problem sending request
        *err = TFTP_NETERR;
        return -1;
    }

    tftp_stream.open = true;
    tftp_stream.avail = 0;
    tftp_stream.actual_len = -1;
    tftp_stream.last_good_block = 0;
    tftp_stream.total_timeouts = 0;
    tftp_stream.from_addr.sin_port = 0;
    tftp_stream.packets_received = 0;

    // Try and read the first byte [block] since no errors are
    // reported until then.
    if (tftp_stream_read(&test_buf, 1, err) == 1) {
        // Back up [rewind] over this datum
        tftp_stream.bufp--;
        tftp_stream.avail++;
        return 0;  // Open and first read successful
    } else {
        tftp_stream.open = false;
        return -1; // Couldn't read
    }
}