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/ipxe/src/net/tcp/ftp.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/ipxe/src/net/tcp/ftp.c')
-rw-r--r-- | qemu/roms/ipxe/src/net/tcp/ftp.c | 546 |
1 files changed, 0 insertions, 546 deletions
diff --git a/qemu/roms/ipxe/src/net/tcp/ftp.c b/qemu/roms/ipxe/src/net/tcp/ftp.c deleted file mode 100644 index be7a7c3b5..000000000 --- a/qemu/roms/ipxe/src/net/tcp/ftp.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <errno.h> -#include <ctype.h> -#include <byteswap.h> -#include <ipxe/socket.h> -#include <ipxe/tcpip.h> -#include <ipxe/in.h> -#include <ipxe/iobuf.h> -#include <ipxe/xfer.h> -#include <ipxe/open.h> -#include <ipxe/uri.h> -#include <ipxe/features.h> -#include <ipxe/ftp.h> - -/** @file - * - * File transfer protocol - * - */ - -FEATURE ( FEATURE_PROTOCOL, "FTP", DHCP_EB_FEATURE_FTP, 1 ); - -/** - * FTP states - * - * These @b must be sequential, i.e. a successful FTP session must - * pass through each of these states in order. - */ -enum ftp_state { - FTP_CONNECT = 0, - FTP_USER, - FTP_PASS, - FTP_TYPE, - FTP_SIZE, - FTP_PASV, - FTP_RETR, - FTP_WAIT, - FTP_QUIT, - FTP_DONE, -}; - -/** - * An FTP request - * - */ -struct ftp_request { - /** Reference counter */ - struct refcnt refcnt; - /** Data transfer interface */ - struct interface xfer; - - /** URI being fetched */ - struct uri *uri; - /** FTP control channel interface */ - struct interface control; - /** FTP data channel interface */ - struct interface data; - - /** Current state */ - enum ftp_state state; - /** Buffer to be filled with data received via the control channel */ - char *recvbuf; - /** Remaining size of recvbuf */ - size_t recvsize; - /** FTP status code, as text */ - char status_text[5]; - /** Passive-mode parameters, as text */ - char passive_text[24]; /* "aaa,bbb,ccc,ddd,eee,fff" */ - /** File size, as text */ - char filesize[20]; -}; - -/** - * Free FTP request - * - * @v refcnt Reference counter - */ -static void ftp_free ( struct refcnt *refcnt ) { - struct ftp_request *ftp = - container_of ( refcnt, struct ftp_request, refcnt ); - - DBGC ( ftp, "FTP %p freed\n", ftp ); - - uri_put ( ftp->uri ); - free ( ftp ); -} - -/** - * Mark FTP operation as complete - * - * @v ftp FTP request - * @v rc Return status code - */ -static void ftp_done ( struct ftp_request *ftp, int rc ) { - - DBGC ( ftp, "FTP %p completed (%s)\n", ftp, strerror ( rc ) ); - - /* Close all data transfer interfaces */ - intf_shutdown ( &ftp->data, rc ); - intf_shutdown ( &ftp->control, rc ); - intf_shutdown ( &ftp->xfer, rc ); -} - -/***************************************************************************** - * - * FTP control channel - * - */ - -/** An FTP control channel string */ -struct ftp_control_string { - /** Literal portion */ - const char *literal; - /** Variable portion - * - * @v ftp FTP request - * @ret string Variable portion of string - */ - const char * ( *variable ) ( struct ftp_request *ftp ); -}; - -/** - * Retrieve FTP pathname - * - * @v ftp FTP request - * @ret path FTP pathname - */ -static const char * ftp_uri_path ( struct ftp_request *ftp ) { - return ftp->uri->path; -} - -/** - * Retrieve FTP user - * - * @v ftp FTP request - * @ret user FTP user - */ -static const char * ftp_user ( struct ftp_request *ftp ) { - static char *ftp_default_user = "anonymous"; - return ftp->uri->user ? ftp->uri->user : ftp_default_user; -} - -/** - * Retrieve FTP password - * - * @v ftp FTP request - * @ret password FTP password - */ -static const char * ftp_password ( struct ftp_request *ftp ) { - static char *ftp_default_password = "ipxe@ipxe.org"; - return ftp->uri->password ? ftp->uri->password : ftp_default_password; -} - -/** FTP control channel strings */ -static struct ftp_control_string ftp_strings[] = { - [FTP_CONNECT] = { NULL, NULL }, - [FTP_USER] = { "USER ", ftp_user }, - [FTP_PASS] = { "PASS ", ftp_password }, - [FTP_TYPE] = { "TYPE I", NULL }, - [FTP_SIZE] = { "SIZE ", ftp_uri_path }, - [FTP_PASV] = { "PASV", NULL }, - [FTP_RETR] = { "RETR ", ftp_uri_path }, - [FTP_WAIT] = { NULL, NULL }, - [FTP_QUIT] = { "QUIT", NULL }, - [FTP_DONE] = { NULL, NULL }, -}; - -/** - * Parse FTP byte sequence value - * - * @v text Text string - * @v value Value buffer - * @v len Length of value buffer - * - * This parses an FTP byte sequence value (e.g. the "aaa,bbb,ccc,ddd" - * form for IP addresses in PORT commands) into a byte sequence. @c - * *text will be updated to point beyond the end of the parsed byte - * sequence. - * - * This function is safe in the presence of malformed data, though the - * output is undefined. - */ -static void ftp_parse_value ( char **text, uint8_t *value, size_t len ) { - do { - *(value++) = strtoul ( *text, text, 10 ); - if ( **text ) - (*text)++; - } while ( --len ); -} - -/** - * Move to next state and send the appropriate FTP control string - * - * @v ftp FTP request - * - */ -static void ftp_next_state ( struct ftp_request *ftp ) { - struct ftp_control_string *ftp_string; - const char *literal; - const char *variable; - - /* Move to next state */ - if ( ftp->state < FTP_DONE ) - ftp->state++; - - /* Send control string if needed */ - ftp_string = &ftp_strings[ftp->state]; - literal = ftp_string->literal; - variable = ( ftp_string->variable ? - ftp_string->variable ( ftp ) : "" ); - if ( literal ) { - DBGC ( ftp, "FTP %p sending %s%s\n", ftp, literal, variable ); - xfer_printf ( &ftp->control, "%s%s\r\n", literal, variable ); - } -} - -/** - * Handle an FTP control channel response - * - * @v ftp FTP request - * - * This is called once we have received a complete response line. - */ -static void ftp_reply ( struct ftp_request *ftp ) { - char status_major = ftp->status_text[0]; - char separator = ftp->status_text[3]; - - DBGC ( ftp, "FTP %p received status %s\n", ftp, ftp->status_text ); - - /* Ignore malformed lines */ - if ( separator != ' ' ) - return; - - /* Ignore "intermediate" responses (1xx codes) */ - if ( status_major == '1' ) - return; - - /* If the SIZE command is not supported by the server, we go to - * the next step. - */ - if ( ( status_major == '5' ) && ( ftp->state == FTP_SIZE ) ) { - ftp_next_state ( ftp ); - return; - } - - /* Anything other than success (2xx) or, in the case of a - * repsonse to a "USER" command, a password prompt (3xx), is a - * fatal error. - */ - if ( ! ( ( status_major == '2' ) || - ( ( status_major == '3' ) && ( ftp->state == FTP_USER ) ) ) ){ - /* Flag protocol error and close connections */ - ftp_done ( ftp, -EPROTO ); - return; - } - - /* Parse file size */ - if ( ftp->state == FTP_SIZE ) { - size_t filesize; - char *endptr; - - /* Parse size */ - filesize = strtoul ( ftp->filesize, &endptr, 10 ); - if ( *endptr != '\0' ) { - DBGC ( ftp, "FTP %p invalid SIZE \"%s\"\n", - ftp, ftp->filesize ); - ftp_done ( ftp, -EPROTO ); - return; - } - - /* Use seek() to notify recipient of filesize */ - DBGC ( ftp, "FTP %p file size is %zd bytes\n", ftp, filesize ); - xfer_seek ( &ftp->xfer, filesize ); - xfer_seek ( &ftp->xfer, 0 ); - } - - /* Open passive connection when we get "PASV" response */ - if ( ftp->state == FTP_PASV ) { - char *ptr = ftp->passive_text; - union { - struct sockaddr_in sin; - struct sockaddr sa; - } sa; - int rc; - - sa.sin.sin_family = AF_INET; - ftp_parse_value ( &ptr, ( uint8_t * ) &sa.sin.sin_addr, - sizeof ( sa.sin.sin_addr ) ); - ftp_parse_value ( &ptr, ( uint8_t * ) &sa.sin.sin_port, - sizeof ( sa.sin.sin_port ) ); - if ( ( rc = xfer_open_socket ( &ftp->data, SOCK_STREAM, - &sa.sa, NULL ) ) != 0 ) { - DBGC ( ftp, "FTP %p could not open data connection\n", - ftp ); - ftp_done ( ftp, rc ); - return; - } - } - - /* Move to next state and send control string */ - ftp_next_state ( ftp ); - -} - -/** - * Handle new data arriving on FTP control channel - * - * @v ftp FTP request - * @v iob I/O buffer - * @v meta Data transfer metadata - * @ret rc Return status code - * - * Data is collected until a complete line is received, at which point - * its information is passed to ftp_reply(). - */ -static int ftp_control_deliver ( struct ftp_request *ftp, - struct io_buffer *iobuf, - struct xfer_metadata *meta __unused ) { - char *data = iobuf->data; - size_t len = iob_len ( iobuf ); - char *recvbuf = ftp->recvbuf; - size_t recvsize = ftp->recvsize; - char c; - - while ( len-- ) { - c = *(data++); - if ( ( c == '\r' ) || ( c == '\n' ) ) { - /* End of line: call ftp_reply() to handle - * completed reply. Avoid calling ftp_reply() - * twice if we receive both \r and \n. - */ - if ( recvbuf != ftp->status_text ) - ftp_reply ( ftp ); - /* Start filling up the status code buffer */ - recvbuf = ftp->status_text; - recvsize = sizeof ( ftp->status_text ) - 1; - } else if ( ( ftp->state == FTP_PASV ) && ( c == '(' ) ) { - /* Start filling up the passive parameter buffer */ - recvbuf = ftp->passive_text; - recvsize = sizeof ( ftp->passive_text ) - 1; - } else if ( ( ftp->state == FTP_PASV ) && ( c == ')' ) ) { - /* Stop filling the passive parameter buffer */ - recvsize = 0; - } else if ( ( ftp->state == FTP_SIZE ) && ( c == ' ' ) ) { - /* Start filling up the file size buffer */ - recvbuf = ftp->filesize; - recvsize = sizeof ( ftp->filesize ) - 1; - } else { - /* Fill up buffer if applicable */ - if ( recvsize > 0 ) { - *(recvbuf++) = c; - recvsize--; - } - } - } - - /* Store for next invocation */ - ftp->recvbuf = recvbuf; - ftp->recvsize = recvsize; - - /* Free I/O buffer */ - free_iob ( iobuf ); - - return 0; -} - -/** FTP control channel interface operations */ -static struct interface_operation ftp_control_operations[] = { - INTF_OP ( xfer_deliver, struct ftp_request *, ftp_control_deliver ), - INTF_OP ( intf_close, struct ftp_request *, ftp_done ), -}; - -/** FTP control channel interface descriptor */ -static struct interface_descriptor ftp_control_desc = - INTF_DESC ( struct ftp_request, control, ftp_control_operations ); - -/***************************************************************************** - * - * FTP data channel - * - */ - -/** - * Handle FTP data channel being closed - * - * @v ftp FTP request - * @v rc Reason for closure - * - * When the data channel is closed, the control channel should be left - * alone; the server will send a completion message via the control - * channel which we'll pick up. - * - * If the data channel is closed due to an error, we abort the request. - */ -static void ftp_data_closed ( struct ftp_request *ftp, int rc ) { - - DBGC ( ftp, "FTP %p data connection closed: %s\n", - ftp, strerror ( rc ) ); - - /* If there was an error, close control channel and record status */ - if ( rc ) { - ftp_done ( ftp, rc ); - } else { - ftp_next_state ( ftp ); - } -} - -/** FTP data channel interface operations */ -static struct interface_operation ftp_data_operations[] = { - INTF_OP ( intf_close, struct ftp_request *, ftp_data_closed ), -}; - -/** FTP data channel interface descriptor */ -static struct interface_descriptor ftp_data_desc = - INTF_DESC_PASSTHRU ( struct ftp_request, data, ftp_data_operations, - xfer ); - -/***************************************************************************** - * - * Data transfer interface - * - */ - -/** FTP data transfer interface operations */ -static struct interface_operation ftp_xfer_operations[] = { - INTF_OP ( intf_close, struct ftp_request *, ftp_done ), -}; - -/** FTP data transfer interface descriptor */ -static struct interface_descriptor ftp_xfer_desc = - INTF_DESC_PASSTHRU ( struct ftp_request, xfer, ftp_xfer_operations, - data ); - -/***************************************************************************** - * - * URI opener - * - */ - -/** - * Check validity of FTP control channel string - * - * @v string String - * @ret rc Return status code - */ -static int ftp_check_string ( const char *string ) { - char c; - - /* The FTP control channel is line-based. Check for invalid - * non-printable characters (e.g. newlines). - */ - while ( ( c = *(string++) ) ) { - if ( ! isprint ( c ) ) - return -EINVAL; - } - return 0; -} - -/** - * Initiate an FTP connection - * - * @v xfer Data transfer interface - * @v uri Uniform Resource Identifier - * @ret rc Return status code - */ -static int ftp_open ( struct interface *xfer, struct uri *uri ) { - struct ftp_request *ftp; - struct sockaddr_tcpip server; - int rc; - - /* Sanity checks */ - if ( ! uri->host ) - return -EINVAL; - if ( ! uri->path ) - return -EINVAL; - if ( ( rc = ftp_check_string ( uri->path ) ) != 0 ) - return rc; - if ( uri->user && ( ( rc = ftp_check_string ( uri->user ) ) != 0 ) ) - return rc; - if ( uri->password && - ( ( rc = ftp_check_string ( uri->password ) ) != 0 ) ) - return rc; - - /* Allocate and populate structure */ - ftp = zalloc ( sizeof ( *ftp ) ); - if ( ! ftp ) - return -ENOMEM; - ref_init ( &ftp->refcnt, ftp_free ); - intf_init ( &ftp->xfer, &ftp_xfer_desc, &ftp->refcnt ); - intf_init ( &ftp->control, &ftp_control_desc, &ftp->refcnt ); - intf_init ( &ftp->data, &ftp_data_desc, &ftp->refcnt ); - ftp->uri = uri_get ( uri ); - ftp->recvbuf = ftp->status_text; - ftp->recvsize = sizeof ( ftp->status_text ) - 1; - - DBGC ( ftp, "FTP %p fetching %s\n", ftp, ftp->uri->path ); - - /* Open control connection */ - memset ( &server, 0, sizeof ( server ) ); - server.st_port = htons ( uri_port ( uri, FTP_PORT ) ); - if ( ( rc = xfer_open_named_socket ( &ftp->control, SOCK_STREAM, - ( struct sockaddr * ) &server, - uri->host, NULL ) ) != 0 ) - goto err; - - /* Attach to parent interface, mortalise self, and return */ - intf_plug_plug ( &ftp->xfer, xfer ); - ref_put ( &ftp->refcnt ); - return 0; - - err: - DBGC ( ftp, "FTP %p could not create request: %s\n", - ftp, strerror ( rc ) ); - ftp_done ( ftp, rc ); - ref_put ( &ftp->refcnt ); - return rc; -} - -/** FTP URI opener */ -struct uri_opener ftp_uri_opener __uri_opener = { - .scheme = "ftp", - .open = ftp_open, -}; |