iPXE
Defines | Functions
guestrpc.c File Reference

VMware GuestRPC mechanism. More...

#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/vmware.h>
#include <ipxe/guestrpc.h>

Go to the source code of this file.

Defines

#define EPROTO_OPEN   __einfo_error ( EINFO_EPROTO_OPEN )
#define EINFO_EPROTO_OPEN   __einfo_uniqify ( EINFO_EPROTO, 0x00, "GuestRPC open failed" )
#define EPROTO_COMMAND_LEN   __einfo_error ( EINFO_EPROTO_COMMAND_LEN )
#define EINFO_EPROTO_COMMAND_LEN   __einfo_uniqify ( EINFO_EPROTO, 0x01, "GuestRPC command length failed" )
#define EPROTO_COMMAND_DATA   __einfo_error ( EINFO_EPROTO_COMMAND_DATA )
#define EINFO_EPROTO_COMMAND_DATA   __einfo_uniqify ( EINFO_EPROTO, 0x02, "GuestRPC command data failed" )
#define EPROTO_REPLY_LEN   __einfo_error ( EINFO_EPROTO_REPLY_LEN )
#define EINFO_EPROTO_REPLY_LEN   __einfo_uniqify ( EINFO_EPROTO, 0x03, "GuestRPC reply length failed" )
#define EPROTO_REPLY_DATA   __einfo_error ( EINFO_EPROTO_REPLY_DATA )
#define EINFO_EPROTO_REPLY_DATA   __einfo_uniqify ( EINFO_EPROTO, 0x04, "GuestRPC reply data failed" )
#define EPROTO_REPLY_FINISH   __einfo_error ( EINFO_EPROTO_REPLY_FINISH )
#define EINFO_EPROTO_REPLY_FINISH   __einfo_uniqify ( EINFO_EPROTO, 0x05, "GuestRPC reply finish failed" )
#define EPROTO_CLOSE   __einfo_error ( EINFO_EPROTO_CLOSE )
#define EINFO_EPROTO_CLOSE   __einfo_uniqify ( EINFO_EPROTO, 0x06, "GuestRPC close failed" )

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
int guestrpc_open (void)
 Open GuestRPC channel.
static int guestrpc_command_len (int channel, size_t len)
 Send GuestRPC command length.
static int guestrpc_command_data (int channel, uint32_t data)
 Send GuestRPC command data.
static int guestrpc_reply_len (int channel, uint16_t *reply_id)
 Receive GuestRPC reply length.
static int guestrpc_reply_data (int channel, uint16_t reply_id, uint32_t *data)
 Receive GuestRPC reply data.
static int guestrpc_reply_finish (int channel, uint16_t reply_id)
 Finish receiving GuestRPC reply.
void guestrpc_close (int channel)
 Close GuestRPC channel.
int guestrpc_command (int channel, const char *command, char *reply, size_t reply_len)
 Issue GuestRPC command.

Detailed Description

VMware GuestRPC mechanism.

Definition in file guestrpc.c.


Define Documentation

Definition at line 40 of file guestrpc.c.

Referenced by guestrpc_open().

#define EINFO_EPROTO_OPEN   __einfo_uniqify ( EINFO_EPROTO, 0x00, "GuestRPC open failed" )

Definition at line 41 of file guestrpc.c.

Definition at line 43 of file guestrpc.c.

Referenced by guestrpc_command_len().

#define EINFO_EPROTO_COMMAND_LEN   __einfo_uniqify ( EINFO_EPROTO, 0x01, "GuestRPC command length failed" )

Definition at line 44 of file guestrpc.c.

Definition at line 46 of file guestrpc.c.

Referenced by guestrpc_command_data().

#define EINFO_EPROTO_COMMAND_DATA   __einfo_uniqify ( EINFO_EPROTO, 0x02, "GuestRPC command data failed" )

Definition at line 47 of file guestrpc.c.

Definition at line 49 of file guestrpc.c.

Referenced by guestrpc_reply_len().

#define EINFO_EPROTO_REPLY_LEN   __einfo_uniqify ( EINFO_EPROTO, 0x03, "GuestRPC reply length failed" )

Definition at line 50 of file guestrpc.c.

Definition at line 52 of file guestrpc.c.

Referenced by guestrpc_reply_data().

#define EINFO_EPROTO_REPLY_DATA   __einfo_uniqify ( EINFO_EPROTO, 0x04, "GuestRPC reply data failed" )

Definition at line 53 of file guestrpc.c.

Definition at line 55 of file guestrpc.c.

Referenced by guestrpc_reply_finish().

#define EINFO_EPROTO_REPLY_FINISH   __einfo_uniqify ( EINFO_EPROTO, 0x05, "GuestRPC reply finish failed" )

Definition at line 56 of file guestrpc.c.

Definition at line 58 of file guestrpc.c.

#define EINFO_EPROTO_CLOSE   __einfo_uniqify ( EINFO_EPROTO, 0x06, "GuestRPC close failed" )

Definition at line 59 of file guestrpc.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
int guestrpc_open ( void  )

Open GuestRPC channel.

Return values:
channelChannel number, or negative error

Definition at line 67 of file guestrpc.c.

References channel, DBGC, EPROTO_OPEN, GUESTRPC_MAGIC, GUESTRPC_OPEN, GUESTRPC_OPEN_SUCCESS, and status.

Referenced by guestinfo_init(), and vmconsole_init().

                           {
        uint16_t channel;
        uint32_t discard_b;
        uint32_t status;

        /* Issue GuestRPC command */
        status = vmware_cmd_guestrpc ( 0, GUESTRPC_OPEN, GUESTRPC_MAGIC,
                                       &channel, &discard_b );
        if ( status != GUESTRPC_OPEN_SUCCESS ) {
                DBGC ( GUESTRPC_MAGIC, "GuestRPC open failed: status %08x\n",
                       status );
                return -EPROTO_OPEN;
        }

        DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d opened\n", channel );
        return channel;
}
static int guestrpc_command_len ( int  channel,
size_t  len 
) [static]

Send GuestRPC command length.

Parameters:
channelChannel number
lenCommand length
Return values:
rcReturn status code

Definition at line 92 of file guestrpc.c.

References DBGC, EPROTO_COMMAND_LEN, GUESTRPC_COMMAND_LEN, GUESTRPC_COMMAND_LEN_SUCCESS, GUESTRPC_MAGIC, and status.

Referenced by guestrpc_command().

                                                            {
        uint16_t discard_d;
        uint32_t discard_b;
        uint32_t status;

        /* Issue GuestRPC command */
        status = vmware_cmd_guestrpc ( channel, GUESTRPC_COMMAND_LEN, len,
                                       &discard_d, &discard_b );
        if ( status != GUESTRPC_COMMAND_LEN_SUCCESS ) {
                DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d send command "
                       "length %zd failed: status %08x\n",
                       channel, len, status );
                return -EPROTO_COMMAND_LEN;
        }

        return 0;
}
static int guestrpc_command_data ( int  channel,
uint32_t  data 
) [static]

Send GuestRPC command data.

Parameters:
channelChannel number
dataCommand data
Return values:
rcReturn status code

Definition at line 117 of file guestrpc.c.

References DBGC, EPROTO_COMMAND_DATA, GUESTRPC_COMMAND_DATA, GUESTRPC_COMMAND_DATA_SUCCESS, GUESTRPC_MAGIC, and status.

Referenced by guestrpc_command().

                                                                {
        uint16_t discard_d;
        uint32_t discard_b;
        uint32_t status;

        /* Issue GuestRPC command */
        status = vmware_cmd_guestrpc ( channel, GUESTRPC_COMMAND_DATA, data,
                                       &discard_d, &discard_b );
        if ( status != GUESTRPC_COMMAND_DATA_SUCCESS ) {
                DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d send command "
                       "data %08x failed: status %08x\n",
                       channel, data, status );
                return -EPROTO_COMMAND_DATA;
        }

        return 0;
}
static int guestrpc_reply_len ( int  channel,
uint16_t reply_id 
) [static]

Receive GuestRPC reply length.

Parameters:
channelChannel number
Return values:
reply_idReply ID
lenReply length, or negative error

Definition at line 142 of file guestrpc.c.

References DBGC, EPROTO_REPLY_LEN, GUESTRPC_MAGIC, GUESTRPC_REPLY_LEN, GUESTRPC_REPLY_LEN_SUCCESS, len, and status.

Referenced by guestrpc_command().

                                                                  {
        uint32_t len;
        uint32_t status;

        /* Issue GuestRPC command */
        status = vmware_cmd_guestrpc ( channel, GUESTRPC_REPLY_LEN, 0,
                                       reply_id, &len );
        if ( status != GUESTRPC_REPLY_LEN_SUCCESS ) {
                DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d receive reply "
                       "length failed: status %08x\n", channel, status );
                return -EPROTO_REPLY_LEN;
        }

        return len;
}
static int guestrpc_reply_data ( int  channel,
uint16_t  reply_id,
uint32_t data 
) [static]

Receive GuestRPC reply data.

Parameters:
channelChannel number
reply_idReply ID
Return values:
dataReply data
rcReturn status code

Definition at line 166 of file guestrpc.c.

References DBGC, EPROTO_REPLY_DATA, GUESTRPC_MAGIC, GUESTRPC_REPLY_DATA, GUESTRPC_REPLY_DATA_SUCCESS, and status.

Referenced by guestrpc_command().

                                                  {
        uint16_t discard_d;
        uint32_t status;

        /* Issue GuestRPC command */
        status = vmware_cmd_guestrpc ( channel, GUESTRPC_REPLY_DATA, reply_id,
                                       &discard_d, data );
        if ( status != GUESTRPC_REPLY_DATA_SUCCESS ) {
                DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d receive reply "
                       "%d data failed: status %08x\n",
                       channel, reply_id, status );
                return -EPROTO_REPLY_DATA;
        }

        return 0;
}
static int guestrpc_reply_finish ( int  channel,
uint16_t  reply_id 
) [static]

Finish receiving GuestRPC reply.

Parameters:
channelChannel number
reply_idReply ID
Return values:
rcReturn status code

Definition at line 191 of file guestrpc.c.

References DBGC, EPROTO_REPLY_FINISH, GUESTRPC_MAGIC, GUESTRPC_REPLY_FINISH, GUESTRPC_REPLY_FINISH_SUCCESS, and status.

Referenced by guestrpc_command().

                                                                    {
        uint16_t discard_d;
        uint32_t discard_b;
        uint32_t status;

        /* Issue GuestRPC command */
        status = vmware_cmd_guestrpc ( channel, GUESTRPC_REPLY_FINISH, reply_id,
                                       &discard_d, &discard_b );
        if ( status != GUESTRPC_REPLY_FINISH_SUCCESS ) {
                DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d finish reply %d "
                       "failed: status %08x\n", channel, reply_id, status );
                return -EPROTO_REPLY_FINISH;
        }

        return 0;
}
void guestrpc_close ( int  channel)

Close GuestRPC channel.

Parameters:
channelChannel number

Definition at line 213 of file guestrpc.c.

References DBGC, GUESTRPC_CLOSE, GUESTRPC_CLOSE_SUCCESS, GUESTRPC_MAGIC, and status.

                                    {
        uint16_t discard_d;
        uint32_t discard_b;
        uint32_t status;

        /* Issue GuestRPC command */
        status = vmware_cmd_guestrpc ( channel, GUESTRPC_CLOSE, 0,
                                       &discard_d, &discard_b );
        if ( status != GUESTRPC_CLOSE_SUCCESS ) {
                DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d close failed: "
                       "status %08x\n", channel, status );
                return;
        }

        DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d closed\n", channel );
}
int guestrpc_command ( int  channel,
const char *  command,
char *  reply,
size_t  reply_len 
)

Issue GuestRPC command.

Parameters:
channelChannel number
commandCommand
replyReply buffer
reply_lenLength of reply buffer
Return values:
lenLength of reply, or negative error

The actual length of the reply will be returned even if the buffer was too small.

Definition at line 242 of file guestrpc.c.

References assert, data, DBGC, DBGC2, DBGC2_HDA, DBGC_HDA, EIO, guestrpc_command_data(), guestrpc_command_len(), GUESTRPC_MAGIC, guestrpc_reply_data(), guestrpc_reply_finish(), guestrpc_reply_len(), GUESTRPC_SUCCESS, len, NULL, rc, status, and strlen().

Referenced by guestinfo_fetch_type(), and vmconsole_putchar().

                                          {
        const uint8_t *command_bytes = ( ( const void * ) command );
        uint8_t *reply_bytes = ( ( void * ) reply );
        size_t command_len = strlen ( command );
        int orig_reply_len = reply_len;
        uint16_t status;
        uint8_t *status_bytes = ( ( void * ) &status );
        size_t status_len = sizeof ( status );
        uint32_t data;
        uint16_t reply_id;
        int len;
        int remaining;
        unsigned int i;
        int rc;

        DBGC2 ( GUESTRPC_MAGIC, "GuestRPC channel %d issuing command:\n",
                channel );
        DBGC2_HDA ( GUESTRPC_MAGIC, 0, command, command_len );

        /* Sanity check */
        assert ( ( reply != NULL ) || ( reply_len == 0 ) );

        /* Send command length */
        if ( ( rc = guestrpc_command_len ( channel, command_len ) ) < 0 )
                return rc;

        /* Send command data */
        while ( command_len ) {
                data = 0;
                for ( i = sizeof ( data ) ; i ; i-- ) {
                        if ( command_len ) {
                                data = ( ( data & ~0xff ) |
                                         *(command_bytes++) );
                                command_len--;
                        }
                        data = ( ( data << 24 ) | ( data >> 8 ) );
                }
                if ( ( rc = guestrpc_command_data ( channel, data ) ) < 0 )
                        return rc;
        }

        /* Receive reply length */
        if ( ( len = guestrpc_reply_len ( channel, &reply_id ) ) < 0 ) {
                rc = len;
                return rc;
        }

        /* Receive reply */
        for ( remaining = len ; remaining > 0 ; remaining -= sizeof ( data ) ) {
                if ( ( rc = guestrpc_reply_data ( channel, reply_id,
                                                  &data ) ) < 0 ) {
                        return rc;
                }
                for ( i = sizeof ( data ) ; i ; i-- ) {
                        if ( status_len ) {
                                *(status_bytes++) = ( data & 0xff );
                                status_len--;
                                len--;
                        } else if ( reply_len ) {
                                *(reply_bytes++) = ( data & 0xff );
                                reply_len--;
                        }
                        data = ( ( data << 24 ) | ( data >> 8 ) );
                }
        }

        /* Finish receiving RPC reply */
        if ( ( rc = guestrpc_reply_finish ( channel, reply_id ) ) < 0 )
                return rc;

        DBGC2 ( GUESTRPC_MAGIC, "GuestRPC channel %d received reply (id %d, "
                "length %d):\n", channel, reply_id, len );
        DBGC2_HDA ( GUESTRPC_MAGIC, 0, &status, sizeof ( status ) );
        DBGC2_HDA ( GUESTRPC_MAGIC, sizeof ( status ), reply,
                    ( ( len < orig_reply_len ) ? len : orig_reply_len ) );

        /* Check reply status */
        if ( status != GUESTRPC_SUCCESS ) {
                DBGC ( GUESTRPC_MAGIC, "GuestRPC channel %d command failed "
                       "(status %04x, reply id %d, reply length %d):\n",
                       channel, status, reply_id, len );
                DBGC_HDA ( GUESTRPC_MAGIC, 0, command, command_len );
                DBGC_HDA ( GUESTRPC_MAGIC, 0, &status, sizeof ( status ) );
                DBGC_HDA ( GUESTRPC_MAGIC, sizeof ( status ), reply,
                           ( ( len < orig_reply_len ) ? len : orig_reply_len ));
                return -EIO;
        }

        return len;
}