/** @file
 *
 * PXE UDP API
 *
 */

#include <string.h>
#include <byteswap.h>
#include <gpxe/xfer.h>
#include <gpxe/udp.h>
#include <gpxe/uaccess.h>
#include <gpxe/process.h>
#include <pxe.h>

/*
 * Copyright (C) 2004 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

FILE_LICENCE ( GPL2_OR_LATER );

/** A PXE UDP connection */
struct pxe_udp_connection {
	/** Data transfer interface to UDP stack */
	struct xfer_interface xfer;
	/** Local address */
	struct sockaddr_in local;
	/** Current PXENV_UDP_READ parameter block */
	struct s_PXENV_UDP_READ *pxenv_udp_read;
};

/**
 * Receive PXE UDP data
 *
 * @v xfer			Data transfer interface
 * @v iobuf			I/O buffer
 * @v meta			Data transfer metadata
 * @ret rc			Return status code
 *
 * Receives a packet as part of the current pxenv_udp_read()
 * operation.
 */
static int pxe_udp_deliver_iob ( struct xfer_interface *xfer,
				 struct io_buffer *iobuf,
				 struct xfer_metadata *meta ) {
	struct pxe_udp_connection *pxe_udp = 
		container_of ( xfer, struct pxe_udp_connection, xfer );
	struct s_PXENV_UDP_READ *pxenv_udp_read = pxe_udp->pxenv_udp_read;
	struct sockaddr_in *sin_src;
	struct sockaddr_in *sin_dest;
	userptr_t buffer;
	size_t len;
	int rc = 0;

	if ( ! pxenv_udp_read ) {
		DBG ( "PXE discarded UDP packet\n" );
		rc = -ENOBUFS;
		goto done;
	}

	/* Copy packet to buffer and record length */
	buffer = real_to_user ( pxenv_udp_read->buffer.segment,
				pxenv_udp_read->buffer.offset );
	len = iob_len ( iobuf );
	if ( len > pxenv_udp_read->buffer_size )
		len = pxenv_udp_read->buffer_size;
	copy_to_user ( buffer, 0, iobuf->data, len );
	pxenv_udp_read->buffer_size = len;

	/* Fill in source/dest information */
	assert ( meta );
	sin_src = ( struct sockaddr_in * ) meta->src;
	assert ( sin_src );
	assert ( sin_src->sin_family == AF_INET );
	pxenv_udp_read->src_ip = sin_src->sin_addr.s_addr;
	pxenv_udp_read->s_port = sin_src->sin_port;
	sin_dest = ( struct sockaddr_in * ) meta->dest;
	assert ( sin_dest );
	assert ( sin_dest->sin_family == AF_INET );
	pxenv_udp_read->dest_ip = sin_dest->sin_addr.s_addr;
	pxenv_udp_read->d_port = sin_dest->sin_port;

	/* Mark as received */
	pxe_udp->pxenv_udp_read = NULL;

 done:
	free_iob ( iobuf );
	return rc;
}

/** PXE UDP data transfer interface operations */
static struct xfer_interface_operations pxe_udp_xfer_operations = {
	.close		= ignore_xfer_close,
	.vredirect	= ignore_xfer_vredirect,
	.window		= unlimited_xfer_window,
	.alloc_iob	= default_xfer_alloc_iob,
	.deliver_iob	= pxe_udp_deliver_iob,
	.deliver_raw	= xfer_deliver_as_iob,
};

/** The PXE UDP connection */
static struct pxe_udp_connection pxe_udp = {
	.xfer = XFER_INIT ( &pxe_udp_xfer_operations ),
	.local = {
		.sin_family = AF_INET,
	},
};

/**
 * UDP OPEN
 *
 * @v pxenv_udp_open			Pointer to a struct s_PXENV_UDP_OPEN
 * @v s_PXENV_UDP_OPEN::src_ip		IP address of this station, or 0.0.0.0
 * @ret #PXENV_EXIT_SUCCESS		Always
 * @ret s_PXENV_UDP_OPEN::Status	PXE status code
 * @err #PXENV_STATUS_UDP_OPEN		UDP connection already open
 * @err #PXENV_STATUS_OUT_OF_RESOURCES	Could not open connection
 *
 * Prepares the PXE stack for communication using pxenv_udp_write()
 * and pxenv_udp_read().
 *
 * The IP address supplied in s_PXENV_UDP_OPEN::src_ip will be
 * recorded and used as the local station's IP address for all further
 * communication, including communication by means other than
 * pxenv_udp_write() and pxenv_udp_read().  (If
 * s_PXENV_UDP_OPEN::src_ip is 0.0.0.0, the local station's IP address
 * will remain unchanged.)
 *
 * You can only have one open UDP connection at a time.  This is not a
 * meaningful restriction, since pxenv_udp_write() and
 * pxenv_udp_read() allow you to specify arbitrary local and remote
 * ports and an arbitrary remote address for each packet.  According
 * to the PXE specifiation, you cannot have a UDP connection open at
 * the same time as a TFTP connection; this restriction does not apply
 * to Etherboot.
 *
 * On x86, you must set the s_PXE::StatusCallout field to a nonzero
 * value before calling this function in protected mode.  You cannot
 * call this function with a 32-bit stack segment.  (See the relevant
 * @ref pxe_x86_pmode16 "implementation note" for more details.)
 *
 * @note The PXE specification does not make it clear whether the IP
 * address supplied in s_PXENV_UDP_OPEN::src_ip should be used only
 * for this UDP connection, or retained for all future communication.
 * The latter seems more consistent with typical PXE stack behaviour.
 *
 * @note Etherboot currently ignores the s_PXENV_UDP_OPEN::src_ip
 * parameter.
 *
 */
PXENV_EXIT_t pxenv_udp_open ( struct s_PXENV_UDP_OPEN *pxenv_udp_open ) {
	int rc;

	DBG ( "PXENV_UDP_OPEN" );

	/* Record source IP address */
	pxe_udp.local.sin_addr.s_addr = pxenv_udp_open->src_ip;
	DBG ( " %s", inet_ntoa ( pxe_udp.local.sin_addr ) );

	/* Open promiscuous UDP connection */
	xfer_close ( &pxe_udp.xfer, 0 );
	if ( ( rc = udp_open_promisc ( &pxe_udp.xfer ) ) != 0 ) {
		pxenv_udp_open->Status = PXENV_STATUS ( rc );
		return PXENV_EXIT_FAILURE;
	}

	pxenv_udp_open->Status = PXENV_STATUS_SUCCESS;
	return PXENV_EXIT_SUCCESS;
}

/**
 * UDP CLOSE
 *
 * @v pxenv_udp_close			Pointer to a struct s_PXENV_UDP_CLOSE
 * @ret #PXENV_EXIT_SUCCESS		Always
 * @ret s_PXENV_UDP_CLOSE::Status	PXE status code
 * @err None				-
 *
 * Closes a UDP connection opened with pxenv_udp_open().
 *
 * You can only have one open UDP connection at a time.  You cannot
 * have a UDP connection open at the same time as a TFTP connection.
 * You cannot use pxenv_udp_close() to close a TFTP connection; use
 * pxenv_tftp_close() instead.
 *
 * On x86, you must set the s_PXE::StatusCallout field to a nonzero
 * value before calling this function in protected mode.  You cannot
 * call this function with a 32-bit stack segment.  (See the relevant
 * @ref pxe_x86_pmode16 "implementation note" for more details.)
 *
 */
PXENV_EXIT_t pxenv_udp_close ( struct s_PXENV_UDP_CLOSE *pxenv_udp_close ) {
	DBG ( "PXENV_UDP_CLOSE" );

	/* Close UDP connection */
	xfer_close ( &pxe_udp.xfer, 0 );

	pxenv_udp_close->Status = PXENV_STATUS_SUCCESS;
	return PXENV_EXIT_SUCCESS;
}

/**
 * UDP WRITE
 *
 * @v pxenv_udp_write			Pointer to a struct s_PXENV_UDP_WRITE
 * @v s_PXENV_UDP_WRITE::ip		Destination IP address
 * @v s_PXENV_UDP_WRITE::gw		Relay agent IP address, or 0.0.0.0
 * @v s_PXENV_UDP_WRITE::src_port	Source UDP port, or 0
 * @v s_PXENV_UDP_WRITE::dst_port	Destination UDP port
 * @v s_PXENV_UDP_WRITE::buffer_size	Length of the UDP payload
 * @v s_PXENV_UDP_WRITE::buffer		Address of the UDP payload
 * @ret #PXENV_EXIT_SUCCESS		Packet was transmitted successfully
 * @ret #PXENV_EXIT_FAILURE		Packet could not be transmitted
 * @ret s_PXENV_UDP_WRITE::Status	PXE status code
 * @err #PXENV_STATUS_UDP_CLOSED	UDP connection is not open
 * @err #PXENV_STATUS_UNDI_TRANSMIT_ERROR Could not transmit packet
 *
 * Transmits a single UDP packet.  A valid IP and UDP header will be
 * prepended to the payload in s_PXENV_UDP_WRITE::buffer; the buffer
 * should not contain precomputed IP and UDP headers, nor should it
 * contain space allocated for these headers.  The first byte of the
 * buffer will be transmitted as the first byte following the UDP
 * header.
 *
 * If s_PXENV_UDP_WRITE::gw is 0.0.0.0, normal IP routing will take
 * place.  See the relevant @ref pxe_routing "implementation note" for
 * more details.
 *
 * If s_PXENV_UDP_WRITE::src_port is 0, port 2069 will be used.
 *
 * You must have opened a UDP connection with pxenv_udp_open() before
 * calling pxenv_udp_write().
 *
 * On x86, you must set the s_PXE::StatusCallout field to a nonzero
 * value before calling this function in protected mode.  You cannot
 * call this function with a 32-bit stack segment.  (See the relevant
 * @ref pxe_x86_pmode16 "implementation note" for more details.)
 *
 * @note Etherboot currently ignores the s_PXENV_UDP_WRITE::gw
 * parameter.
 *
 */
PXENV_EXIT_t pxenv_udp_write ( struct s_PXENV_UDP_WRITE *pxenv_udp_write ) {
	struct sockaddr_in dest;
	struct xfer_metadata meta = {
		.src = ( struct sockaddr * ) &pxe_udp.local,
		.dest = ( struct sockaddr * ) &dest,
		.netdev = pxe_netdev,
	};
	size_t len;
	struct io_buffer *iobuf;
	userptr_t buffer;
	int rc;

	DBG ( "PXENV_UDP_WRITE" );

	/* Construct destination socket address */
	memset ( &dest, 0, sizeof ( dest ) );
	dest.sin_family = AF_INET;
	dest.sin_addr.s_addr = pxenv_udp_write->ip;
	dest.sin_port = pxenv_udp_write->dst_port;

	/* Set local (source) port.  PXE spec says source port is 2069
	 * if not specified.  Really, this ought to be set at UDP open
	 * time but hey, we didn't design this API.
	 */
	pxe_udp.local.sin_port = pxenv_udp_write->src_port;
	if ( ! pxe_udp.local.sin_port )
		pxe_udp.local.sin_port = htons ( 2069 );

	/* FIXME: we ignore the gateway specified, since we're
	 * confident of being able to do our own routing.  We should
	 * probably allow for multiple gateways.
	 */

	/* Allocate and fill data buffer */
	len = pxenv_udp_write->buffer_size;
	iobuf = xfer_alloc_iob ( &pxe_udp.xfer, len );
	if ( ! iobuf ) {
		pxenv_udp_write->Status = PXENV_STATUS_OUT_OF_RESOURCES;
		return PXENV_EXIT_FAILURE;
	}
	buffer = real_to_user ( pxenv_udp_write->buffer.segment,
				pxenv_udp_write->buffer.offset );
	copy_from_user ( iob_put ( iobuf, len ), buffer, 0, len );

	DBG ( " %04x:%04x+%x %d->%s:%d", pxenv_udp_write->buffer.segment,
	      pxenv_udp_write->buffer.offset, pxenv_udp_write->buffer_size,
	      ntohs ( pxenv_udp_write->src_port ),
	      inet_ntoa ( dest.sin_addr ),
	      ntohs ( pxenv_udp_write->dst_port ) );
	
	/* Transmit packet */
	if ( ( rc = xfer_deliver_iob_meta ( &pxe_udp.xfer, iobuf,
					    &meta ) ) != 0 ) {
		pxenv_udp_write->Status = PXENV_STATUS ( rc );
		return PXENV_EXIT_FAILURE;
	}

	pxenv_udp_write->Status = PXENV_STATUS_SUCCESS;
	return PXENV_EXIT_SUCCESS;
}

/**
 * UDP READ
 *
 * @v pxenv_udp_read			Pointer to a struct s_PXENV_UDP_READ
 * @v s_PXENV_UDP_READ::dest_ip		Destination IP address, or 0.0.0.0
 * @v s_PXENV_UDP_READ::d_port		Destination UDP port, or 0
 * @v s_PXENV_UDP_READ::buffer_size	Size of the UDP payload buffer
 * @v s_PXENV_UDP_READ::buffer		Address of the UDP payload buffer
 * @ret #PXENV_EXIT_SUCCESS		A packet has been received
 * @ret #PXENV_EXIT_FAILURE		No packet has been received
 * @ret s_PXENV_UDP_READ::Status	PXE status code
 * @ret s_PXENV_UDP_READ::src_ip	Source IP address
 * @ret s_PXENV_UDP_READ::dest_ip	Destination IP address
 * @ret s_PXENV_UDP_READ::s_port	Source UDP port
 * @ret s_PXENV_UDP_READ::d_port	Destination UDP port
 * @ret s_PXENV_UDP_READ::buffer_size	Length of UDP payload
 * @err #PXENV_STATUS_UDP_CLOSED	UDP connection is not open
 * @err #PXENV_STATUS_FAILURE		No packet was ready to read
 *
 * Receive a single UDP packet.  This is a non-blocking call; if no
 * packet is ready to read, the call will return instantly with
 * s_PXENV_UDP_READ::Status==PXENV_STATUS_FAILURE.
 *
 * If s_PXENV_UDP_READ::dest_ip is 0.0.0.0, UDP packets addressed to
 * any IP address will be accepted and may be returned to the caller.
 *
 * If s_PXENV_UDP_READ::d_port is 0, UDP packets addressed to any UDP
 * port will be accepted and may be returned to the caller.
 *
 * You must have opened a UDP connection with pxenv_udp_open() before
 * calling pxenv_udp_read().
 *
 * On x86, you must set the s_PXE::StatusCallout field to a nonzero
 * value before calling this function in protected mode.  You cannot
 * call this function with a 32-bit stack segment.  (See the relevant
 * @ref pxe_x86_pmode16 "implementation note" for more details.)
 *
 * @note The PXE specification (version 2.1) does not state that we
 * should fill in s_PXENV_UDP_READ::dest_ip and
 * s_PXENV_UDP_READ::d_port, but Microsoft Windows' NTLDR program
 * expects us to do so, and will fail if we don't.
 *
 */
PXENV_EXIT_t pxenv_udp_read ( struct s_PXENV_UDP_READ *pxenv_udp_read ) {
	struct in_addr dest_ip_wanted = { .s_addr = pxenv_udp_read->dest_ip };
	struct in_addr dest_ip;
	uint16_t d_port_wanted = pxenv_udp_read->d_port;
	uint16_t d_port;

	DBG ( "PXENV_UDP_READ" );

	/* Try receiving a packet */
	pxe_udp.pxenv_udp_read = pxenv_udp_read;
	step();
	if ( pxe_udp.pxenv_udp_read ) {
		/* No packet received */
		pxe_udp.pxenv_udp_read = NULL;
		goto no_packet;
	}
	dest_ip.s_addr = pxenv_udp_read->dest_ip;
	d_port = pxenv_udp_read->d_port;

	/* Filter on destination address and/or port */
	if ( dest_ip_wanted.s_addr &&
	     ( dest_ip_wanted.s_addr != dest_ip.s_addr ) ) {
		DBG ( " wrong IP %s", inet_ntoa ( dest_ip ) );
		DBG ( " (wanted %s)", inet_ntoa ( dest_ip_wanted ) );
		goto no_packet;
	}
	if ( d_port_wanted && ( d_port_wanted != d_port ) ) {
		DBG ( " wrong port %d ", htons ( d_port ) );
		DBG ( " (wanted %d)", htons ( d_port_wanted ) );
		goto no_packet;
	}

	DBG ( " %04x:%04x+%x %s:", pxenv_udp_read->buffer.segment,
	      pxenv_udp_read->buffer.offset, pxenv_udp_read->buffer_size,
	      inet_ntoa ( *( ( struct in_addr * ) &pxenv_udp_read->src_ip ) ));
	DBG ( "%d<-%s:%d",  ntohs ( pxenv_udp_read->s_port ),
	      inet_ntoa ( *( ( struct in_addr * ) &pxenv_udp_read->dest_ip ) ),
	      ntohs ( pxenv_udp_read->d_port ) );

	pxenv_udp_read->Status = PXENV_STATUS_SUCCESS;
	return PXENV_EXIT_SUCCESS;

 no_packet:
	pxenv_udp_read->Status = PXENV_STATUS_FAILURE;
	return PXENV_EXIT_FAILURE;
}
