aboutsummaryrefslogtreecommitdiff
path: root/src/include/ipxe
diff options
context:
space:
mode:
authorMarin Hannache <git@mareo.fr>2013-07-15 17:56:29 +0200
committerMichael Brown <mcb30@ipxe.org>2013-07-15 17:56:29 +0200
commit30de9e8300e97c4b56e29f5a3b08e4615b30606f (patch)
tree48d66fac04d1a3eb129e878c2696f9afef2f6e8f /src/include/ipxe
parented28c8304c1653a340088137966fff56bae15ad0 (diff)
downloadipxe-30de9e8300e97c4b56e29f5a3b08e4615b30606f.zip
ipxe-30de9e8300e97c4b56e29f5a3b08e4615b30606f.tar.gz
ipxe-30de9e8300e97c4b56e29f5a3b08e4615b30606f.tar.bz2
[nfs] Add support for NFS protocol
Tested-by: Robin Smidsrød <robin@smidsrod.no> Signed-off-by: Marin Hannache <git@mareo.fr> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include/ipxe')
-rw-r--r--src/include/ipxe/dhcp.h12
-rw-r--r--src/include/ipxe/errfile.h6
-rw-r--r--src/include/ipxe/features.h1
-rw-r--r--src/include/ipxe/mount.h76
-rw-r--r--src/include/ipxe/nfs.h157
-rw-r--r--src/include/ipxe/nfs_open.h12
-rw-r--r--src/include/ipxe/oncrpc.h128
-rw-r--r--src/include/ipxe/oncrpc_iob.h102
-rw-r--r--src/include/ipxe/portmap.h63
-rw-r--r--src/include/ipxe/uri.h18
10 files changed, 571 insertions, 4 deletions
diff --git a/src/include/ipxe/dhcp.h b/src/include/ipxe/dhcp.h
index b97dfe3..6c02846 100644
--- a/src/include/ipxe/dhcp.h
+++ b/src/include/ipxe/dhcp.h
@@ -450,6 +450,18 @@ struct dhcp_netdev_desc {
*/
#define DHCP_EB_REVERSE_PASSWORD DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc1 )
+/** User ID
+ *
+ * This will be used as the user id for AUTH_SYS based authentication in NFS.
+ */
+#define DHCP_EB_UID DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc2 )
+
+/** Group ID
+ *
+ * This will be used as the group id for AUTH_SYS based authentication in NFS.
+ */
+#define DHCP_EB_GID DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xc3 )
+
/** iPXE version number */
#define DHCP_EB_VERSION DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xeb )
diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h
index aad3f35..0fd3fac 100644
--- a/src/include/ipxe/errfile.h
+++ b/src/include/ipxe/errfile.h
@@ -208,6 +208,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_fcoe ( ERRFILE_NET | 0x002e0000 )
#define ERRFILE_fcns ( ERRFILE_NET | 0x002f0000 )
#define ERRFILE_vlan ( ERRFILE_NET | 0x00300000 )
+#define ERRFILE_oncrpc ( ERRFILE_NET | 0x00310000 )
+#define ERRFILE_portmap ( ERRFILE_NET | 0x00320000 )
+#define ERRFILE_nfs ( ERRFILE_NET | 0x00330000 )
+#define ERRFILE_nfs_open ( ERRFILE_NET | 0x00340000 )
+#define ERRFILE_mount ( ERRFILE_NET | 0x00350000 )
+#define ERRFILE_oncrpc_iob ( ERRFILE_NET | 0x00360000 )
#define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 )
#define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 )
diff --git a/src/include/ipxe/features.h b/src/include/ipxe/features.h
index 0c92f5b..d8b8b21 100644
--- a/src/include/ipxe/features.h
+++ b/src/include/ipxe/features.h
@@ -54,6 +54,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define DHCP_EB_FEATURE_VLAN 0x26 /**< VLAN support */
#define DHCP_EB_FEATURE_MENU 0x27 /**< Menu support */
#define DHCP_EB_FEATURE_SDI 0x28 /**< SDI image support */
+#define DHCP_EB_FEATURE_NFS 0x29 /**< NFS protocol */
/** @} */
diff --git a/src/include/ipxe/mount.h b/src/include/ipxe/mount.h
new file mode 100644
index 0000000..ca95811
--- /dev/null
+++ b/src/include/ipxe/mount.h
@@ -0,0 +1,76 @@
+#ifndef _IPXE_MOUNT_H
+#define _IPXE_MOUNT_H
+
+#include <ipxe/nfs.h>
+
+/** @file
+ *
+ * NFS MOUNT protocol.
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** NFS MOUNT protocol number */
+#define ONCRPC_MOUNT 100005
+/** NFS MOUNT protocol version */
+#define MOUNT_VERS 3
+
+
+/** No error */
+#define MNT3_OK 0
+/** Not owner */
+#define MNT3ERR_PERM 1
+/** No such file or directory */
+#define MNT3ERR_NOENT 2
+/** I/O error */
+#define MNT3ERR_IO 5
+/** Permission denied */
+#define MNT3ERR_ACCES 13
+/** Not a directory */
+#define MNT3ERR_NOTDIR 20
+/** Invalid argument */
+#define MNT3ERR_INVAL 22
+/** Filename too long */
+#define MNT3ERR_NAMETOOLONG 63
+/** Operation not supported */
+#define MNT3ERR_NOTSUPP 10004
+/** A failure on the server */
+#define MNT3ERR_SERVERFAULT 10006
+
+
+/**
+ * A MOUNT MNT reply
+ *
+ */
+struct mount_mnt_reply {
+ /** Reply status */
+ uint32_t status;
+ /** Root file handle */
+ struct nfs_fh fh;
+};
+
+/**
+ * Prepare an ONC RPC session to be used as a MOUNT session
+ *
+ * @v session ONC RPC session
+ * @v credential ONC RPC credential
+ *
+ * The credential parameter must not be NULL, use 'oncrpc_auth_none' if you
+ * don't want a particular scheme to be used.
+ */
+static inline void mount_init_session ( struct oncrpc_session *session,
+ struct oncrpc_cred *credential ) {
+ oncrpc_init_session ( session, credential, &oncrpc_auth_none,
+ ONCRPC_MOUNT, MOUNT_VERS );
+}
+
+int mount_mnt ( struct interface *intf, struct oncrpc_session *session,
+ const char *mountpoint );
+int mount_umnt ( struct interface *intf, struct oncrpc_session *session,
+ const char *mountpoint );
+
+int mount_get_mnt_reply ( struct mount_mnt_reply *mnt_reply,
+ struct oncrpc_reply *reply );
+
+#endif /* _IPXE_MOUNT_H */
diff --git a/src/include/ipxe/nfs.h b/src/include/ipxe/nfs.h
new file mode 100644
index 0000000..498ed5a
--- /dev/null
+++ b/src/include/ipxe/nfs.h
@@ -0,0 +1,157 @@
+#ifndef _IPXE_NFS_H
+#define _IPXE_NFS_H
+
+#include <stdint.h>
+#include <ipxe/oncrpc.h>
+
+/** @file
+ *
+ * Network File System protocol.
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** NFS protocol number */
+#define ONCRPC_NFS 100003
+
+/** NFS protocol version */
+#define NFS_VERS 3
+
+/** No error*/
+#define NFS3_OK 0
+/** Not owner */
+#define NFS3ERR_PERM 1
+/** No such file or directory */
+#define NFS3ERR_NOENT 2
+/** I/O error */
+#define NFS3ERR_IO 5
+/** No such device or address */
+#define NFS3ERR_NXIO 6
+/** Permission denied */
+#define NFS3ERR_ACCES 13
+/** The file specified already exists */
+#define NFS3ERR_EXIST 17
+/** Attempt to do a cross-device hard link */
+#define NFS3ERR_XDEV 18
+/** No such device */
+#define NFS3ERR_NODEV 19
+/** Not a directory */
+#define NFS3ERR_NOTDIR 20
+ /**Is a directory */
+#define NFS3ERR_ISDIR 21
+/** Invalid argument */
+#define NFS3ERR_INVAL 22
+/** Filename too long */
+#define NFS3ERR_NAMETOOLONG 63
+/** Invalid file handle */
+#define NFS3ERR_STALE 70
+/** Too many levels of remote in path */
+#define NFS3ERR_REMOTE 71
+/** Illegal NFS file handle */
+#define NFS3ERR_BADHANDLE 10001
+/** READDIR or READDIRPLUS cookie is stale */
+#define NFS3ERR_BAD_COOKIE 10003
+/** Operation not supported */
+#define NFS3ERR_NOTSUPP 10004
+/** Buffer or request is too small */
+#define NFS3ERR_TOOSMALL 10005
+/** An error occurred on the server which does not map to any of the legal NFS
+ * version 3 protocol error values */
+#define NFS3ERR_SERVERFAULT 10006
+/** The server initiated the request, but was not able to complete it in a
+ * timely fashion */
+#define NFS3ERR_JUKEBOX 10008
+
+enum nfs_attr_type {
+ NFS_ATTR_SYMLINK = 5,
+};
+
+/**
+ * A NFS file handle
+ *
+ */
+struct nfs_fh {
+ uint8_t fh[64];
+ size_t size;
+};
+
+/**
+ * A NFS LOOKUP reply
+ *
+ */
+struct nfs_lookup_reply {
+ /** Reply status */
+ uint32_t status;
+ /** Entity type */
+ enum nfs_attr_type ent_type;
+ /** File handle */
+ struct nfs_fh fh;
+};
+
+/**
+ * A NFS READLINK reply
+ *
+ */
+struct nfs_readlink_reply {
+ /** Reply status */
+ uint32_t status;
+ /** File path length */
+ uint32_t path_len;
+ /** File path */
+ char *path;
+};
+
+
+/**
+ * A NFS READ reply
+ *
+ */
+struct nfs_read_reply {
+ /** Reply status */
+ uint32_t status;
+ /** File size */
+ uint64_t filesize;
+ /** Bytes read */
+ uint32_t count;
+ /** End-of-File indicator */
+ uint32_t eof;
+ /** Data length */
+ uint32_t data_len;
+ /** Data read */
+ void *data;
+};
+
+size_t nfs_iob_get_fh ( struct io_buffer *io_buf, struct nfs_fh *fh );
+size_t nfs_iob_add_fh ( struct io_buffer *io_buf, const struct nfs_fh *fh );
+
+/**
+ * Prepare an ONC RPC session to be used as a NFS session
+ *
+ * @v session ONC RPC session
+ * @v credential ONC RPC credential
+ *
+ * The credential parameter must not be NULL, use 'oncrpc_auth_none' if you
+ * don't want a particular scheme to be used.
+ */
+static inline void nfs_init_session ( struct oncrpc_session *session,
+ struct oncrpc_cred *credential ) {
+ oncrpc_init_session ( session, credential, &oncrpc_auth_none,
+ ONCRPC_NFS, NFS_VERS );
+}
+
+int nfs_lookup ( struct interface *intf, struct oncrpc_session *session,
+ const struct nfs_fh *fh, const char *filename );
+int nfs_readlink ( struct interface *intf, struct oncrpc_session *session,
+ const struct nfs_fh *fh );
+int nfs_read ( struct interface *intf, struct oncrpc_session *session,
+ const struct nfs_fh *fh, uint64_t offset, uint32_t count );
+
+int nfs_get_lookup_reply ( struct nfs_lookup_reply *lookup_reply,
+ struct oncrpc_reply *reply );
+int nfs_get_readlink_reply ( struct nfs_readlink_reply *readlink_reply,
+ struct oncrpc_reply *reply );
+int nfs_get_read_reply ( struct nfs_read_reply *read_reply,
+ struct oncrpc_reply *reply );
+
+#endif /* _IPXE_NFS_H */
diff --git a/src/include/ipxe/nfs_open.h b/src/include/ipxe/nfs_open.h
new file mode 100644
index 0000000..caba977
--- /dev/null
+++ b/src/include/ipxe/nfs_open.h
@@ -0,0 +1,12 @@
+#ifndef _IPXE_NFS_OPEN_H
+#define _IPXE_NFS_OPEN_H
+
+/** @file
+ *
+ * Network File System protocol.
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#endif /* _IPXE_NFS_OPEN_H */
diff --git a/src/include/ipxe/oncrpc.h b/src/include/ipxe/oncrpc.h
new file mode 100644
index 0000000..76c1260
--- /dev/null
+++ b/src/include/ipxe/oncrpc.h
@@ -0,0 +1,128 @@
+#ifndef _IPXE_ONCRPC_H
+#define _IPXE_ONCRPC_H
+
+#include <stdint.h>
+#include <ipxe/interface.h>
+#include <ipxe/iobuf.h>
+
+/** @file
+ *
+ * SUN ONC RPC protocol.
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** ONC RCP Version */
+#define ONCRPC_VERS 2
+
+/** ONC RPC Null Authentication */
+#define ONCRPC_AUTH_NONE 0
+
+/** ONC RPC System Authentication (also called UNIX Authentication) */
+#define ONCRPC_AUTH_SYS 1
+
+/** Size of an ONC RPC header */
+#define ONCRPC_HEADER_SIZE ( 11 * sizeof ( uint32_t ) )
+
+#define ONCRPC_FIELD( type, value ) { oncrpc_ ## type, { .type = value } }
+#define ONCRPC_SUBFIELD( type, args... ) \
+ { oncrpc_ ## type, { .type = { args } } }
+
+#define ONCRPC_FIELD_END { oncrpc_none, { } }
+
+/** Enusure that size is a multiple of four */
+#define oncrpc_align( size ) ( ( (size) + 3 ) & ~3 )
+
+/**
+ * Calculate the length of a string, including padding bytes.
+ *
+ * @v str String
+ * @ret size Length of the padded string
+ */
+#define oncrpc_strlen( str ) ( oncrpc_align ( strlen ( str ) ) + \
+ sizeof ( uint32_t ) )
+
+struct oncrpc_cred {
+ uint32_t flavor;
+ uint32_t length;
+};
+
+struct oncrpc_cred_sys {
+ struct oncrpc_cred credential;
+ uint32_t stamp;
+ char *hostname;
+ uint32_t uid;
+ uint32_t gid;
+ uint32_t aux_gid_len;
+ uint32_t aux_gid[16];
+};
+
+struct oncrpc_reply
+{
+ struct oncrpc_cred *verifier;
+ uint32_t rpc_id;
+ uint32_t reply_state;
+ uint32_t accept_state;
+ uint32_t frame_size;
+ struct io_buffer *data;
+};
+
+struct oncrpc_session {
+ struct oncrpc_reply pending_reply;
+ struct oncrpc_cred *credential;
+ struct oncrpc_cred *verifier;
+ uint32_t rpc_id;
+ uint32_t prog_name;
+ uint32_t prog_vers;
+};
+
+enum oncrpc_field_type {
+ oncrpc_none = 0,
+ oncrpc_int32,
+ oncrpc_int64,
+ oncrpc_str,
+ oncrpc_array,
+ oncrpc_intarray,
+ oncrpc_cred,
+};
+
+union oncrpc_field_value {
+ struct {
+ size_t length;
+ const void *ptr;
+ } array;
+
+ struct {
+ size_t length;
+ const uint32_t *ptr;
+ } intarray;
+
+ int64_t int64;
+ int32_t int32;
+ const char *str;
+ const struct oncrpc_cred *cred;
+};
+
+struct oncrpc_field {
+ enum oncrpc_field_type type;
+ union oncrpc_field_value value;
+};
+
+extern struct oncrpc_cred oncrpc_auth_none;
+
+int oncrpc_init_cred_sys ( struct oncrpc_cred_sys *auth_sys );
+void oncrpc_init_session ( struct oncrpc_session *session,
+ struct oncrpc_cred *credential,
+ struct oncrpc_cred *verifier, uint32_t prog_name,
+ uint32_t prog_vers );
+
+int oncrpc_call ( struct interface *intf, struct oncrpc_session *session,
+ uint32_t proc_name, const struct oncrpc_field fields[] );
+
+size_t oncrpc_compute_size ( const struct oncrpc_field fields[] );
+
+int oncrpc_get_reply ( struct oncrpc_session *session,
+ struct oncrpc_reply *reply, struct io_buffer *io_buf );
+
+#endif /* _IPXE_ONCRPC_H */
diff --git a/src/include/ipxe/oncrpc_iob.h b/src/include/ipxe/oncrpc_iob.h
new file mode 100644
index 0000000..4858d96
--- /dev/null
+++ b/src/include/ipxe/oncrpc_iob.h
@@ -0,0 +1,102 @@
+#ifndef _IPXE_ONCRPC_IOB_H
+#define _IPXE_ONCRPC_IOB_H
+
+#include <stdint.h>
+#include <string.h>
+#include <ipxe/iobuf.h>
+#include <ipxe/refcnt.h>
+#include <ipxe/oncrpc.h>
+
+/** @file
+ *
+ * SUN ONC RPC protocol.
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/**
+ * Add a string to the end of an I/O buffer
+ *
+ * @v io_buf I/O buffer
+ * @v val String
+ * @ret size Size of the data written
+ */
+#define oncrpc_iob_add_string( buf, str ) \
+( { \
+ const char * _str = (str); \
+ oncrpc_iob_add_array ( (buf), strlen ( _str ), _str ); \
+} )
+
+/**
+ * Get a 32 bits integer from the beginning of an I/O buffer
+ *
+ * @v buf I/O buffer
+ * @ret int Integer
+ */
+
+#define oncrpc_iob_get_int( buf ) \
+( { \
+ uint32_t *_val; \
+ _val = (buf)->data; \
+ iob_pull ( (buf), sizeof ( uint32_t ) ); \
+ ntohl ( *_val ); \
+} )
+
+/**
+ * Get a 64 bits integer from the beginning of an I/O buffer
+ *
+ * @v buf I/O buffer
+ * @ret int Integer
+ */
+#define oncrpc_iob_get_int64( buf ) \
+( { \
+ uint64_t *_val; \
+ _val = (buf)->data; \
+ iob_pull ( (buf), sizeof ( uint64_t ) ); \
+ ntohll ( *_val ); \
+} )
+
+
+size_t oncrpc_iob_add_fields ( struct io_buffer *io_buf,
+ const struct oncrpc_field fields[] );
+
+size_t oncrpc_iob_add_array ( struct io_buffer *io_buf, size_t length,
+ const void *data );
+
+size_t oncrpc_iob_add_intarray ( struct io_buffer *io_buf, size_t length,
+ const uint32_t *array );
+
+size_t oncrpc_iob_add_cred ( struct io_buffer *io_buf,
+ const struct oncrpc_cred *cred );
+
+size_t oncrpc_iob_get_cred ( struct io_buffer *io_buf,
+ struct oncrpc_cred *cred );
+
+/**
+ * Add a 32 bits integer to the end of an I/O buffer
+ *
+ * @v io_buf I/O buffer
+ * @v val Integer
+ * @ret size Size of the data written
+ */
+static inline size_t oncrpc_iob_add_int ( struct io_buffer *io_buf,
+ uint32_t val ) {
+ * ( uint32_t * ) iob_put ( io_buf, sizeof ( val ) ) = htonl ( val );
+ return ( sizeof ( val) );
+}
+
+/**
+ * Add a 64 bits integer to the end of an I/O buffer
+ *
+ * @v io_buf I/O buffer
+ * @v val Integer
+ * @ret size Size of the data written
+ */
+static inline size_t oncrpc_iob_add_int64 ( struct io_buffer *io_buf,
+ uint64_t val ) {
+ * ( uint64_t * ) iob_put ( io_buf, sizeof ( val ) ) = htonll ( val );
+ return ( sizeof ( val) );
+}
+
+#endif /* _IPXE_ONCRPC_IOB_H */
diff --git a/src/include/ipxe/portmap.h b/src/include/ipxe/portmap.h
new file mode 100644
index 0000000..9b735bb
--- /dev/null
+++ b/src/include/ipxe/portmap.h
@@ -0,0 +1,63 @@
+#ifndef _IPXE_PORTMAP_H
+#define _IPXE_PORTMAP_H
+
+#include <stdint.h>
+#include <ipxe/oncrpc.h>
+
+/** @file
+ *
+ * SUN ONC RPC protocol.
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** PORTMAP default port */
+#define PORTMAP_PORT 111
+
+/** PORTMAP protocol number */
+#define ONCRPC_PORTMAP 100000
+
+/** PORTMAP version */
+#define PORTMAP_VERS 2
+
+
+/** TCP protocol number */
+#define PORTMAP_PROTO_TCP 6
+/** UDB protocol number */
+#define PORTMAP_PROTO_UDP 17
+
+
+/**
+ * A PORTMAP GETPORT reply
+ *
+ */
+struct portmap_getport_reply {
+ /** Port returned */
+ uint32_t port;
+};
+
+
+/**
+ * Prepare an ONC RPC session to be used as a PORTMAP session
+ *
+ * @v session ONC RPC session
+ * @v credential ONC RPC credential
+ *
+ * The credential parameter must not be NULL, use 'oncrpc_auth_none' if you
+ * don't want a particular scheme to be used.
+ */
+static inline void portmap_init_session ( struct oncrpc_session *session,
+ struct oncrpc_cred *credential) {
+ oncrpc_init_session ( session, credential, &oncrpc_auth_none,
+ ONCRPC_PORTMAP, PORTMAP_VERS );
+}
+
+
+int portmap_getport ( struct interface *intf, struct oncrpc_session *session,
+ uint32_t prog, uint32_t vers, uint32_t proto );
+int portmap_get_getport_reply ( struct portmap_getport_reply *getport_reply,
+ struct oncrpc_reply *reply );
+
+
+#endif /* _IPXE_PORTMAP_H */
diff --git a/src/include/ipxe/uri.h b/src/include/ipxe/uri.h
index b7b8b44..9a13469 100644
--- a/src/include/ipxe/uri.h
+++ b/src/include/ipxe/uri.h
@@ -109,17 +109,27 @@ enum {
* Note that this is a separate concept from a URI with an absolute
* path.
*/
-static inline int uri_is_absolute ( struct uri *uri ) {
+static inline int uri_is_absolute ( const struct uri *uri ) {
return ( uri->scheme != NULL );
}
/**
+ * URI has an opaque part
+ *
+ * @v uri URI
+ * @ret has_opaque URI has an opaque part
+ */
+static inline int uri_has_opaque ( const struct uri *uri ) {
+ return ( uri->opaque && ( uri->opaque[0] != '\0' ) );
+
+}
+/**
* URI has a path
*
* @v uri URI
* @ret has_path URI has a path
*/
-static inline int uri_has_path ( struct uri *uri ) {
+static inline int uri_has_path ( const struct uri *uri ) {
return ( uri->path && ( uri->path[0] != '\0' ) );
}
@@ -133,7 +143,7 @@ static inline int uri_has_path ( struct uri *uri ) {
* concept from an absolute URI. Note also that a URI may not have a
* path at all.
*/
-static inline int uri_has_absolute_path ( struct uri *uri ) {
+static inline int uri_has_absolute_path ( const struct uri *uri ) {
return ( uri->path && ( uri->path[0] == '/' ) );
}
@@ -147,7 +157,7 @@ static inline int uri_has_absolute_path ( struct uri *uri ) {
* this is a separate concept from a relative URI. Note also that a
* URI may not have a path at all.
*/
-static inline int uri_has_relative_path ( struct uri *uri ) {
+static inline int uri_has_relative_path ( const struct uri *uri ) {
return ( uri->path && ( uri->path[0] != '/' ) );
}