Exemplo n.º 1
0
void tftpd_general(void *p_info, int socket_ID)
{
    connect_info_S *p_con_info=(connect_info_S *)p_info;
    FILE *f;
    int result=255;

    if (p_con_info->job==RRQ)
    {
        f=fopen(p_con_info->p_name,"rb");
        if(f == NULL)
        {
            nak(socket_ID, &p_con_info->adresse, errno,strerror(errno));
            tftp_free(p_con_info->p_name);
            tftp_free(p_con_info);
            close(socket_ID);
            return ;
        }
        result=tftp_send(&p_con_info->adresse,p_con_info->p_name,"octet",0,TFTPsread,f);
        fclose(f);
    }
    else if (p_con_info->job==WRQ)
    {
        result=tftp_receive(&p_con_info->adresse,p_con_info->p_name,"octet",0,TFTPswrite,f);
    }
    else
    {
        DEBUG_MSG("TFTP op code is not correct \n");
    }

    if (result!=0) DEBUG_MSG("TFTP error\n");
    tftp_free(p_con_info->p_name);
    tftp_free(p_con_info);
    return ;
}
Exemplo n.º 2
0
static void
tftp_recvfile(int peer, const char *mode)
{
	uint16_t block;
	struct timeval now1, now2;
	struct tftp_stats ts;

	gettimeofday(&now1, NULL);
	if (debug&DEBUG_SIMPLE)
		tftp_log(LOG_DEBUG, "Receiving file");

	write_init(0, file, mode);

	block = 0;
	tftp_receive(peer, &block, &ts, NULL, 0);

	write_close();
	gettimeofday(&now2, NULL);

	if (debug&DEBUG_SIMPLE) {
		double f;
		if (now1.tv_usec > now2.tv_usec) {
			now2.tv_usec += 1000000;
			now2.tv_sec--;
		}

		f = now2.tv_sec - now1.tv_sec +
		    (now2.tv_usec - now1.tv_usec) / 100000.0;
		tftp_log(LOG_INFO,
		    "Download of %jd bytes in %d blocks completed after %0.1f seconds\n",
		    (intmax_t)ts.amount, block, f);
	}

	return;
}
Exemplo n.º 3
0
/*
 * Receive a file.
 */
void
recvfile(int peer, char *port, int fd, char *name, char *mode)
{
	struct tftphdr *rp;
	uint16_t block;
	char recvbuffer[MAXPKTSIZE];
	int n, i;
	struct tftp_stats tftp_stats;

	stats_init(&tftp_stats);

	rp = (struct tftphdr *)recvbuffer;

	if (port == NULL) {
		struct servent *se;
		se = getservbyname("tftp", "udp");
		((struct sockaddr_in *)&peer_sock)->sin_port = se->s_port;
	} else
		((struct sockaddr_in *)&peer_sock)->sin_port =
		    htons(atoi(port));

	for (i = 0; i < 12; i++) {
		struct sockaddr_storage from;

		/* Tell the other side what we want to do */
		if (debug&DEBUG_SIMPLE)
			printf("Requesting %s\n", name);

		n = send_rrq(peer, name, mode);
		if (n > 0) {
			printf("Cannot send RRQ packet\n");
			return;
		}

		/*
		 * The first packet we receive has the new destination port
		 * we have to send the next packets to.
		 */
		n = receive_packet(peer, recvbuffer,
		    MAXPKTSIZE, &from, timeoutpacket);

		/* We got something useful! */
		if (n >= 0) {
			((struct sockaddr_in *)&peer_sock)->sin_port =
			    ((struct sockaddr_in *)&from)->sin_port;
			break;
		}

		/* We should retry if this happens */
		if (n == RP_TIMEOUT) {
			printf("Try %d, didn't receive answer from remote.\n",
			    i + 1);
			continue;
		}

		/* Otherwise it is a fatal error */
		break;
	}
	if (i == 12) {
		printf("Transfer timed out.\n");
		return;
	}
	if (rp->th_opcode == ERROR) {
		tftp_log(LOG_ERR, "Error code %d: %s", rp->th_code, rp->th_msg);
		return;
	}

	if (write_init(fd, NULL, mode) < 0) {
		warn("write_init");
		return;
	}

	/*
	 * If the first packet is an OACK packet instead of an DATA packet,
	 * handle it different.
	 */
	if (rp->th_opcode == OACK) {
		if (!options_rfc_enabled) {
			printf("Got OACK while options are not enabled!\n");
			send_error(peer, EBADOP);
			return;
		}

		parse_options(peer, rp->th_stuff, n + 2);

		n = send_ack(peer, 0);
		if (n > 0) {
			printf("Cannot send ACK on OACK.\n");
			return;
		}
		block = 0;
		tftp_receive(peer, &block, &tftp_stats, NULL, 0);
	} else {
		block = 1;
		tftp_receive(peer, &block, &tftp_stats, rp, n);
	}

	write_close();
	if (tftp_stats.amount > 0)
		printstats("Received", verbose, &tftp_stats);
	return;
}