diff options
author | 2017-04-25 03:31:15 -0700 | |
---|---|---|
committer | 2017-05-22 06:48:08 +0000 | |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.c | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.c')
-rw-r--r-- | qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.c | 586 |
1 files changed, 0 insertions, 586 deletions
diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.c deleted file mode 100644 index c1197cf17..000000000 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.c +++ /dev/null @@ -1,586 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2008 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <tftp.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <sys/socket.h> - -#include <ethernet.h> -#include <ipv4.h> -#include <ipv6.h> -#include <udp.h> - -//#define __DEBUG__ - -#define MAX_BLOCKSIZE 1428 -#define BUFFER_LEN 256 - -#define ENOTFOUND 1 -#define EACCESS 2 -#define EBADOP 4 -#define EBADID 5 -#define ENOUSER 7 -//#define EUNDEF 0 -//#define ENOSPACE 3 -//#define EEXISTS 6 - -#define RRQ 1 -#define WRQ 2 -#define DATA 3 -#define ACK 4 -#define ERROR 5 -#define OACK 6 - -/* Local variables */ -static unsigned char packet[BUFFER_LEN]; -static unsigned char *buffer = NULL; -static unsigned short block = 0; -static unsigned short blocksize; -static char blocksize_str[6]; /* Blocksize string for read request */ -static int received_len = 0; -static unsigned int retries = 0; -static int huge_load; -static int len; -static int tftp_finished = 0; -static int lost_packets = 0; -static int tftp_errno = 0; -static int ip_version = 0; -static short port_number = -1; -static tftp_err_t *tftp_err; -static filename_ip_t *fn_ip; - -/** - * dump_package - Prints a package. - * - * @package: package which is to print - * @len: length of the package - */ -#ifdef __DEBUG__ - -static void dump_package(unsigned char *buffer, unsigned int len) -{ - int i; - - for (i = 1; i <= len; i++) { - printf("%02x%02x ", buffer[i - 1], buffer[i]); - i++; - if ((i % 16) == 0) - printf("\n"); - } - printf("\n"); -} -#endif - -/** - * send_rrq - Sends a read request package. - * - * @fd: Socket Descriptor - */ -static void send_rrq(int fd) -{ - int ip_len = 0; - int ip6_payload_len = 0; - unsigned short udp_len = 0; - unsigned char mode[] = "octet"; - char *ptr = NULL; - struct iphdr *ip = NULL; - struct ip6hdr *ip6 = NULL; - struct udphdr *udph = NULL; - struct tftphdr *tftp = NULL; - - memset(packet, 0, BUFFER_LEN); - - if (4 == ip_version) { - ip = (struct iphdr *) packet; - udph = (struct udphdr *) (ip + 1); - ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) - + strlen((char *) fn_ip->filename) + strlen((char *) mode) + 4 - + strlen("blksize") + strlen(blocksize_str) + 2; - fill_iphdr ((uint8_t *) ip, ip_len, IPTYPE_UDP, 0, - fn_ip->server_ip); - } - else if (6 == ip_version) { - ip6 = (struct ip6hdr *) packet; - udph = (struct udphdr *) (ip6 + 1); - ip6_payload_len = sizeof(struct udphdr) - + strlen((char *) fn_ip->filename) + strlen((char *) mode) + 4 - + strlen("blksize") + strlen(blocksize_str) + 2; - ip_len = sizeof(struct ip6hdr) + ip6_payload_len; - fill_ip6hdr ((uint8_t *) ip6, ip6_payload_len, IPTYPE_UDP, get_ipv6_address(), - &(fn_ip->server_ip6)); - - } - udp_len = htons(sizeof(struct udphdr) - + strlen((char *) fn_ip->filename) + strlen((char *) mode) + 4 - + strlen("blksize") + strlen(blocksize_str) + 2); - fill_udphdr ((uint8_t *) udph, udp_len, htons(2001), htons(69)); - - tftp = (struct tftphdr *) (udph + 1); - tftp->th_opcode = htons(RRQ); - - ptr = (char *) &tftp->th_data; - memcpy(ptr, fn_ip->filename, strlen((char *) fn_ip->filename) + 1); - - ptr += strlen((char *) fn_ip->filename) + 1; - memcpy(ptr, mode, strlen((char *) mode) + 1); - - ptr += strlen((char *) mode) + 1; - memcpy(ptr, "blksize", strlen("blksize") + 1); - - ptr += strlen("blksize") + 1; - memcpy(ptr, blocksize_str, strlen(blocksize_str) + 1); - - send_ip (fd, packet, ip_len); - -#ifdef __DEBUG__ - printf("tftp RRQ with %d bytes transmitted.\n", ip_len); -#endif - return; -} - -/** - * send_ack - Sends a acknowlege package. - * - * @blckno: block number - * @dport: UDP destination port - */ -static void send_ack(int fd, int blckno, unsigned short dport) -{ - int ip_len = 0; - int ip6_payload_len = 0; - unsigned short udp_len = 0; - struct iphdr *ip = NULL; - struct ip6hdr *ip6 = NULL; - struct udphdr *udph = NULL; - struct tftphdr *tftp = NULL; - - memset(packet, 0, BUFFER_LEN); - - if (4 == ip_version) { - ip = (struct iphdr *) packet; - udph = (struct udphdr *) (ip + 1); - ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) + 4; - fill_iphdr ((uint8_t *) ip, ip_len, IPTYPE_UDP, 0, - fn_ip->server_ip); - } - else if (6 == ip_version) { - ip6 = (struct ip6hdr *) packet; - udph = (struct udphdr *) (ip6 + 1); - ip6_payload_len = sizeof(struct udphdr) + 4; - ip_len = sizeof(struct ip6hdr) + ip6_payload_len; - fill_ip6hdr ((uint8_t *) ip6, ip6_payload_len, IPTYPE_UDP, get_ipv6_address(), - &(fn_ip->server_ip6)); - } - udp_len = htons(sizeof(struct udphdr) + 4); - fill_udphdr ((uint8_t *) udph, udp_len, htons(2001), htons(dport)); - - tftp = (struct tftphdr *) (udph + 1); - tftp->th_opcode = htons(ACK); - tftp->th_data = htons(blckno); - - send_ip(fd, packet, ip_len); - -#ifdef __DEBUG__ - printf("tftp ACK %d bytes transmitted.\n", ip_len); -#endif - - return; -} - -/** - * send_error - Sends an error package. - * - * @fd: Socket Descriptor - * @error_code: Used sub code for error packet - * @dport: UDP destination port - */ -static void send_error(int fd, int error_code, unsigned short dport) -{ - int ip_len = 0; - int ip6_payload_len = 0; - unsigned short udp_len = 0; - struct ip6hdr *ip6 = NULL; - struct iphdr *ip = NULL; - struct udphdr *udph = NULL; - struct tftphdr *tftp = NULL; - - memset(packet, 0, BUFFER_LEN); - - if (4 == ip_version) { - ip = (struct iphdr *) packet; - udph = (struct udphdr *) (ip + 1); - ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) + 5; - fill_iphdr ((uint8_t *) ip, ip_len, IPTYPE_UDP, 0, - fn_ip->server_ip); - } - else if (6 == ip_version) { - ip6 = (struct ip6hdr *) packet; - udph = (struct udphdr *) (ip6 + 1); - ip6_payload_len = sizeof(struct udphdr) + 5; - ip_len = sizeof(struct ip6hdr) + ip6_payload_len; - fill_ip6hdr ((uint8_t *) ip6, ip6_payload_len, IPTYPE_UDP, get_ipv6_address(), - &(fn_ip->server_ip6)); - } - udp_len = htons(sizeof(struct udphdr) + 5); - fill_udphdr ((uint8_t *) udph, udp_len, htons(2001), htons(dport)); - - tftp = (struct tftphdr *) (udph + 1); - tftp->th_opcode = htons(ERROR); - tftp->th_data = htons(error_code); - ((char *) &tftp->th_data)[2] = 0; - - send_ip(fd, packet, ip_len); - -#ifdef __DEBUG__ - printf("tftp ERROR %d bytes transmitted.\n", ip_len); -#endif - - return; -} - -static void print_progress(int urgent, int received_bytes) -{ - static unsigned int i = 1; - static int first = -1; - static int last_bytes = 0; - char buffer[100]; - char *ptr; - - // 1MB steps or 0x400 times or urgent - if(((received_bytes - last_bytes) >> 20) > 0 - || (i & 0x3FF) == 0 || urgent) { - if(!first) { - sprintf(buffer, "%d KBytes", (last_bytes >> 10)); - for(ptr = buffer; *ptr != 0; ++ptr) - *ptr = '\b'; - printf(buffer); - } - printf("%d KBytes", (received_bytes >> 10)); - i = 1; - first = 0; - last_bytes = received_bytes; - } - ++i; -} - -/** - * get_blksize tries to extract the blksize from the OACK package - * the TFTP returned. From RFC 1782 - * The OACK packet has the following format: - * - * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ - * | opc | opt1 | 0 | value1 | 0 | optN | 0 | valueN | 0 | - * +-------+---~~---+---+---~~---+---+---~~---+---+---~~---+---+ - * - * @param buffer the network packet - * @param len the length of the network packet - * @return the blocksize the server supports or 0 for error - */ -static int get_blksize(unsigned char *buffer, unsigned int len) -{ - unsigned char *orig = buffer; - /* skip all headers until tftp has been reached */ - buffer += sizeof(struct udphdr); - /* skip opc */ - buffer += 2; - while (buffer < orig + len) { - if (!memcmp(buffer, "blksize", strlen("blksize") + 1)) - return (unsigned short) strtoul((char *) (buffer + - strlen("blksize") + 1), - (char **) NULL, 10); - else { - /* skip the option name */ - buffer = (unsigned char *) strchr((char *) buffer, 0); - if (!buffer) - return 0; - buffer++; - /* skip the option value */ - buffer = (unsigned char *) strchr((char *) buffer, 0); - if (!buffer) - return 0; - buffer++; - } - } - return 0; -} - -/** - * Handle incoming tftp packets after read request was sent - * - * this function also prints out some status characters - * \|-/ for each packet received - * A for an arp packet - * I for an ICMP packet - * #+* for different unexpected TFTP packets (not very good) - * - * @param fd socket descriptor - * @param packet points to the UDP header of the packet - * @param len the length of the network packet - * @return ZERO if packet was handled successfully - * ERRORCODE if error occurred - */ -int32_t handle_tftp(int fd, uint8_t *pkt, int32_t packetsize) -{ - struct udphdr *udph; - struct tftphdr *tftp; - - /* buffer is only set if we are handling TFTP */ - if (buffer == NULL ) - return 0; - -#ifndef __DEBUG__ - print_progress(0, received_len); -#endif - udph = (struct udphdr *) pkt; - tftp = (struct tftphdr *) ((void *) udph + sizeof(struct udphdr)); - set_timer(TICKS_SEC); - -#ifdef __DEBUG__ - dump_package(pkt, packetsize); -#endif - - port_number = udph->uh_sport; - if (tftp->th_opcode == htons(OACK)) { - /* an OACK means that the server answers our blocksize request */ - blocksize = get_blksize(pkt, packetsize); - if (!blocksize || blocksize > MAX_BLOCKSIZE) { - send_error(fd, 8, port_number); - tftp_errno = -8; - goto error; - } - send_ack(fd, 0, port_number); - } else if (tftp->th_opcode == htons(ACK)) { - /* an ACK means that the server did not answers - * our blocksize request, therefore we will set the blocksize - * to the default value of 512 */ - blocksize = 512; - send_ack(fd, 0, port_number); - } else if ((unsigned char) tftp->th_opcode == ERROR) { -#ifdef __DEBUG__ - printf("tftp->th_opcode : %x\n", tftp->th_opcode); - printf("tftp->th_data : %x\n", tftp->th_data); -#endif - switch ( (uint8_t) tftp->th_data) { - case ENOTFOUND: - tftp_errno = -3; // ERROR: file not found - break; - case EACCESS: - tftp_errno = -4; // ERROR: access violation - break; - case EBADOP: - tftp_errno = -5; // ERROR: illegal TFTP operation - break; - case EBADID: - tftp_errno = -6; // ERROR: unknown transfer ID - break; - case ENOUSER: - tftp_errno = -7; // ERROR: no such user - break; - default: - tftp_errno = -1; // ERROR: unknown error - } - goto error; - } else if (tftp->th_opcode == DATA) { - /* DATA PACKAGE */ - if (block + 1 == tftp->th_data) { - ++block; - } - else if( block == 0xffff && huge_load != 0 - && (tftp->th_data == 0 || tftp->th_data == 1) ) { - block = tftp->th_data; - } - else if (tftp->th_data == block) { -#ifdef __DEBUG__ - printf - ("\nTFTP: Received block %x, expected block was %x\n", - tftp->th_data, block + 1); - printf("\b+ "); -#endif - send_ack(fd, tftp->th_data, port_number); - lost_packets++; - tftp_err->bad_tftp_packets++; - return 0; - } else if (tftp->th_data < block) { -#ifdef __DEBUG__ - printf - ("\nTFTP: Received block %x, expected block was %x\n", - tftp->th_data, block + 1); - printf("\b* "); -#endif - /* This means that an old data packet appears (again); - * this happens sometimes if we don't answer fast enough - * and a timeout is generated on the server side; - * as we already have this packet we just ignore it */ - tftp_err->bad_tftp_packets++; - return 0; - } else { - tftp_err->blocks_missed = block + 1; - tftp_err->blocks_received = tftp->th_data; - tftp_errno = -42; - goto error; - } - tftp_err->bad_tftp_packets = 0; - /* check if our buffer is large enough */ - if (received_len + udph->uh_ulen - 12 > len) { - tftp_errno = -2; - goto error; - } - memcpy(buffer + received_len, &tftp->th_data + 1, - udph->uh_ulen - 12); - send_ack(fd, tftp->th_data, port_number); - received_len += udph->uh_ulen - 12; - /* Last packet reached if the payload of the UDP packet - * is smaller than blocksize + 12 - * 12 = UDP header (8) + 4 bytes TFTP payload */ - if (udph->uh_ulen < blocksize + 12) { - tftp_finished = 1; - return 0; - } - /* 0xffff is the highest block number possible - * see the TFTP RFCs */ - - if (block >= 0xffff && huge_load == 0) { - tftp_errno = -9; - goto error; - } - } else { -#ifdef __DEBUG__ - printf("Unknown packet %x\n", tftp->th_opcode); - printf("\b# "); -#endif - tftp_err->bad_tftp_packets++; - return 0; - } - - return 0; - -error: -#ifdef __DEBUG__ - printf("\nTFTP errno: %d\n", tftp_errno); -#endif - tftp_finished = 1; - return tftp_errno; -} - -/** - * TFTP: This function handles situation when "Destination unreachable" - * ICMP-error occurs during sending TFTP-packet. - * - * @param err_code Error Code (e.g. "Host unreachable") - */ -void handle_tftp_dun(uint8_t err_code) -{ - tftp_errno = - err_code - 10; - tftp_finished = 1; -} - -/** - * TFTP: Interface function to load files via TFTP. - * - * @param _fn_ip contains the following configuration information: - * client IP, TFTP-server IP, filename to be loaded - * @param _buffer destination buffer for the file - * @param _len size of destination buffer - * @param _retries max number of retries - * @param _tftp_err contains info about TFTP-errors (e.g. lost packets) - * @param _mode NON ZERO - multicast, ZERO - unicast - * @param _blocksize blocksize for DATA-packets - * @return ZERO - error condition occurs - * NON ZERO - size of received file - */ -int tftp(filename_ip_t * _fn_ip, unsigned char *_buffer, int _len, - unsigned int _retries, tftp_err_t * _tftp_err, - int32_t _mode, int32_t _blocksize, int _ip_version) -{ - retries = _retries; - fn_ip = _fn_ip; - len = _len; - huge_load = _mode; - ip_version = _ip_version; - tftp_errno = 0; - tftp_err = _tftp_err; - tftp_err->bad_tftp_packets = 0; - tftp_err->no_packets = 0; - - /* Default blocksize must be 512 for TFTP servers - * which do not support the RRQ blocksize option */ - blocksize = 512; - - /* Preferred blocksize - used as option for the read request */ - if (_blocksize < 8) - _blocksize = 8; - else if (_blocksize > MAX_BLOCKSIZE) - _blocksize = MAX_BLOCKSIZE; - sprintf(blocksize_str, "%d", _blocksize); - - printf(" Receiving data: "); - print_progress(-1, 0); - - // Setting buffer to a non-zero address enabled handling of received TFTP packets. - buffer = _buffer; - - set_timer(TICKS_SEC); - send_rrq(fn_ip->fd); - - while (! tftp_finished) { - /* if timeout (no packet received) */ - if(get_timer() <= 0) { - /* the server doesn't seem to retry let's help out a bit */ - if (tftp_err->no_packets > 4 && port_number != -1 - && block > 1) { - send_ack(fn_ip->fd, block, port_number); - } - else if (port_number == -1 && block == 0 - && (tftp_err->no_packets&3) == 3) { - printf("\nRepeating TFTP read request...\n"); - send_rrq(fn_ip->fd); - } - tftp_err->no_packets++; - set_timer(TICKS_SEC); - } - - /* handle received packets */ - receive_ether(fn_ip->fd); - - /* bad_tftp_packets are counted whenever we receive a TFTP packet - * which was not expected; if this gets larger than 'retries' - * we just exit */ - if (tftp_err->bad_tftp_packets > retries) { - tftp_errno = -40; - break; - } - - /* no_packets counts the times we have returned from receive_ether() - * without any packet received; if this gets larger than 'retries' - * we also just exit */ - if (tftp_err->no_packets > retries) { - tftp_errno = -41; - break; - } - } - - // Setting buffer to NULL disables handling of received TFTP packets. - buffer = NULL; - - if (tftp_errno) - return tftp_errno; - - print_progress(-1, received_len); - printf("\n"); - if (lost_packets) - printf("Lost ACK packets: %d\n", lost_packets); - - return received_len; -} |