summaryrefslogtreecommitdiffstats
path: root/qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.c
diff options
context:
space:
mode:
authorRajithaY <rajithax.yerrumsetty@intel.com>2017-04-25 03:31:15 -0700
committerRajitha Yerrumchetty <rajithax.yerrumsetty@intel.com>2017-05-22 06:48:08 +0000
commitbb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch)
treeca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/SLOF/clients/net-snk/app/netlib/tftp.c
parenta14b48d18a9ed03ec191cf16b162206998a895ce (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.c586
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;
-}