iPXE
nfs.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2013 Marin Hannache <ipxe@mareo.fr>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 */
19
20FILE_SECBOOT ( FORBIDDEN );
21
22#include <stdint.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#include <assert.h>
27#include <errno.h>
28#include <libgen.h>
29#include <byteswap.h>
30#include <ipxe/time.h>
31#include <ipxe/iobuf.h>
32#include <ipxe/open.h>
33#include <ipxe/features.h>
34#include <ipxe/nfs.h>
35#include <ipxe/oncrpc.h>
36#include <ipxe/oncrpc_iob.h>
37#include <ipxe/portmap.h>
38#include <ipxe/mount.h>
39#include <ipxe/settings.h>
40
41/** @file
42 *
43 * Network File System protocol
44 *
45 */
46
47/** NFS LOOKUP procedure */
48#define NFS_LOOKUP 3
49/** NFS READLINK procedure */
50#define NFS_READLINK 5
51/** NFS READ procedure */
52#define NFS_READ 6
53
54/**
55 * Extract a file handle from the beginning of an I/O buffer
56 *
57 * @v io_buf I/O buffer
58 * @v fh File handle
59 * @ret size Size of the data read
60 */
61size_t nfs_iob_get_fh ( struct io_buffer *io_buf, struct nfs_fh *fh ) {
62 fh->size = oncrpc_iob_get_int ( io_buf );
63
64 if ( fh->size > 64 )
65 return sizeof ( uint32_t );
66
67 memcpy (fh->fh, io_buf->data, fh->size );
68 iob_pull ( io_buf, fh->size );
69
70 return fh->size + sizeof ( uint32_t );
71}
72
73/**
74 * Add a file handle to the end of an I/O buffer
75 *
76 * @v io_buf I/O buffer
77 * @v fh File handle
78 * @ret size Size of the data written
79 */
80size_t nfs_iob_add_fh ( struct io_buffer *io_buf, const struct nfs_fh *fh ) {
81 size_t s;
82
83 s = oncrpc_iob_add_int ( io_buf, fh->size );
84 memcpy ( iob_put ( io_buf, fh->size ), &fh->fh, fh->size );
85
86 return s + fh->size;
87}
88
89/**
90 * Send a LOOKUP request
91 *
92 * @v intf Interface to send the request on
93 * @v session ONC RPC session
94 * @v fh The file handle of the the directory
95 * @v filename The file name
96 * @ret rc Return status code
97 */
98int nfs_lookup ( struct interface *intf, struct oncrpc_session *session,
99 const struct nfs_fh *fh, const char *filename ) {
100 struct oncrpc_field fields[] = {
101 ONCRPC_SUBFIELD ( array, fh->size, &fh->fh ),
102 ONCRPC_FIELD ( str, filename ),
104 };
105
106 return oncrpc_call ( intf, session, NFS_LOOKUP, fields );
107}
108
109/**
110 * Send a READLINK request
111 *
112 * @v intf Interface to send the request on
113 * @v session ONC RPC session
114 * @v fh The symlink file handle
115 * @ret rc Return status code
116 */
117int nfs_readlink ( struct interface *intf, struct oncrpc_session *session,
118 const struct nfs_fh *fh ) {
119 struct oncrpc_field fields[] = {
120 ONCRPC_SUBFIELD ( array, fh->size, &fh->fh ),
122 };
123
124 return oncrpc_call ( intf, session, NFS_READLINK, fields );
125}
126
127/**
128 * Send a READ request
129 *
130 * @v intf Interface to send the request on
131 * @v session ONC RPC session
132 * @v fh The file handle
133 * @v offset Offset
134 * @v count Byte count
135 * @ret rc Return status code
136 */
137int nfs_read ( struct interface *intf, struct oncrpc_session *session,
138 const struct nfs_fh *fh, uint64_t offset, uint32_t count ) {
139 struct oncrpc_field fields[] = {
140 ONCRPC_SUBFIELD ( array, fh->size, &fh->fh ),
144 };
145
146 return oncrpc_call ( intf, session, NFS_READ, fields );
147}
148
149/**
150 * Parse a LOOKUP reply
151 *
152 * @v lookup_reply A structure where the data will be saved
153 * @v reply The ONC RPC reply to get data from
154 * @ret rc Return status code
155 */
156int nfs_get_lookup_reply ( struct nfs_lookup_reply *lookup_reply,
157 struct oncrpc_reply *reply ) {
158 if ( ! lookup_reply || ! reply )
159 return -EINVAL;
160
161 lookup_reply->status = oncrpc_iob_get_int ( reply->data );
162 switch ( lookup_reply->status )
163 {
164 case NFS3_OK:
165 break;
166 case NFS3ERR_PERM:
167 return -EPERM;
168 case NFS3ERR_NOENT:
169 return -ENOENT;
170 case NFS3ERR_IO:
171 return -EIO;
172 case NFS3ERR_ACCES:
173 return -EACCES;
174 case NFS3ERR_NOTDIR:
175 return -ENOTDIR;
177 return -ENAMETOOLONG;
178 case NFS3ERR_STALE:
179 return -ESTALE;
182 default:
183 return -EPROTO;
184 }
185
186 nfs_iob_get_fh ( reply->data, &lookup_reply->fh );
187
188 if ( oncrpc_iob_get_int ( reply->data ) == 1 )
189 lookup_reply->ent_type = oncrpc_iob_get_int ( reply->data );
190
191 return 0;
192}
193/**
194 * Parse a READLINK reply
195 *
196 * @v readlink_reply A structure where the data will be saved
197 * @v reply The ONC RPC reply to get data from
198 * @ret rc Return status code
199 */
200int nfs_get_readlink_reply ( struct nfs_readlink_reply *readlink_reply,
201 struct oncrpc_reply *reply ) {
202 if ( ! readlink_reply || ! reply )
203 return -EINVAL;
204
205 readlink_reply->status = oncrpc_iob_get_int ( reply->data );
206 switch ( readlink_reply->status )
207 {
208 case NFS3_OK:
209 break;
210 case NFS3ERR_IO:
211 return -EIO;
212 case NFS3ERR_ACCES:
213 return -EACCES;
214 case NFS3ERR_INVAL:
215 return -EINVAL;
216 case NFS3ERR_NOTSUPP:
217 return -ENOTSUP;
218 case NFS3ERR_STALE:
219 return -ESTALE;
222 default:
223 return -EPROTO;
224 }
225
226 if ( oncrpc_iob_get_int ( reply->data ) == 1 )
227 iob_pull ( reply->data, 5 * sizeof ( uint32_t ) +
228 8 * sizeof ( uint64_t ) );
229
230 readlink_reply->path_len = oncrpc_iob_get_int ( reply->data );
231 readlink_reply->path = reply->data->data;
232
233 return 0;
234}
235
236/**
237 * Parse a READ reply
238 *
239 * @v read_reply A structure where the data will be saved
240 * @v reply The ONC RPC reply to get data from
241 * @ret rc Return status code
242 */
243int nfs_get_read_reply ( struct nfs_read_reply *read_reply,
244 struct oncrpc_reply *reply ) {
245 if ( ! read_reply || ! reply )
246 return -EINVAL;
247
248 read_reply->status = oncrpc_iob_get_int ( reply->data );
249 switch ( read_reply->status )
250 {
251 case NFS3_OK:
252 break;
253 case NFS3ERR_PERM:
254 return -EPERM;
255 case NFS3ERR_NOENT:
256 return -ENOENT;
257 case NFS3ERR_IO:
258 return -EIO;
259 case NFS3ERR_NXIO:
260 return -ENXIO;
261 case NFS3ERR_ACCES:
262 return -EACCES;
263 case NFS3ERR_INVAL:
264 return -EINVAL;
265 case NFS3ERR_STALE:
266 return -ESTALE;
269 default:
270 return -EPROTO;
271 }
272
273 if ( oncrpc_iob_get_int ( reply->data ) == 1 )
274 {
275 iob_pull ( reply->data, 5 * sizeof ( uint32_t ) );
276 read_reply->filesize = oncrpc_iob_get_int64 ( reply->data );
277 iob_pull ( reply->data, 7 * sizeof ( uint64_t ) );
278 }
279
280 read_reply->count = oncrpc_iob_get_int ( reply->data );
281 read_reply->eof = oncrpc_iob_get_int ( reply->data );
282 read_reply->data_len = oncrpc_iob_get_int ( reply->data );
283 read_reply->data = reply->data->data;
284
285 if ( read_reply->count != read_reply->data_len )
286 return -EPROTO;
287
288 return 0;
289}
290
unsigned int uint32_t
Definition stdint.h:12
unsigned long long uint64_t
Definition stdint.h:13
Assertions.
uint16_t offset
Offset to command line.
Definition bzimage.h:3
uint32_t array
Array number.
Definition edd.h:1
Error codes.
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define ENOENT
No such file or directory.
Definition errno.h:515
#define ESTALE
Stale file handle.
Definition errno.h:660
#define ENXIO
No such device or address.
Definition errno.h:600
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENAMETOOLONG
Filename too long.
Definition errno.h:474
#define EPROTO
Protocol error.
Definition errno.h:625
#define EIO
Input/output error.
Definition errno.h:434
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define ENOTDIR
Not a directory.
Definition errno.h:575
#define EACCES
Permission denied.
Definition errno.h:299
#define EPERM
Operation not permitted.
Definition errno.h:615
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
Configuration settings.
Time source.
int64_t int64
Definition stdint.h:34
int32_t int32
Definition stdint.h:32
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
I/O buffers.
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define iob_pull(iobuf, len)
Definition iobuf.h:107
Feature list.
NFS MOUNT protocol.
size_t nfs_iob_get_fh(struct io_buffer *io_buf, struct nfs_fh *fh)
Extract a file handle from the beginning of an I/O buffer.
Definition nfs.c:61
int nfs_get_read_reply(struct nfs_read_reply *read_reply, struct oncrpc_reply *reply)
Parse a READ reply.
Definition nfs.c:243
int nfs_get_lookup_reply(struct nfs_lookup_reply *lookup_reply, struct oncrpc_reply *reply)
Parse a LOOKUP reply.
Definition nfs.c:156
int nfs_readlink(struct interface *intf, struct oncrpc_session *session, const struct nfs_fh *fh)
Send a READLINK request.
Definition nfs.c:117
#define NFS_READ
NFS READ procedure.
Definition nfs.c:52
size_t nfs_iob_add_fh(struct io_buffer *io_buf, const struct nfs_fh *fh)
Add a file handle to the end of an I/O buffer.
Definition nfs.c:80
#define NFS_READLINK
NFS READLINK procedure.
Definition nfs.c:50
int nfs_lookup(struct interface *intf, struct oncrpc_session *session, const struct nfs_fh *fh, const char *filename)
Send a LOOKUP request.
Definition nfs.c:98
int nfs_read(struct interface *intf, struct oncrpc_session *session, const struct nfs_fh *fh, uint64_t offset, uint32_t count)
Send a READ request.
Definition nfs.c:137
int nfs_get_readlink_reply(struct nfs_readlink_reply *readlink_reply, struct oncrpc_reply *reply)
Parse a READLINK reply.
Definition nfs.c:200
#define NFS_LOOKUP
NFS LOOKUP procedure.
Definition nfs.c:48
Network File System protocol.
#define NFS3ERR_PERM
Not owner.
Definition nfs.h:24
#define NFS3ERR_SERVERFAULT
An error occurred on the server which does not map to any of the legal NFS version 3 protocol error v...
Definition nfs.h:61
#define NFS3ERR_NOTDIR
Not a directory.
Definition nfs.h:40
#define NFS3ERR_BADHANDLE
Illegal NFS file handle.
Definition nfs.h:52
#define NFS3ERR_NOENT
No such file or directory.
Definition nfs.h:26
#define NFS3ERR_INVAL
Invalid argument.
Definition nfs.h:44
#define NFS3ERR_NOTSUPP
Operation not supported.
Definition nfs.h:56
#define NFS3ERR_ACCES
Permission denied.
Definition nfs.h:32
#define NFS3ERR_STALE
Invalid file handle.
Definition nfs.h:48
#define NFS3ERR_IO
I/O error.
Definition nfs.h:28
#define NFS3ERR_NXIO
No such device or address.
Definition nfs.h:30
#define NFS3ERR_NAMETOOLONG
Filename too long.
Definition nfs.h:46
#define NFS3_OK
No error.
Definition nfs.h:22
int oncrpc_call(struct interface *intf, struct oncrpc_session *session, uint32_t proc_name, const struct oncrpc_field fields[])
Definition oncrpc.c:129
SUN ONC RPC protocol.
#define ONCRPC_FIELD_END
Definition oncrpc.h:32
#define ONCRPC_SUBFIELD(type, args...)
Definition oncrpc.h:29
#define ONCRPC_FIELD(type, value)
Definition oncrpc.h:28
SUN ONC RPC protocol.
#define oncrpc_iob_get_int64(buf)
Get a 64 bits integer from the beginning of an I/O buffer.
Definition oncrpc_iob.h:52
static size_t oncrpc_iob_add_int(struct io_buffer *io_buf, uint32_t val)
Add a 32 bits integer to the end of an I/O buffer.
Definition oncrpc_iob.h:83
#define oncrpc_iob_get_int(buf)
Get a 32 bits integer from the beginning of an I/O buffer.
Definition oncrpc_iob.h:38
Data transfer interface opening.
SUN ONC RPC protocol.
An object interface.
Definition interface.h:125
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
A NFS file handle.
Definition nfs.h:74
uint8_t fh[64]
Definition nfs.h:75
size_t size
Definition nfs.h:76
A NFS LOOKUP reply.
Definition nfs.h:83
enum nfs_attr_type ent_type
Entity type.
Definition nfs.h:87
struct nfs_fh fh
File handle.
Definition nfs.h:89
uint32_t status
Reply status.
Definition nfs.h:85
A NFS READ reply.
Definition nfs.h:110
uint32_t count
Bytes read.
Definition nfs.h:116
uint32_t status
Reply status.
Definition nfs.h:112
uint32_t data_len
Data length.
Definition nfs.h:120
void * data
Data read.
Definition nfs.h:122
uint32_t eof
End-of-File indicator.
Definition nfs.h:118
uint64_t filesize
File size.
Definition nfs.h:114
struct io_buffer * data
Definition oncrpc.h:68