Imported Upstream version 3.1.0
[debian/amanda] / ndmp-src / ndmp9.x
diff --git a/ndmp-src/ndmp9.x b/ndmp-src/ndmp9.x
new file mode 100644 (file)
index 0000000..e1c0f1d
--- /dev/null
@@ -0,0 +1,1069 @@
+/*
+ * Copyright (c) 2000,2001
+ *     Traakan, Inc., Los Altos, CA
+ *     All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Project:  NDMJOB
+ * Ident:    $Id: $
+ *
+ * Description:
+ *     NDMPv9, represented here, is a ficticious version
+ *     used internally and never over-the-wire. This
+ *     isolates higher-level routines from variations
+ *     between NDMP protocol version. At this time,
+ *     NDMPv2, NDMPv3 and NDMPv4 are deployed. NDMPv9 tends
+ *     to be bits and pieces of all supported protocol versions
+ *     mashed together.
+ *
+ *     While we want the higher-level routines isolated,
+ *     for clarity we still want them to use data structures
+ *     and construct that resemble NDMP. Higher-level routines
+ *     manipulate NDMPv9 data structures. Mid-level routines
+ *     translate between NDMPv9 and the over-the-wire version
+ *     in use. Low-level routines do the over-the-wire functions.
+ *
+ *     The approach of using the latest version internally
+ *     and retrofiting earlier versions was rejected for
+ *     two reasons. First, it means a tear-up of higher-level
+ *     functions as new versions are deployed. Second,
+ *     it makes building with selected version impossible.
+ *     No matter what approach is taken, there will be
+ *     some sort of retrofit between versions. NDMPv9
+ *     is simply the internal version, and all bona-fide
+ *     versions are retrofitted. v9 was chosen because
+ *     it is unlikely the NDMP version will reach 9
+ *     within the useful life of the NDMP architecture.
+ *
+ *     NDMPv9 could be implemented in a hand-crafted header (.h)
+ *     file, yet we continue to use the ONC RPC (.x) description
+ *     for convenvience. It's easy to cut-n-paste from the other
+ *     NDMP.x files. It's important that ndmp9_xdr.c never be
+ *     generated nor compiled.
+ */
+
+
+/*
+ * (from ndmp3.x)
+ * ndmp.x
+ *
+ * Description  : NDMP protocol rpcgen file.
+ *
+ * Copyright (c) 1999 Intelliguard Software, Network Appliance.
+ * All Rights Reserved.
+ */
+
+/*
+ * (from ndmp2.x)
+ * Copyright (c) 1997 Network Appliance. All Rights Reserved.
+ *
+ * Network Appliance makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+
+const NDMP9VER = 9;
+
+
+/*
+ * General types
+ ****************************************************************
+ */
+
+/*
+ * Error codes
+ */
+enum ndmp9_error {
+       NDMP9_NO_ERR,                   /* No error */
+       NDMP9_NOT_SUPPORTED_ERR,        /* Call is not supported */
+       NDMP9_DEVICE_BUSY_ERR,          /* The device is in use */
+       NDMP9_DEVICE_OPENED_ERR,        /* Another tape or scsi device
+                                        * is already open */
+       NDMP9_NOT_AUTHORIZED_ERR,       /* connection has not been authorized*/
+       NDMP9_PERMISSION_ERR,           /* some sort of permission problem */
+       NDMP9_DEV_NOT_OPEN_ERR,         /* SCSI device is not open */
+       NDMP9_IO_ERR,                   /* I/O error */
+       NDMP9_TIMEOUT_ERR,              /* command timed out */
+       NDMP9_ILLEGAL_ARGS_ERR,         /* illegal arguments in request */
+       NDMP9_NO_TAPE_LOADED_ERR,       /* Cannot open because there is
+                                          no tape loaded */
+       NDMP9_WRITE_PROTECT_ERR,        /* tape cannot be open for write */
+       NDMP9_EOF_ERR,                  /* Command encountered EOF */
+       NDMP9_EOM_ERR,                  /* Command encountered EOM */
+       NDMP9_FILE_NOT_FOUND_ERR,       /* File not found during recover */
+       NDMP9_BAD_FILE_ERR,             /* The file descriptor is invalid */
+       NDMP9_NO_DEVICE_ERR,            /* The device is not at that target */
+       NDMP9_NO_BUS_ERR,               /* Invalid controller */
+       NDMP9_XDR_DECODE_ERR,           /* Can't decode the request argument */
+       NDMP9_ILLEGAL_STATE_ERR,        /* Call can't be done at this state */
+       NDMP9_UNDEFINED_ERR,            /* Undefined Error */
+       NDMP9_XDR_ENCODE_ERR,           /* Can't encode the reply argument */
+       NDMP9_NO_MEM_ERR,               /* no memory */
+       NDMP9_CONNECT_ERR,              /* Error connecting to another
+                                        * NDMP server */
+       NDMP9_SEQUENCE_NUM_ERR,
+       NDMP9_READ_IN_PROGRESS_ERR      = 25,
+       NDMP9_PRECONDITION_ERR          = 26,
+       NDMP9_CLASS_NOT_SUPPORTED       = 27,
+       NDMP9_VERSION_NOT_SUPPORTED     = 28,
+       NDMP9_EXT_DUPL_CLASSES          = 29,
+       NDMP9_EXT_DN_ILLEGAL            = 30
+};
+
+
+/*
+ * Message codes
+ */
+enum ndmp9_message {
+       NDMP9_CONNECT_OPEN = 0x900,     /* CONNECT INTERFACE */
+       NDMP9_CONNECT_CLIENT_AUTH = 0x901,
+       NDMP9_CONNECT_CLOSE = 0x902,
+       NDMP9_CONNECT_SERVER_AUTH = 0x903,
+
+       NDMP9_CONFIG_GET_HOST_INFO = 0x100, /* CONFIG INTERFACE */
+       NDMP9_CONFIG_GET_CONNECTION_TYPE = 0x102, /* NDMP2_CONFIG_GET_MOVER_TYPE on v2*/
+       NDMP9_CONFIG_GET_AUTH_ATTR = 0x103,
+       NDMP9_CONFIG_GET_BUTYPE_INFO = 0x104,   /* NDMPv3 and forward */
+       NDMP9_CONFIG_GET_FS_INFO = 0x105,       /* NDMPv3 and forward */
+       NDMP9_CONFIG_GET_TAPE_INFO = 0x106,     /* NDMPv3 and forward */
+       NDMP9_CONFIG_GET_SCSI_INFO = 0x107,     /* NDMPv3 and forward */
+       NDMP9_CONFIG_GET_SERVER_INFO =0x108,    /* NDMPv3 and forward */
+
+       NDMP9_SCSI_OPEN = 0x200,        /* SCSI INTERFACE */
+       NDMP9_SCSI_CLOSE = 0x201,
+       NDMP9_SCSI_GET_STATE = 0x202,
+       NDMP9_SCSI_SET_TARGET = 0x203,
+       NDMP9_SCSI_RESET_DEVICE = 0x204,
+       NDMP9_SCSI_RESET_BUS = 0x205,
+       NDMP9_SCSI_EXECUTE_CDB = 0x206,
+
+       NDMP9_TAPE_OPEN = 0x300,        /* TAPE INTERFACE */
+       NDMP9_TAPE_CLOSE = 0x301,
+       NDMP9_TAPE_GET_STATE = 0x302,
+       NDMP9_TAPE_MTIO = 0x303,
+       NDMP9_TAPE_WRITE = 0x304,
+       NDMP9_TAPE_READ = 0x305,
+       NDMP9_TAPE_EXECUTE_CDB = 0x307,
+
+       NDMP9_DATA_GET_STATE = 0x400,   /* DATA INTERFACE */
+       NDMP9_DATA_START_BACKUP = 0x401,
+       NDMP9_DATA_START_RECOVER = 0x402,
+       NDMP9_DATA_ABORT = 0x403,
+       NDMP9_DATA_GET_ENV = 0x404,
+       NDMP9_DATA_STOP = 0x407,
+       NDMP9_DATA_LISTEN = 0x409,
+       NDMP9_DATA_CONNECT = 0x40a,
+       NDMP9_DATA_START_RECOVER_FILEHIST = 0x40b,
+
+       NDMP9_NOTIFY_DATA_HALTED =0x501,/* NOTIFY INTERFACE */
+       NDMP9_NOTIFY_CONNECTED = 0x502,
+       NDMP9_NOTIFY_MOVER_HALTED = 0x503,
+       NDMP9_NOTIFY_MOVER_PAUSED = 0x504,
+       NDMP9_NOTIFY_DATA_READ =0x505,
+
+       NDMP9_LOG_FILE = 0x602,         /* LOGGING INTERFACE */
+       NDMP9_LOG_MESSAGE = 0x603,
+
+       NDMP9_FH_ADD_FILE = 0x703,      /* FILE HISTORY INTERFACE */
+       NDMP9_FH_ADD_DIR = 0x704,
+       NDMP9_FH_ADD_NODE = 0x705,
+
+       NDMP9_MOVER_GET_STATE = 0xa00,  /* MOVER INTERFACE */
+       NDMP9_MOVER_LISTEN = 0xa01,
+       NDMP9_MOVER_CONTINUE = 0xa02,
+       NDMP9_MOVER_ABORT = 0xa03,
+       NDMP9_MOVER_STOP = 0xa04,
+       NDMP9_MOVER_SET_WINDOW = 0xa05,
+       NDMP9_MOVER_READ = 0xa06,
+       NDMP9_MOVER_CLOSE =0xa07,
+       NDMP9_MOVER_SET_RECORD_SIZE =0xa08,
+       NDMP9_MOVER_CONNECT =0xa09
+};
+
+
+/*
+ * Common message bodies
+ */
+%extern bool_t xdr_ndmp9_no_arguments();
+%#define ndmp9_no_arguments int
+
+struct ndmp9_just_error_reply {
+       ndmp9_error     error;
+};
+
+
+/*
+ * 64-bit integers
+ */
+%extern bool_t xdr_ndmp9_u_quad();
+%#define ndmp9_u_quad unsigned long long
+
+/*
+ * Valid values. Sometimes we have values, and sometimes we don't.
+ */
+enum ndmp9_validity {
+       NDMP9_VALIDITY_INVALID = 0,
+       NDMP9_VALIDITY_VALID,
+       NDMP9_VALIDITY_MAYBE_INVALID,
+       NDMP9_VALIDITY_MAYBE_VALID
+};
+
+%#define NDMP9_INVALID_U_LONG  0xFFFFFFFFul
+struct ndmp9_valid_u_long {
+       ndmp9_validity  valid;
+       u_long          value;
+};
+
+%#define NDMP9_INVALID_U_QUAD  0xFFFFFFFFFFFFFFFFull
+struct ndmp9_valid_u_quad {
+       ndmp9_validity  valid;
+       ndmp9_u_quad    value;
+};
+
+
+/*
+ * Property values. A simple name/value pair. Used in lots of places.
+ */
+struct ndmp9_pval {
+       string          name<>;
+       string          value<>;
+};
+
+
+/*
+ * Authorization data. Three authorization types each
+ * with their particular values. Authorization is done
+ * in three steps:
+ *     1) Client determines which types of authorization are available
+ *        on the server.
+ *     2) Client may get parameters (challenge) from server.
+ *     3) Client requests authorization based on a shared
+ *        secret (password) with parameters (challenge) applied.
+ */
+enum ndmp9_auth_type {
+       NDMP9_AUTH_NONE,                /* no password is required */
+       NDMP9_AUTH_TEXT,                /* the clear text password */
+       NDMP9_AUTH_MD5                  /* md5 */
+};
+
+union ndmp9_auth_attr switch (enum ndmp9_auth_type auth_type) {
+       case NDMP9_AUTH_NONE:
+               void;
+       case NDMP9_AUTH_TEXT:
+               void;
+       case NDMP9_AUTH_MD5:
+               opaque  challenge[64];
+};
+
+struct ndmp9_auth_text {
+       string          auth_id<>;      /* account/user name */
+       string          auth_password<>; /* clear-text password */
+};
+
+struct ndmp9_auth_md5 {
+       string          auth_id<>;      /* account/user name */
+       opaque          auth_digest[16]; /* MD5 "hashed" password */
+};
+
+union ndmp9_auth_data switch (enum ndmp9_auth_type auth_type) {
+       case NDMP9_AUTH_NONE:
+               void;
+       case NDMP9_AUTH_TEXT:
+               struct ndmp9_auth_text  auth_text;
+       case NDMP9_AUTH_MD5:
+               struct ndmp9_auth_md5   auth_md5;
+};
+
+
+/*
+ * The data connection (data stream, image stream, big ol' pipe)
+ * has two endpoints, Once side instigates the connection (connects),
+ * the other side receives the connection (listen/accept).
+ * Appears in DATA and MOVER interfaces.
+ */
+enum ndmp9_addr_type {
+       NDMP9_ADDR_LOCAL,
+       NDMP9_ADDR_TCP,
+       /* IPC and FC addr types contemplated but never deployed */
+       NDMP9_ADDR_AS_CONNECTED = 0x1000
+};
+
+struct ndmp9_tcp_addr {
+       u_long          ip_addr;
+       u_short         port;
+};
+
+union ndmp9_addr switch (ndmp9_addr_type addr_type) {
+       case NDMP9_ADDR_LOCAL:
+       case NDMP9_ADDR_AS_CONNECTED:
+               void;
+       case NDMP9_ADDR_TCP:
+               ndmp9_tcp_addr  tcp_addr;
+};
+
+
+
+
+/*
+ * CONNECT INTERFACE
+ ****************************************************************
+ *
+ * The CONNECT INTERFACE is used to condition and authorize
+ * the control connection from the CONTROL Agent (DMA, Client)
+ * to the DATA, TAPE, or SCSI Agent (DSP, Servers).
+ *
+ * Most of this is addressed by NDMP0 (zero), which is a companion
+ * ficticious version. The NDMP0 features must never change to
+ * support protocol version negotiation. Once the version is
+ * negotiated, subsequent negotiations and authorization can
+ * take place.
+ */
+
+/* NDMP9_CONNECT_OPEN -- must never change, negotiate protocol version */
+struct ndmp9_connect_open_request {
+       u_short protocol_version;       /* the version of protocol supported */
+};
+typedef ndmp9_just_error_reply ndmp9_connect_open_reply;
+
+/* NDMP9_CONNECT_CLIENT_AUTH -- authorize client */
+struct ndmp9_connect_client_auth_request {
+       ndmp9_auth_data auth_data;
+};
+typedef ndmp9_just_error_reply ndmp9_connect_client_auth_reply;
+
+
+/* NDMP9_CONNECT_CLOSE -- must never change, terminate control connection */
+typedef ndmp9_no_arguments     ndmp9_connect_close_request;
+typedef ndmp9_no_arguments     ndmp9_connect_close_reply;
+
+/* NDMP9_CONNECT_SERVER_AUTH -- once client is authorized, ask server to
+ * prove itself -- nobody is using this */
+struct ndmp9_connect_server_auth_request {
+       ndmp9_auth_attr         client_attr;
+};
+
+struct ndmp9_connect_server_auth_reply {
+       ndmp9_error             error;
+       ndmp9_auth_data         server_result;
+};
+
+
+/*
+ * CONFIG INTERFACE
+ ****************************************************************
+ *
+ * The CONFIG interfaces allow the CONTROL Agent (DMA, client) to
+ * obtain resource and other information from the DATA/TAPE/SCSI
+ * Agent (DSP, server).
+ *
+ * For NDMPv9, the whole show is lumped into a single data structure.
+ * The specific CONFIG interfaces, which vary between versions,
+ * pick-n-choose the info needed.
+ */
+
+struct ndmp9_butype_info {
+       string                  butype_name<>;
+       ndmp9_valid_u_long      v2attr;
+       ndmp9_valid_u_long      v3attr;
+       ndmp9_valid_u_long      v4attr;
+       ndmp9_pval              default_env<>;
+};
+
+struct ndmp9_fs_info {
+       string                  fs_type<>;
+       string                  fs_logical_device<>;
+       string                  fs_physical_device<>;
+       ndmp9_valid_u_quad      total_size;
+       ndmp9_valid_u_quad      used_size;
+       ndmp9_valid_u_quad      avail_size;
+       ndmp9_valid_u_quad      total_inodes;
+       ndmp9_valid_u_quad      used_inodes;
+       ndmp9_pval              fs_env<>;
+       string                  fs_status<>;
+};
+
+struct ndmp9_device_capability {
+       string                  device<>;
+       ndmp9_valid_u_long      v3attr;
+       ndmp9_valid_u_long      v4attr;
+       ndmp9_pval              capability<>;
+};
+
+struct ndmp9_device_info {
+       string                  model<>;
+       ndmp9_device_capability caplist<>;
+};
+
+const NDMP9_CONFIG_CONNTYPE_LOCAL      = 0x0001;
+const NDMP9_CONFIG_CONNTYPE_TCP                = 0x0002;
+
+const NDMP9_CONFIG_AUTHTYPE_NONE       = 0x0001;
+const NDMP9_CONFIG_AUTHTYPE_TEXT       = 0x0002;
+const NDMP9_CONFIG_AUTHTYPE_MD5                = 0x0004;
+
+struct ndmp9_config_info {
+       ndmp9_error             error;
+
+       /* ndmp[23]_config_get_host_info_reply */
+       string                  hostname<>; /* host name */
+       string                  os_type<>;  /* The O/S type (e.g. SOLARIS) */
+       string                  os_vers<>;  /* The O/S version (e.g. 2.5) */
+       string                  hostid<>;
+
+       /* ndmp[34]_config_get_server_info_reply */
+       string                  vendor_name<>;
+       string                  product_name<>;
+       string                  revision_number<>;
+
+       /* ndmp2_config_get_host_info */
+       /* ndmp[34]_config_get_server_info */
+       u_long                  authtypes;
+
+       /* ndmp2_config_get_mover_type */
+       /* ndmp[34]_config_get_connection_type */
+       u_long                  conntypes;
+
+       /* ndmp2_config_get_butype_attr */
+       /* ndmp[34]_config_get_butype_info */
+       ndmp9_butype_info       butype_info<>;
+
+       /* ndmp[34]_config_get_fs_info */
+       ndmp9_fs_info           fs_info<>;
+
+       /* ndmp[34]_config_get_tape_info */
+       ndmp9_device_info       tape_info<>;
+
+       /* ndmp[34]_config_get_scsi_info */
+       ndmp9_device_info       scsi_info<>;
+};
+
+/* NDMP9_CONFIG_GET_INFO */
+typedef ndmp9_no_arguments     ndmp9_config_get_info_request;
+struct ndmp9_config_get_info_reply {
+       ndmp9_error             error;
+       ndmp9_config_info       config_info;
+};
+
+/* NDMP9_CONFIG_GET_HOST_INFO */
+typedef ndmp9_no_arguments     ndmp9_config_get_host_info_request;
+typedef ndmp9_config_get_info_reply ndmp9_config_get_host_info_reply;
+
+/* NDMP9_CONFIG_GET_CONNECTION_TYPE */
+typedef ndmp9_no_arguments     ndmp9_config_get_connection_type_request;
+typedef ndmp9_config_get_info_reply ndmp9_config_get_connection_type_reply;
+
+/* NDMP9_CONFIG_GET_SERVER_INFO */
+typedef ndmp9_no_arguments     ndmp9_config_get_server_info_request;
+typedef ndmp9_config_get_info_reply ndmp9_config_get_server_info_reply;
+
+/* NDMP9_CONFIG_GET_BUTYPE_INFO */
+typedef ndmp9_no_arguments     ndmp9_config_get_butype_info_request;
+typedef ndmp9_config_get_info_reply ndmp9_config_get_butype_info_reply;
+
+/* NDMP9_CONFIG_GET_FS_INFO */
+typedef ndmp9_no_arguments     ndmp9_config_get_fs_info_request;
+typedef ndmp9_config_get_info_reply ndmp9_config_get_fs_info_reply;
+
+/* NDMP9_CONFIG_GET_TAPE_INFO */
+typedef ndmp9_no_arguments     ndmp9_config_get_tape_info_request;
+typedef ndmp9_config_get_info_reply ndmp9_config_get_tape_info_reply;
+
+/* NDMP9_CONFIG_GET_SCSI_INFO */
+typedef ndmp9_no_arguments     ndmp9_config_get_scsi_info_request;
+typedef ndmp9_config_get_info_reply ndmp9_config_get_scsi_info_reply;
+
+
+/* NDMP9_CONFIG_GET_AUTH_ATTR */
+struct ndmp9_config_get_auth_attr_request {
+       ndmp9_auth_type         auth_type;
+};
+
+struct ndmp9_config_get_auth_attr_reply {
+       ndmp9_error             error;
+       ndmp9_auth_attr         server_attr;
+};
+
+
+
+/*
+ * SCSI INTERFACE
+ ****************************************************************
+ *
+ * A SCSI pass-thru service. The CONTROL Agent (DMA, Client)
+ * manipulates a SCSI Media Changer through this interface.
+ * It may be used for other purposes.
+ */
+
+/* NDMP9_SCSI_OPEN */
+struct ndmp9_scsi_open_request {
+       string          device<>;
+};
+typedef ndmp9_just_error_reply ndmp9_scsi_open_reply;
+
+/* NDMP9_SCSI_CLOSE */
+typedef ndmp9_no_arguments     ndmp9_scsi_close_request;
+typedef ndmp9_just_error_reply ndmp9_scsi_close_reply;
+
+/* NDMP9_SCSI_GET_STATE */
+typedef ndmp9_no_arguments     ndmp9_scsi_get_state_request;
+struct ndmp9_scsi_get_state_reply {
+       ndmp9_error     error;
+       short           target_controller;
+       short           target_id;
+       short           target_lun;
+};
+
+/* NDMP9_SCSI_SET_TARGET -- deleted for NDMPv4 */
+struct ndmp9_scsi_set_target_request {
+       string          device<>;
+       u_short         target_controller;
+       u_short         target_id;
+       u_short         target_lun;
+};
+typedef ndmp9_just_error_reply ndmp9_scsi_set_target_reply;
+
+
+/* NDMP9_SCSI_RESET_DEVICE */
+typedef ndmp9_no_arguments     ndmp9_scsi_reset_device_request;
+typedef ndmp9_just_error_reply ndmp9_scsi_reset_device_reply;
+
+/* NDMP9_SCSI_RESET_BUS -- deleted for NDMPv4 */
+typedef ndmp9_no_arguments     ndmp9_scsi_reset_bus_request;
+typedef ndmp9_just_error_reply ndmp9_scsi_reset_bus_reply;
+
+
+/* NDMP9_SCSI_EXECUTE_CDB */
+enum ndmp9_scsi_data_dir {
+       NDMP9_SCSI_DATA_DIR_NONE = 0,
+       NDMP9_SCSI_DATA_DIR_IN = 1,     /* Expect data from SCSI device */
+       NDMP9_SCSI_DATA_DIR_OUT = 2     /* Transfer data to SCSI device */
+};
+
+struct ndmp9_execute_cdb_request {
+       ndmp9_scsi_data_dir     data_dir;
+       u_long                  timeout;
+       u_long                  datain_len;     /* Set for expected datain */
+       opaque                  cdb<>;
+       opaque                  dataout<>;
+};
+
+struct ndmp9_execute_cdb_reply {
+       ndmp9_error     error;
+       u_char          status;         /* SCSI status bytes */
+       u_long          dataout_len;
+       opaque          datain<>;       /* SCSI datain */
+       opaque          ext_sense<>;    /* Extended sense data */
+};
+
+typedef ndmp9_execute_cdb_request      ndmp9_scsi_execute_cdb_request;
+typedef ndmp9_execute_cdb_reply                ndmp9_scsi_execute_cdb_reply;
+
+
+
+/******************/
+/* TAPE INTERFACE */
+/******************/
+/* NDMP9_TAPE_OPEN */
+enum ndmp9_tape_open_mode {
+       NDMP9_TAPE_READ_MODE,
+       NDMP9_TAPE_RDWR_MODE,
+       NDMP9_TAPE_RAW_MODE             /* new for NDMPv4 */
+};
+
+enum ndmp9_tape_state {
+       NDMP9_TAPE_STATE_IDLE,          /* not doing anything */
+       NDMP9_TAPE_STATE_OPEN,          /* open, tape operations OK */
+       NDMP9_TAPE_STATE_MOVER          /* mover active, tape ops locked out */
+                                       /* ie read, write, mtio, close, cdb */
+};
+
+struct ndmp9_tape_open_request {
+       string                  device<>;
+       ndmp9_tape_open_mode    mode;
+};
+typedef ndmp9_just_error_reply ndmp9_tape_open_reply;
+
+/* NDMP9_TAPE_CLOSE */
+typedef ndmp9_no_arguments     ndmp9_tape_close_request;
+typedef ndmp9_just_error_reply ndmp9_tape_close_reply;
+
+
+/* NDMP9_TAPE_GET_STATE */
+const NDMP9_TAPE_STATE_NOREWIND        = 0x0008;       /* non-rewind device */
+const NDMP9_TAPE_STATE_WR_PROT = 0x0010;       /* write-protected */
+const NDMP9_TAPE_STATE_ERROR   = 0x0020;       /* media error */
+const NDMP9_TAPE_STATE_UNLOAD  = 0x0040;       /* tape will be unloaded when
+                                                * the device is closed */
+
+typedef ndmp9_no_arguments     ndmp9_tape_get_state_request;
+struct ndmp9_tape_get_state_reply {
+       ndmp9_error             error;
+       u_long                  flags;          /* compatible NDMP[2349] */
+       ndmp9_tape_state        state;
+       ndmp9_tape_open_mode    open_mode;
+       ndmp9_valid_u_long      file_num;
+       ndmp9_valid_u_long      soft_errors;
+       ndmp9_valid_u_long      block_size;
+       ndmp9_valid_u_long      blockno;
+       ndmp9_valid_u_quad      total_space;
+       ndmp9_valid_u_quad      space_remain;
+       ndmp9_valid_u_long      partition;
+};
+
+/* NDMP9_TAPE_MTIO */
+enum ndmp9_tape_mtio_op {
+       NDMP9_MTIO_FSF,
+       NDMP9_MTIO_BSF,
+       NDMP9_MTIO_FSR,
+       NDMP9_MTIO_BSR,
+       NDMP9_MTIO_REW,
+       NDMP9_MTIO_EOF,
+       NDMP9_MTIO_OFF
+};
+
+struct ndmp9_tape_mtio_request {
+       ndmp9_tape_mtio_op      tape_op;
+       u_long                  count;
+};
+
+struct ndmp9_tape_mtio_reply {
+       ndmp9_error     error;
+       u_long          resid_count;
+};
+
+
+/* NDMP9_TAPE_WRITE */
+struct ndmp9_tape_write_request {
+       opaque          data_out<>;
+};
+
+struct ndmp9_tape_write_reply {
+       ndmp9_error     error;
+       u_long          count;
+};
+
+
+/* NDMP9_TAPE_READ */
+struct ndmp9_tape_read_request {
+       u_long          count;
+};
+
+struct ndmp9_tape_read_reply {
+       ndmp9_error     error;
+       opaque          data_in<>;
+};
+
+/* NDMP9_TAPE_EXECUTE_CDB */
+typedef ndmp9_execute_cdb_request      ndmp9_tape_execute_cdb_request;
+typedef ndmp9_execute_cdb_reply                ndmp9_tape_execute_cdb_reply;
+
+
+
+
+/********************************/
+/* MOVER INTERFACE              */
+/********************************/
+enum ndmp9_mover_state {
+       NDMP9_MOVER_STATE_IDLE,
+       NDMP9_MOVER_STATE_LISTEN,
+       NDMP9_MOVER_STATE_ACTIVE,
+       NDMP9_MOVER_STATE_PAUSED,
+       NDMP9_MOVER_STATE_HALTED,
+       NDMP9_MOVER_STATE_STANDBY       /* awaiting mover_read_request */
+};
+
+enum ndmp9_mover_mode {
+       NDMP9_MOVER_MODE_READ,  /* read from data conn; write to tape */
+       NDMP9_MOVER_MODE_WRITE  /* write to data conn; read from tape */
+};
+
+enum ndmp9_mover_pause_reason {
+       NDMP9_MOVER_PAUSE_NA,
+       NDMP9_MOVER_PAUSE_EOM,
+       NDMP9_MOVER_PAUSE_EOF,
+       NDMP9_MOVER_PAUSE_SEEK,
+       NDMP9_MOVER_PAUSE_MEDIA_ERROR,
+       NDMP9_MOVER_PAUSE_EOW
+};
+
+enum ndmp9_mover_halt_reason {
+       NDMP9_MOVER_HALT_NA,
+       NDMP9_MOVER_HALT_CONNECT_CLOSED,
+       NDMP9_MOVER_HALT_ABORTED,
+       NDMP9_MOVER_HALT_INTERNAL_ERROR,
+       NDMP9_MOVER_HALT_CONNECT_ERROR,
+       NDMP9_MOVER_HALT_MEDIA_ERROR
+};
+
+/* NDMP9_MOVER_GET_STATE */
+typedef ndmp9_no_arguments     ndmp9_mover_get_state_request;
+struct ndmp9_mover_get_state_reply {
+       ndmp9_error             error;
+       ndmp9_mover_state       state;
+       ndmp9_mover_mode        mode;
+       ndmp9_mover_pause_reason pause_reason;
+       ndmp9_mover_halt_reason halt_reason;
+       u_long                  record_size;
+       u_long                  record_num;
+       ndmp9_u_quad            bytes_moved;
+       ndmp9_u_quad            seek_position;
+       ndmp9_u_quad            bytes_left_to_read;
+       ndmp9_u_quad            window_offset;
+       ndmp9_u_quad            window_length;
+       ndmp9_addr              data_connection_addr;
+};
+
+/* NDMP9_MOVER_LISTEN */
+struct ndmp9_mover_listen_request {
+       ndmp9_mover_mode        mode;
+       ndmp9_addr_type         addr_type;
+};
+
+struct ndmp9_mover_listen_reply {
+       ndmp9_error             error;
+       ndmp9_addr              data_connection_addr;
+};
+
+/* NDMP9_MOVER_CONNECT */
+struct ndmp9_mover_connect_request {
+       ndmp9_mover_mode        mode;
+       ndmp9_addr              addr;
+};
+typedef ndmp9_just_error_reply ndmp9_mover_connect_reply;
+
+/* NDMP9_MOVER_SET_RECORD_SIZE */
+struct ndmp9_mover_set_record_size_request {
+       u_long                  record_size;
+};
+typedef ndmp9_just_error_reply ndmp9_mover_set_record_size_reply;
+
+/* NDMP9_MOVER_SET_WINDOW */
+struct ndmp9_mover_set_window_request {
+       ndmp9_u_quad    offset;
+       ndmp9_u_quad    length;
+};
+typedef ndmp9_just_error_reply ndmp9_mover_set_window_reply;
+
+/* NDMP9_MOVER_CONTINUE */
+typedef ndmp9_no_arguments     ndmp9_mover_continue_request;
+typedef ndmp9_just_error_reply ndmp9_mover_continue_reply;
+
+
+/* NDMP9_MOVER_ABORT */
+typedef ndmp9_no_arguments     ndmp9_mover_abort_request;
+typedef ndmp9_just_error_reply ndmp9_mover_abort_reply;
+
+/* NDMP9_MOVER_STOP */
+typedef ndmp9_no_arguments     ndmp9_mover_stop_request;
+typedef ndmp9_just_error_reply ndmp9_mover_stop_reply;
+
+/* NDMP9_MOVER_READ */
+struct ndmp9_mover_read_request {
+       ndmp9_u_quad    offset;
+       ndmp9_u_quad    length;
+};
+typedef ndmp9_just_error_reply ndmp9_mover_read_reply;
+
+/* NDMP9_MOVER_CLOSE */
+typedef ndmp9_no_arguments     ndmp9_mover_close_request;
+typedef ndmp9_just_error_reply ndmp9_mover_close_reply;
+
+
+
+
+/****************************/
+/* DATA INTERFACE          */
+/****************************/
+
+enum ndmp9_data_operation {
+       NDMP9_DATA_OP_NOACTION,
+       NDMP9_DATA_OP_BACKUP,
+       NDMP9_DATA_OP_RECOVER,
+       NDMP9_DATA_OP_RECOVER_FILEHIST
+};
+
+enum ndmp9_data_state {
+       NDMP9_DATA_STATE_IDLE,
+       NDMP9_DATA_STATE_ACTIVE,
+       NDMP9_DATA_STATE_HALTED,
+       NDMP9_DATA_STATE_LISTEN,
+       NDMP9_DATA_STATE_CONNECTED
+};
+
+enum ndmp9_data_halt_reason {
+       NDMP9_DATA_HALT_NA,
+       NDMP9_DATA_HALT_SUCCESSFUL,
+       NDMP9_DATA_HALT_ABORTED,
+       NDMP9_DATA_HALT_INTERNAL_ERROR,
+       NDMP9_DATA_HALT_CONNECT_ERROR
+};
+
+/* NDMP9_DATA_START_BACKUP */
+typedef ndmp9_no_arguments     ndmp9_data_get_state_request;
+struct ndmp9_data_get_state_reply {
+       ndmp9_error             error;
+       ndmp9_data_operation    operation;
+       ndmp9_data_state        state;
+       ndmp9_data_halt_reason  halt_reason;
+       ndmp9_u_quad            bytes_processed;
+       ndmp9_valid_u_quad      est_bytes_remain;
+       ndmp9_valid_u_long      est_time_remain;
+       ndmp9_addr              data_connection_addr;
+       ndmp9_u_quad            read_offset;
+       ndmp9_u_quad            read_length;
+};
+
+struct ndmp9_name {
+       string                  original_path<>; /* relative to backup root */
+       string                  destination_path<>;
+       /* nt_destination_path<> */
+       ndmp9_valid_u_quad      fh_info;
+};
+
+
+
+/* NDMP9_DATA_START_BACKUP */
+struct ndmp9_data_start_backup_request {
+       string          bu_type<>;      /* backup method to use */
+       ndmp9_pval      env<>;          /* Parameters that may modify backup */
+       ndmp9_addr      addr;
+};
+typedef ndmp9_just_error_reply ndmp9_data_start_backup_reply;
+
+/* NDMP9_DATA_START_RECOVER */
+struct ndmp9_data_start_recover_request {
+       ndmp9_pval      env<>;
+       ndmp9_name      nlist<>;
+       string          bu_type<>;
+       ndmp9_addr      addr;
+};
+typedef ndmp9_just_error_reply ndmp9_data_start_recover_reply;
+
+/* NDMP9_DATA_START_RECOVER_FILEHIST */
+typedef ndmp9_data_start_recover_request ndmp9_data_start_recover_filehist_request;
+typedef ndmp9_data_start_recover_reply ndmp9_data_start_recover_filehist_reply;
+
+
+/* NDMP9_DATA_ABORT */
+typedef ndmp9_no_arguments     ndmp9_data_abort_request;
+typedef ndmp9_just_error_reply ndmp9_data_abort_reply;
+
+/* NDMP9_DATA_STOP */
+typedef ndmp9_no_arguments     ndmp9_data_stop_request;
+typedef ndmp9_just_error_reply ndmp9_data_stop_reply;
+
+/* NDMP9_DATA_GET_ENV */
+typedef ndmp9_no_arguments     ndmp9_data_get_env_request;
+struct ndmp9_data_get_env_reply {
+       ndmp9_error     error;
+       ndmp9_pval      env<>;
+};
+
+/* NDMP9_DATA_LISTEN */
+struct ndmp9_data_listen_request {
+       ndmp9_addr_type addr_type;
+};
+
+struct ndmp9_data_listen_reply {
+       ndmp9_error     error;
+       ndmp9_addr      data_connection_addr;
+};
+
+/* NDMP9_DATA_CONNECT */
+struct ndmp9_data_connect_request {
+       ndmp9_addr      addr;
+};
+typedef ndmp9_just_error_reply ndmp9_data_connect_reply;
+
+
+
+
+/****************************/
+/* NOTIFY INTERFACE        */
+/****************************/
+
+/* NDMP9_NOTIFY_DATA_HALTED */
+struct ndmp9_notify_data_halted_request {
+       ndmp9_data_halt_reason  reason;
+};
+
+enum ndmp9_connect_reason {
+       NDMP9_CONNECTED,        /* Connect sucessfully */
+       NDMP9_SHUTDOWN,         /* Connection shutdown */
+       NDMP9_REFUSED           /* reach the maximum number of connections */
+};
+
+/* NDMP9_NOTIFY_CONNECTED */
+struct ndmp9_notify_connected_request {
+       ndmp9_connect_reason    reason;
+       u_short                 protocol_version;
+       string                  text_reason<>;
+};
+
+/* NDMP9_NOTIFY_MOVER_HALTED */
+struct ndmp9_notify_mover_halted_request {
+       ndmp9_mover_halt_reason reason;
+};
+
+/* NDMP9_NOTIFY_MOVER_PAUSED */
+struct ndmp9_notify_mover_paused_request {
+       ndmp9_mover_pause_reason reason;
+       ndmp9_u_quad            seek_position;
+};
+
+/* NDMP9_NOTIFY_DATA_READ */
+struct ndmp9_notify_data_read_request {
+       ndmp9_u_quad    offset;
+       ndmp9_u_quad    length;
+};
+
+
+/********************************/
+/* LOG INTERFACE               */
+/********************************/
+/* NDMP9_LOG_MESSAGE */
+enum ndmp9_log_type {
+       NDMP9_LOG_NORMAL,
+       NDMP9_LOG_DEBUG,
+       NDMP9_LOG_ERROR,
+       NDMP9_LOG_WARNING
+};
+
+struct ndmp9_log_message_request {
+       ndmp9_log_type          log_type;
+       u_long                  message_id;
+       string                  entry<>;
+       ndmp9_valid_u_long      associated_message_sequence;
+};
+/* No reply */
+
+enum ndmp9_recovery_status {
+       NDMP9_RECOVERY_SUCCESSFUL             = 0,
+       NDMP9_RECOVERY_FAILED_PERMISSION      = 1,
+       NDMP9_RECOVERY_FAILED_NOT_FOUND       = 2,
+       NDMP9_RECOVERY_FAILED_NO_DIRECTORY    = 3,
+       NDMP9_RECOVERY_FAILED_OUT_OF_MEMORY   = 4,
+       NDMP9_RECOVERY_FAILED_IO_ERROR        = 5,
+       NDMP9_RECOVERY_FAILED_UNDEFINED_ERROR = 6
+};
+
+/* NDMP9_LOG_FILE */
+struct ndmp9_log_file_request {
+       string                  name<>;
+       ndmp9_recovery_status   recovery_status;
+};
+/* No reply */
+
+
+
+/*
+ * FILE HISTORY INTERFACES
+ ****************************************************************
+ */
+
+
+enum ndmp9_file_type {
+       NDMP9_FILE_DIR,
+       NDMP9_FILE_FIFO,
+       NDMP9_FILE_CSPEC,
+       NDMP9_FILE_BSPEC,
+       NDMP9_FILE_REG,
+       NDMP9_FILE_SLINK,
+       NDMP9_FILE_SOCK,
+       NDMP9_FILE_REGISTRY,
+       NDMP9_FILE_OTHER
+};
+
+struct ndmp9_file_stat {
+       ndmp9_file_type         ftype;
+       ndmp9_valid_u_long      mtime;
+       ndmp9_valid_u_long      atime;
+       ndmp9_valid_u_long      ctime;
+       ndmp9_valid_u_long      uid;
+       ndmp9_valid_u_long      gid;
+       ndmp9_valid_u_long      mode;
+       ndmp9_valid_u_quad      size;
+       ndmp9_valid_u_long      links;
+
+       /*
+        * Add NT attributes here as ndmp9_valid_....
+        */
+
+       ndmp9_valid_u_quad      node;       /* id on disk at backup time */
+       ndmp9_valid_u_quad      fh_info;    /* id on tape at backup time */
+};
+
+
+/*
+ * ndmp_fh_add_file
+ * no reply
+ */
+struct ndmp9_file {
+       string                  unix_path<>;
+       /* nt_path<> here */
+       /* dos_path<> here */
+       ndmp9_file_stat         fstat;
+};
+
+struct ndmp9_fh_add_file_request {
+       ndmp9_file              files<>;
+};
+
+
+/*
+ * ndmp_fh_add_dir
+ * no reply
+ */
+struct ndmp9_dir {
+       string                  unix_name<>;
+       /* nt_name<> here */
+       /* dos_name<> here */
+       ndmp9_u_quad            node;
+       ndmp9_u_quad            parent;
+};
+
+struct ndmp9_fh_add_dir_request {
+       ndmp9_dir               dirs<>;
+};
+
+
+/*
+ * ndmp_fh_add_node
+ * no reply
+ */
+struct ndmp9_node {
+       ndmp9_file_stat         fstat;
+};
+
+struct ndmp9_fh_add_node_request {
+       ndmp9_node              nodes<>;
+};
+/* No reply */