Exemplo n.º 1
0
/**
 * Read from block device
 *
 * @v http		HTTP transaction
 * @v data		Data interface
 * @v lba		Starting logical block address
 * @v count		Number of logical blocks
 * @v buffer		Data buffer
 * @v len		Length of data buffer
 * @ret rc		Return status code
 */
int http_block_read ( struct http_transaction *http, struct interface *data,
		      uint64_t lba, unsigned int count, userptr_t buffer,
		      size_t len ) {
	struct http_request_range range;
	int rc;

	/* Sanity check */
	assert ( len == ( count * HTTP_BLKSIZE ) );

	/* Construct request range descriptor */
	range.start = ( lba * HTTP_BLKSIZE );
	range.len = len;

	/* Start a range request to retrieve the block(s) */
	if ( ( rc = http_open ( data, &http_get, http->uri, &range,
				NULL ) ) != 0 )
		goto err_open;

	/* Insert block device translator */
	if ( ( rc = block_translate ( data, buffer, len ) ) != 0 ) {
		DBGC ( http, "HTTP %p could not insert block translator: %s\n",
		       http, strerror ( rc ) );
		goto err_translate;
	}

	return 0;

 err_translate:
	intf_restart ( data, rc );
 err_open:
	return rc;
}
Exemplo n.º 2
0
Arquivo: resolv.c Projeto: 42wim/ipxe
/**
 * Child finished resolution
 *
 * @v mux		Name resolution multiplexer
 * @v rc		Return status code
 */
static void resmux_child_close ( struct resolv_mux *mux, int rc ) {

	/* Restart child interface */
	intf_restart ( &mux->child, rc );

	/* If this resolution succeeded, stop now */
	if ( rc == 0 ) {
		DBGC ( mux, "RESOLV %p succeeded using method %s\n",
		       mux, mux->resolver->name );
		goto finished;
	}

	/* Attempt next child resolver, if possible */
	mux->resolver++;
	if ( mux->resolver >= table_end ( RESOLVERS ) ) {
		DBGC ( mux, "RESOLV %p failed to resolve name\n", mux );
		goto finished;
	}
	if ( ( rc = resmux_try ( mux ) ) != 0 )
		goto finished;

	/* Next resolver is now running */
	return;

 finished:
	intf_shutdown ( &mux->parent, rc );
}
Exemplo n.º 3
0
Arquivo: open.c Projeto: 42wim/ipxe
/**
 * Reopen location
 *
 * @v intf		Data transfer interface
 * @v type		Location type
 * @v args		Remaining arguments depend upon location type
 * @ret rc		Return status code
 *
 * This will close the existing connection and open a new connection
 * using xfer_vopen().  It is intended to be used as a .vredirect
 * method handler.
 */
int xfer_vreopen ( struct interface *intf, int type, va_list args ) {

	/* Close existing connection */
	intf_restart ( intf, 0 );

	/* Open new location */
	return xfer_vopen ( intf, type, args );
}
Exemplo n.º 4
0
/**
 * 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\n" );

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

	pxenv_udp_close->Status = PXENV_STATUS_SUCCESS;
	return PXENV_EXIT_SUCCESS;
}
Exemplo n.º 5
0
/**
 * Close an object interface
 *
 * @v intf		Object interface
 * @v rc		Reason for close
 *
 * Note that this function merely informs the destination object that
 * the interface is about to be closed; it doesn't actually disconnect
 * the interface.  In most cases, you probably want to use
 * intf_shutdown() or intf_restart() instead.
 */
void intf_close ( struct interface *intf, int rc ) {
	struct interface *dest;
	intf_close_TYPE ( void * ) *op =
		intf_get_dest_op ( intf, intf_close, &dest );
	void *object = intf_object ( dest );

	DBGC ( INTF_COL ( intf ), "INTF " INTF_INTF_FMT " close (%s)\n",
	       INTF_INTF_DBG ( intf, dest ), strerror ( rc ) );

	if ( op ) {
		op ( object, rc );
	} else {
		/* Default is to restart the interface */
		intf_restart ( dest, rc );
	}

	intf_put ( dest );
}
Exemplo n.º 6
0
/**
 * Apply syslog settings
 *
 * @ret rc		Return status code
 */
static int apply_syslog_settings ( void ) {
	struct sockaddr_in *sin_logserver =
		( struct sockaddr_in * ) &logserver;
	struct in_addr old_addr;
	int len;
	int rc;

	/* Fetch log server */
	syslog_console.disabled = 1;
	old_addr.s_addr = sin_logserver->sin_addr.s_addr;
	if ( ( len = fetch_ipv4_setting ( NULL, &syslog_setting,
					  &sin_logserver->sin_addr ) ) >= 0 ) {
		syslog_console.disabled = 0;
	}

	/* Do nothing unless log server has changed */
	if ( sin_logserver->sin_addr.s_addr == old_addr.s_addr )
		return 0;

	/* Reset syslog connection */
	intf_restart ( &syslogger, 0 );

	/* Do nothing unless we have a log server */
	if ( syslog_console.disabled ) {
		DBG ( "SYSLOG has no log server\n" );
		return 0;
	}

	/* Connect to log server */
	if ( ( rc = xfer_open_socket ( &syslogger, SOCK_DGRAM,
				       ( ( struct sockaddr * ) &logserver ),
				       NULL ) ) != 0 ) {
		DBG ( "SYSLOG cannot connect to log server: %s\n",
		      strerror ( rc ) );
		return rc;
	}
	DBG ( "SYSLOG using log server %s\n",
	      inet_ntoa ( sin_logserver->sin_addr ) );

	return 0;
}
Exemplo n.º 7
0
/**
 * 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\n", inet_ntoa ( pxe_udp.local.sin_addr ) );

	/* Open promiscuous UDP connection */
	intf_restart ( &pxe_udp.xfer, 0 );
	if ( ( rc = udp_open_promisc ( &pxe_udp.xfer ) ) != 0 ) {
		DBG ( "PXENV_UDP_OPEN could not open promiscuous socket: %s\n",
		      strerror ( rc ) );
		pxenv_udp_open->Status = PXENV_STATUS ( rc );
		return PXENV_EXIT_FAILURE;
	}

	pxenv_udp_open->Status = PXENV_STATUS_SUCCESS;
	return PXENV_EXIT_SUCCESS;
}
Exemplo n.º 8
0
/**
 * Open all PeerDist discovery sockets
 *
 * @ret rc		Return status code
 */
static int peerdisc_socket_open ( void ) {
	struct peerdisc_socket *socket;
	int rc;

	/* Open each socket */
	for_each_table_entry ( socket, PEERDISC_SOCKETS ) {
		if ( ( rc = xfer_open_socket ( &socket->xfer, SOCK_DGRAM,
					       &socket->address.sa,
					       NULL ) ) != 0 ) {
			DBGC ( socket, "PEERDISC %s could not open socket: "
			       "%s\n", socket->name, strerror ( rc ) );
			goto err;
		}
	}

	return 0;

 err:
	for_each_table_entry_continue_reverse ( socket, PEERDISC_SOCKETS )
		intf_restart ( &socket->xfer, rc );
	return rc;
}
Exemplo n.º 9
0
/**
 * Read block device capacity
 *
 * @v control		Control interface
 * @v data		Data interface
 * @ret rc		Return status code
 */
int http_block_read_capacity ( struct http_transaction *http,
			       struct interface *data ) {
	int rc;

	/* Start a HEAD request to retrieve the capacity */
	if ( ( rc = http_open ( data, &http_head, http->uri, NULL,
				NULL ) ) != 0 )
		goto err_open;

	/* Insert block device translator */
	if ( ( rc = block_translate ( data, UNULL, HTTP_BLKSIZE ) ) != 0 ) {
		DBGC ( http, "HTTP %p could not insert block translator: %s\n",
		       http, strerror ( rc ) );
		goto err_translate;
	}

	return 0;

 err_translate:
	intf_restart ( data, rc );
 err_open:
	return rc;
}