Blame view

net/nfs.c 23.8 KB
cbd8a35c6   wdenk   * Patch by Masami...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  /*
   * NFS support driver - based on etherboot and U-BOOT's tftp.c
   *
   * Masami Komiya <mkomiya@sonare.it> 2004
   *
   */
  
  /* NOTE: the NFS code is heavily inspired by the NetBSD netboot code (read:
   * large portions are copied verbatim) as distributed in OSKit 0.97.  A few
   * changes were necessary to adapt the code to Etherboot and to fix several
   * inconsistencies.  Also the RPC message preparation is done "by hand" to
   * avoid adding netsprintf() which I find hard to understand and use.  */
  
  /* NOTE 2: Etherboot does not care about things beyond the kernel image, so
   * it loads the kernel image off the boot server (ARP_SERVER) and does not
   * access the client root disk (root-path in dhcpd.conf), which would use
   * ARP_ROOTSERVER.  The root disk is something the operating system we are
   * about to load needs to use.	This is different from the OSKit 0.97 logic.  */
  
  /* NOTE 3: Symlink handling introduced by Anselm M Hoffmeister, 2003-July-14
   * If a symlink is encountered, it is followed as far as possible (recursion
   * possible, maximum 16 steps). There is no clearing of ".."'s inside the
   * path, so please DON'T DO THAT. thx. */
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
24
25
26
  /* NOTE 4: NFSv3 support added by Guillaume GARDET, 2016-June-20.
   * NFSv2 is still used by default. But if server does not support NFSv2, then
   * NFSv3 is used, if available on NFS server. */
cbd8a35c6   wdenk   * Patch by Masami...
27
28
  #include <common.h>
  #include <command.h>
0ee48252b   Simon Glass   common: Move flas...
29
  #include <flash.h>
8e8ccfe1a   Simon Glass   common: Move the ...
30
  #include <image.h>
cbd8a35c6   wdenk   * Patch by Masami...
31
32
  #include <net.h>
  #include <malloc.h>
55d5fd9a8   Joe Hershberger   net: Access mappe...
33
  #include <mapmem.h>
cbd8a35c6   wdenk   * Patch by Masami...
34
35
  #include "nfs.h"
  #include "bootp.h"
1045315df   Simon Glass   common: Move get_...
36
  #include <time.h>
cbd8a35c6   wdenk   * Patch by Masami...
37

cbd8a35c6   wdenk   * Patch by Masami...
38
  #define HASHES_PER_LINE 65	/* Number of "loading" hashes per line	*/
fe891ecf4   Hiroshi Ito   NFS Timeout with ...
39
  #define NFS_RETRY_COUNT 30
48a3e999c   Tetsuyuki Kobayashi   net: nfs: make NF...
40
41
42
43
44
  #ifndef CONFIG_NFS_TIMEOUT
  # define NFS_TIMEOUT 2000UL
  #else
  # define NFS_TIMEOUT CONFIG_NFS_TIMEOUT
  #endif
cbd8a35c6   wdenk   * Patch by Masami...
45

fa84fa708   Matthias Brugger   net: nfs: add dyn...
46
47
  #define NFS_RPC_ERR	1
  #define NFS_RPC_DROP	124
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
48
49
  static int fs_mounted;
  static unsigned long rpc_id;
cbd8a35c6   wdenk   * Patch by Masami...
50
51
  static int nfs_offset = -1;
  static int nfs_len;
fa84fa708   Matthias Brugger   net: nfs: add dyn...
52
  static ulong nfs_timeout = NFS_TIMEOUT;
cbd8a35c6   wdenk   * Patch by Masami...
53

b0baca982   Guillaume GARDET   net: NFS: Add NFS...
54
  static char dirfh[NFS_FHSIZE];	/* NFSv2 / NFSv3 file handle of directory */
5280c7691   Joe Hershberger   net: nfs: Share t...
55
56
  static char filefh[NFS3_FHSIZE]; /* NFSv2 / NFSv3 file handle */
  static int filefh3_length;	/* (variable) length of filefh when NFSv3 */
cbd8a35c6   wdenk   * Patch by Masami...
57

22f6e99d5   Joe Hershberger   net: Refactor to ...
58
  static enum net_loop_state nfs_download_state;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
59
  static struct in_addr nfs_server_ip;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
60
61
62
63
64
  static int nfs_server_mount_port;
  static int nfs_server_port;
  static int nfs_our_port;
  static int nfs_timeout_count;
  static int nfs_state;
cbd8a35c6   wdenk   * Patch by Masami...
65
66
67
68
69
70
71
  #define STATE_PRCLOOKUP_PROG_MOUNT_REQ	1
  #define STATE_PRCLOOKUP_PROG_NFS_REQ	2
  #define STATE_MOUNT_REQ			3
  #define STATE_UMOUNT_REQ		4
  #define STATE_LOOKUP_REQ		5
  #define STATE_READ_REQ			6
  #define STATE_READLINK_REQ		7
cbd8a35c6   wdenk   * Patch by Masami...
72
73
74
  static char *nfs_filename;
  static char *nfs_path;
  static char nfs_path_buff[2048];
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
75
76
77
  #define NFSV2_FLAG 1
  #define NFSV3_FLAG 1 << 1
  static char supported_nfs_versions = NFSV2_FLAG | NFSV3_FLAG;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
78
  static inline int store_block(uchar *src, unsigned offset, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
79
  {
a084f7da8   wdenk   * Patch by Masami...
80
  	ulong newsize = offset + len;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
81
  #ifdef CONFIG_SYS_DIRECT_FLASH_NFS
cbd8a35c6   wdenk   * Patch by Masami...
82
  	int i, rc = 0;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
83
  	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
cbd8a35c6   wdenk   * Patch by Masami...
84
  		/* start address in flash? */
bb872dd93   Simon Glass   image: Rename loa...
85
  		if (image_load_addr + offset >= flash_info[i].start[0]) {
cbd8a35c6   wdenk   * Patch by Masami...
86
87
88
89
90
91
  			rc = 1;
  			break;
  		}
  	}
  
  	if (rc) { /* Flash is destination for this packet */
bb872dd93   Simon Glass   image: Rename loa...
92
93
  		rc = flash_write((uchar *)src, (ulong)image_load_addr + offset,
  				 len);
cbd8a35c6   wdenk   * Patch by Masami...
94
  		if (rc) {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
95
  			flash_perror(rc);
23a7a32d4   Wolfgang Denk   Fix return code o...
96
  			return -1;
cbd8a35c6   wdenk   * Patch by Masami...
97
98
  		}
  	} else
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
99
  #endif /* CONFIG_SYS_DIRECT_FLASH_NFS */
cbd8a35c6   wdenk   * Patch by Masami...
100
  	{
bb872dd93   Simon Glass   image: Rename loa...
101
  		void *ptr = map_sysmem(image_load_addr + offset, len);
55d5fd9a8   Joe Hershberger   net: Access mappe...
102
103
104
  
  		memcpy(ptr, src, len);
  		unmap_sysmem(ptr);
cbd8a35c6   wdenk   * Patch by Masami...
105
  	}
a084f7da8   wdenk   * Patch by Masami...
106

1411157d8   Joe Hershberger   net: cosmetic: Fi...
107
108
  	if (net_boot_file_size < (offset + len))
  		net_boot_file_size = newsize;
23a7a32d4   Wolfgang Denk   Fix return code o...
109
  	return 0;
cbd8a35c6   wdenk   * Patch by Masami...
110
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
111
  static char *basename(char *path)
cbd8a35c6   wdenk   * Patch by Masami...
112
113
114
115
116
117
118
119
120
121
122
123
124
  {
  	char *fname;
  
  	fname = path + strlen(path) - 1;
  	while (fname >= path) {
  		if (*fname == '/') {
  			fname++;
  			break;
  		}
  		fname--;
  	}
  	return fname;
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
125
  static char *dirname(char *path)
cbd8a35c6   wdenk   * Patch by Masami...
126
127
  {
  	char *fname;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
128
  	fname = basename(path);
cbd8a35c6   wdenk   * Patch by Masami...
129
130
131
132
133
134
  	--fname;
  	*fname = '\0';
  	return path;
  }
  
  /**************************************************************************
cbd8a35c6   wdenk   * Patch by Masami...
135
136
  RPC_ADD_CREDENTIALS - Add RPC authentication/verifier entries
  **************************************************************************/
e4ead4a21   Ralf Hubert   net: Fix incorrec...
137
  static uint32_t *rpc_add_credentials(uint32_t *p)
cbd8a35c6   wdenk   * Patch by Masami...
138
  {
cbd8a35c6   wdenk   * Patch by Masami...
139
140
141
142
143
144
145
146
  	/* Here's the executive summary on authentication requirements of the
  	 * various NFS server implementations:	Linux accepts both AUTH_NONE
  	 * and AUTH_UNIX authentication (also accepts an empty hostname field
  	 * in the AUTH_UNIX scheme).  *BSD refuses AUTH_NONE, but accepts
  	 * AUTH_UNIX (also accepts an empty hostname field in the AUTH_UNIX
  	 * scheme).  To be safe, use AUTH_UNIX and pass the hostname if we have
  	 * it (if the BOOTP/DHCP reply didn't give one, just use an empty
  	 * hostname).  */
cbd8a35c6   wdenk   * Patch by Masami...
147
148
  	/* Provide an AUTH_UNIX credential.  */
  	*p++ = htonl(1);		/* AUTH_UNIX */
1ff65d440   Joe Hershberger   net: nfs: Simplif...
149
150
151
  	*p++ = htonl(20);		/* auth length */
  	*p++ = 0;			/* stamp */
  	*p++ = 0;			/* hostname string */
cbd8a35c6   wdenk   * Patch by Masami...
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  	*p++ = 0;			/* uid */
  	*p++ = 0;			/* gid */
  	*p++ = 0;			/* auxiliary gid list */
  
  	/* Provide an AUTH_NONE verifier.  */
  	*p++ = 0;			/* AUTH_NONE */
  	*p++ = 0;			/* auth length */
  
  	return p;
  }
  
  /**************************************************************************
  RPC_LOOKUP - Lookup RPC Port numbers
  **************************************************************************/
a73588fe4   Joe Hershberger   Revert "net: nfs:...
166
  static void rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
cbd8a35c6   wdenk   * Patch by Masami...
167
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
168
  	struct rpc_t rpc_pkt;
cbd8a35c6   wdenk   * Patch by Masami...
169
  	unsigned long id;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
170
  	uint32_t *p;
cbd8a35c6   wdenk   * Patch by Masami...
171
172
  	int pktlen;
  	int sport;
c3f9d4939   wdenk   * Patch by Yuli B...
173
  	id = ++rpc_id;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
174
175
176
177
  	rpc_pkt.u.call.id = htonl(id);
  	rpc_pkt.u.call.type = htonl(MSG_CALL);
  	rpc_pkt.u.call.rpcvers = htonl(2);	/* use RPC version 2 */
  	rpc_pkt.u.call.prog = htonl(rpc_prog);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
178
179
180
  	switch (rpc_prog) {
  	case PROG_NFS:
  		if (supported_nfs_versions & NFSV2_FLAG)
a73588fe4   Joe Hershberger   Revert "net: nfs:...
181
  			rpc_pkt.u.call.vers = htonl(2);	/* NFS v2 */
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
182
  		else /* NFSV3_FLAG */
a73588fe4   Joe Hershberger   Revert "net: nfs:...
183
  			rpc_pkt.u.call.vers = htonl(3);	/* NFS v3 */
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
184
185
186
187
  		break;
  	case PROG_PORTMAP:
  	case PROG_MOUNT:
  	default:
a73588fe4   Joe Hershberger   Revert "net: nfs:...
188
  		rpc_pkt.u.call.vers = htonl(2);	/* portmapper is version 2 */
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
189
  	}
a73588fe4   Joe Hershberger   Revert "net: nfs:...
190
  	rpc_pkt.u.call.proc = htonl(rpc_proc);
15eea9a1a   Heinrich Schuchardt   net: nfs: remove ...
191
  	p = rpc_pkt.u.call.data;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
192
193
  
  	if (datalen)
15eea9a1a   Heinrich Schuchardt   net: nfs: remove ...
194
  		memcpy(p, data, datalen * sizeof(uint32_t));
a73588fe4   Joe Hershberger   Revert "net: nfs:...
195
196
  
  	pktlen = (char *)p + datalen * sizeof(uint32_t) - (char *)&rpc_pkt;
cbd8a35c6   wdenk   * Patch by Masami...
197

a73588fe4   Joe Hershberger   Revert "net: nfs:...
198
199
  	memcpy((char *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE,
  	       &rpc_pkt.u.data[0], pktlen);
cbd8a35c6   wdenk   * Patch by Masami...
200
201
202
203
  
  	if (rpc_prog == PROG_PORTMAP)
  		sport = SUNRPC_PORT;
  	else if (rpc_prog == PROG_MOUNT)
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
204
  		sport = nfs_server_mount_port;
cbd8a35c6   wdenk   * Patch by Masami...
205
  	else
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
206
  		sport = nfs_server_port;
cbd8a35c6   wdenk   * Patch by Masami...
207

1203fccee   Joe Hershberger   net: cosmetic: Cl...
208
  	net_send_udp_packet(net_server_ethaddr, nfs_server_ip, sport,
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
209
  			    nfs_our_port, pktlen);
cbd8a35c6   wdenk   * Patch by Masami...
210
211
212
213
214
  }
  
  /**************************************************************************
  RPC_LOOKUP - Lookup RPC Port numbers
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
215
  static void rpc_lookup_req(int prog, int ver)
cbd8a35c6   wdenk   * Patch by Masami...
216
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
217
  	uint32_t data[16];
cbd8a35c6   wdenk   * Patch by Masami...
218
219
220
221
222
223
224
  
  	data[0] = 0; data[1] = 0;	/* auth credential */
  	data[2] = 0; data[3] = 0;	/* auth verifier */
  	data[4] = htonl(prog);
  	data[5] = htonl(ver);
  	data[6] = htonl(17);	/* IP_UDP */
  	data[7] = 0;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
225
  	rpc_req(PROG_PORTMAP, PORTMAP_GETPORT, data, 8);
cbd8a35c6   wdenk   * Patch by Masami...
226
227
228
229
230
  }
  
  /**************************************************************************
  NFS_MOUNT - Mount an NFS Filesystem
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
231
  static void nfs_mount_req(char *path)
cbd8a35c6   wdenk   * Patch by Masami...
232
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
233
  	uint32_t data[1024];
cbd8a35c6   wdenk   * Patch by Masami...
234
235
236
  	uint32_t *p;
  	int len;
  	int pathlen;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
237
  	pathlen = strlen(path);
cbd8a35c6   wdenk   * Patch by Masami...
238

a73588fe4   Joe Hershberger   Revert "net: nfs:...
239
  	p = &(data[0]);
e4ead4a21   Ralf Hubert   net: Fix incorrec...
240
  	p = rpc_add_credentials(p);
cbd8a35c6   wdenk   * Patch by Masami...
241
242
  
  	*p++ = htonl(pathlen);
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
243
244
245
  	if (pathlen & 3)
  		*(p + pathlen / 4) = 0;
  	memcpy(p, path, pathlen);
cbd8a35c6   wdenk   * Patch by Masami...
246
  	p += (pathlen + 3) / 4;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
247
  	len = (uint32_t *)p - (uint32_t *)&(data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
248

a73588fe4   Joe Hershberger   Revert "net: nfs:...
249
  	rpc_req(PROG_MOUNT, MOUNT_ADDENTRY, data, len);
cbd8a35c6   wdenk   * Patch by Masami...
250
251
252
253
254
  }
  
  /**************************************************************************
  NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
255
  static void nfs_umountall_req(void)
cbd8a35c6   wdenk   * Patch by Masami...
256
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
257
  	uint32_t data[1024];
cbd8a35c6   wdenk   * Patch by Masami...
258
259
  	uint32_t *p;
  	int len;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
260
  	if ((nfs_server_mount_port == -1) || (!fs_mounted))
cbd8a35c6   wdenk   * Patch by Masami...
261
262
  		/* Nothing mounted, nothing to umount */
  		return;
cbd8a35c6   wdenk   * Patch by Masami...
263

a73588fe4   Joe Hershberger   Revert "net: nfs:...
264
  	p = &(data[0]);
e4ead4a21   Ralf Hubert   net: Fix incorrec...
265
  	p = rpc_add_credentials(p);
cbd8a35c6   wdenk   * Patch by Masami...
266

a73588fe4   Joe Hershberger   Revert "net: nfs:...
267
  	len = (uint32_t *)p - (uint32_t *)&(data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
268

a73588fe4   Joe Hershberger   Revert "net: nfs:...
269
  	rpc_req(PROG_MOUNT, MOUNT_UMOUNTALL, data, len);
cbd8a35c6   wdenk   * Patch by Masami...
270
271
272
273
274
275
276
277
278
  }
  
  /***************************************************************************
   * NFS_READLINK (AH 2003-07-14)
   * This procedure is called when read of the first block fails -
   * this probably happens when it's a directory or a symlink
   * In case of successful readlink(), the dirname is manipulated,
   * so that inside the nfs() function a recursion can be done.
   **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
279
  static void nfs_readlink_req(void)
cbd8a35c6   wdenk   * Patch by Masami...
280
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
281
  	uint32_t data[1024];
cbd8a35c6   wdenk   * Patch by Masami...
282
283
  	uint32_t *p;
  	int len;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
284
  	p = &(data[0]);
e4ead4a21   Ralf Hubert   net: Fix incorrec...
285
  	p = rpc_add_credentials(p);
cbd8a35c6   wdenk   * Patch by Masami...
286

b0baca982   Guillaume GARDET   net: NFS: Add NFS...
287
288
289
290
291
  	if (supported_nfs_versions & NFSV2_FLAG) {
  		memcpy(p, filefh, NFS_FHSIZE);
  		p += (NFS_FHSIZE / 4);
  	} else { /* NFSV3_FLAG */
  		*p++ = htonl(filefh3_length);
5280c7691   Joe Hershberger   net: nfs: Share t...
292
  		memcpy(p, filefh, filefh3_length);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
293
294
  		p += (filefh3_length / 4);
  	}
cbd8a35c6   wdenk   * Patch by Masami...
295

a73588fe4   Joe Hershberger   Revert "net: nfs:...
296
  	len = (uint32_t *)p - (uint32_t *)&(data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
297

a73588fe4   Joe Hershberger   Revert "net: nfs:...
298
  	rpc_req(PROG_NFS, NFS_READLINK, data, len);
cbd8a35c6   wdenk   * Patch by Masami...
299
300
301
302
303
  }
  
  /**************************************************************************
  NFS_LOOKUP - Lookup Pathname
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
304
  static void nfs_lookup_req(char *fname)
cbd8a35c6   wdenk   * Patch by Masami...
305
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
306
  	uint32_t data[1024];
cbd8a35c6   wdenk   * Patch by Masami...
307
308
309
  	uint32_t *p;
  	int len;
  	int fnamelen;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
310
  	fnamelen = strlen(fname);
cbd8a35c6   wdenk   * Patch by Masami...
311

a73588fe4   Joe Hershberger   Revert "net: nfs:...
312
  	p = &(data[0]);
e4ead4a21   Ralf Hubert   net: Fix incorrec...
313
  	p = rpc_add_credentials(p);
cbd8a35c6   wdenk   * Patch by Masami...
314

b0baca982   Guillaume GARDET   net: NFS: Add NFS...
315
316
317
318
319
320
321
322
  	if (supported_nfs_versions & NFSV2_FLAG) {
  		memcpy(p, dirfh, NFS_FHSIZE);
  		p += (NFS_FHSIZE / 4);
  		*p++ = htonl(fnamelen);
  		if (fnamelen & 3)
  			*(p + fnamelen / 4) = 0;
  		memcpy(p, fname, fnamelen);
  		p += (fnamelen + 3) / 4;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
323
  		len = (uint32_t *)p - (uint32_t *)&(data[0]);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
324

a73588fe4   Joe Hershberger   Revert "net: nfs:...
325
  		rpc_req(PROG_NFS, NFS_LOOKUP, data, len);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
326
327
328
329
330
331
332
333
334
  	} else {  /* NFSV3_FLAG */
  		*p++ = htonl(NFS_FHSIZE);	/* Dir handle length */
  		memcpy(p, dirfh, NFS_FHSIZE);
  		p += (NFS_FHSIZE / 4);
  		*p++ = htonl(fnamelen);
  		if (fnamelen & 3)
  			*(p + fnamelen / 4) = 0;
  		memcpy(p, fname, fnamelen);
  		p += (fnamelen + 3) / 4;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
335
  		len = (uint32_t *)p - (uint32_t *)&(data[0]);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
336

a73588fe4   Joe Hershberger   Revert "net: nfs:...
337
  		rpc_req(PROG_NFS, NFS3PROC_LOOKUP, data, len);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
338
  	}
cbd8a35c6   wdenk   * Patch by Masami...
339
340
341
342
343
  }
  
  /**************************************************************************
  NFS_READ - Read File on NFS Server
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
344
  static void nfs_read_req(int offset, int readlen)
cbd8a35c6   wdenk   * Patch by Masami...
345
  {
a73588fe4   Joe Hershberger   Revert "net: nfs:...
346
  	uint32_t data[1024];
cbd8a35c6   wdenk   * Patch by Masami...
347
348
  	uint32_t *p;
  	int len;
a73588fe4   Joe Hershberger   Revert "net: nfs:...
349
  	p = &(data[0]);
e4ead4a21   Ralf Hubert   net: Fix incorrec...
350
  	p = rpc_add_credentials(p);
cbd8a35c6   wdenk   * Patch by Masami...
351

b0baca982   Guillaume GARDET   net: NFS: Add NFS...
352
353
354
355
356
357
358
359
  	if (supported_nfs_versions & NFSV2_FLAG) {
  		memcpy(p, filefh, NFS_FHSIZE);
  		p += (NFS_FHSIZE / 4);
  		*p++ = htonl(offset);
  		*p++ = htonl(readlen);
  		*p++ = 0;
  	} else { /* NFSV3_FLAG */
  		*p++ = htonl(filefh3_length);
5280c7691   Joe Hershberger   net: nfs: Share t...
360
  		memcpy(p, filefh, filefh3_length);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
361
362
363
364
365
366
  		p += (filefh3_length / 4);
  		*p++ = htonl(0); /* offset is 64-bit long, so fill with 0 */
  		*p++ = htonl(offset);
  		*p++ = htonl(readlen);
  		*p++ = 0;
  	}
cbd8a35c6   wdenk   * Patch by Masami...
367

a73588fe4   Joe Hershberger   Revert "net: nfs:...
368
  	len = (uint32_t *)p - (uint32_t *)&(data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
369

a73588fe4   Joe Hershberger   Revert "net: nfs:...
370
  	rpc_req(PROG_NFS, NFS_READ, data, len);
cbd8a35c6   wdenk   * Patch by Masami...
371
372
373
374
375
  }
  
  /**************************************************************************
  RPC request dispatcher
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
376
  static void nfs_send(void)
cbd8a35c6   wdenk   * Patch by Masami...
377
  {
0ebf04c60   Robin Getz   minor debug clean...
378
379
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
380

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
381
  	switch (nfs_state) {
cbd8a35c6   wdenk   * Patch by Masami...
382
  	case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
383
384
385
386
  		if (supported_nfs_versions & NFSV2_FLAG)
  			rpc_lookup_req(PROG_MOUNT, 1);
  		else  /* NFSV3_FLAG */
  			rpc_lookup_req(PROG_MOUNT, 3);
cbd8a35c6   wdenk   * Patch by Masami...
387
388
  		break;
  	case STATE_PRCLOOKUP_PROG_NFS_REQ:
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
389
390
391
392
  		if (supported_nfs_versions & NFSV2_FLAG)
  			rpc_lookup_req(PROG_NFS, 2);
  		else  /* NFSV3_FLAG */
  			rpc_lookup_req(PROG_NFS, 3);
cbd8a35c6   wdenk   * Patch by Masami...
393
394
  		break;
  	case STATE_MOUNT_REQ:
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
395
  		nfs_mount_req(nfs_path);
cbd8a35c6   wdenk   * Patch by Masami...
396
397
  		break;
  	case STATE_UMOUNT_REQ:
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
398
  		nfs_umountall_req();
cbd8a35c6   wdenk   * Patch by Masami...
399
400
  		break;
  	case STATE_LOOKUP_REQ:
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
401
  		nfs_lookup_req(nfs_filename);
cbd8a35c6   wdenk   * Patch by Masami...
402
403
  		break;
  	case STATE_READ_REQ:
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
404
  		nfs_read_req(nfs_offset, nfs_len);
cbd8a35c6   wdenk   * Patch by Masami...
405
406
  		break;
  	case STATE_READLINK_REQ:
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
407
  		nfs_readlink_req();
cbd8a35c6   wdenk   * Patch by Masami...
408
409
410
411
412
413
414
  		break;
  	}
  }
  
  /**************************************************************************
  Handlers for the reply from server
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
415
  static int rpc_lookup_reply(int prog, uchar *pkt, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
416
417
  {
  	struct rpc_t rpc_pkt;
0517cc45e   Joe Hershberger   net: nfs: Use con...
418
  	memcpy(&rpc_pkt.u.data[0], pkt, len);
cbd8a35c6   wdenk   * Patch by Masami...
419

0ebf04c60   Robin Getz   minor debug clean...
420
421
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
422

fa84fa708   Matthias Brugger   net: nfs: add dyn...
423
424
425
426
  	if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
  		return -NFS_RPC_ERR;
  	else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
  		return -NFS_RPC_DROP;
c3f9d4939   wdenk   * Patch by Yuli B...
427

cbd8a35c6   wdenk   * Patch by Masami...
428
429
  	if (rpc_pkt.u.reply.rstatus  ||
  	    rpc_pkt.u.reply.verifier ||
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
430
  	    rpc_pkt.u.reply.astatus)
c3f9d4939   wdenk   * Patch by Yuli B...
431
  		return -1;
cbd8a35c6   wdenk   * Patch by Masami...
432
433
434
  
  	switch (prog) {
  	case PROG_MOUNT:
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
435
  		nfs_server_mount_port = ntohl(rpc_pkt.u.reply.data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
436
437
  		break;
  	case PROG_NFS:
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
438
  		nfs_server_port = ntohl(rpc_pkt.u.reply.data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
439
440
441
442
443
  		break;
  	}
  
  	return 0;
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
444
  static int nfs_mount_reply(uchar *pkt, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
445
446
  {
  	struct rpc_t rpc_pkt;
0ebf04c60   Robin Getz   minor debug clean...
447
448
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
449

0517cc45e   Joe Hershberger   net: nfs: Use con...
450
  	memcpy(&rpc_pkt.u.data[0], pkt, len);
cbd8a35c6   wdenk   * Patch by Masami...
451

fa84fa708   Matthias Brugger   net: nfs: add dyn...
452
453
454
455
  	if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
  		return -NFS_RPC_ERR;
  	else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
  		return -NFS_RPC_DROP;
c3f9d4939   wdenk   * Patch by Yuli B...
456

cbd8a35c6   wdenk   * Patch by Masami...
457
458
459
  	if (rpc_pkt.u.reply.rstatus  ||
  	    rpc_pkt.u.reply.verifier ||
  	    rpc_pkt.u.reply.astatus  ||
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
460
  	    rpc_pkt.u.reply.data[0])
cbd8a35c6   wdenk   * Patch by Masami...
461
  		return -1;
cbd8a35c6   wdenk   * Patch by Masami...
462
463
  
  	fs_mounted = 1;
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
464
  	/*  NFSv2 and NFSv3 use same structure */
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
465
  	memcpy(dirfh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
cbd8a35c6   wdenk   * Patch by Masami...
466
467
468
  
  	return 0;
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
469
  static int nfs_umountall_reply(uchar *pkt, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
470
471
  {
  	struct rpc_t rpc_pkt;
0ebf04c60   Robin Getz   minor debug clean...
472
473
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
474

0517cc45e   Joe Hershberger   net: nfs: Use con...
475
  	memcpy(&rpc_pkt.u.data[0], pkt, len);
cbd8a35c6   wdenk   * Patch by Masami...
476

fa84fa708   Matthias Brugger   net: nfs: add dyn...
477
478
479
480
  	if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
  		return -NFS_RPC_ERR;
  	else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
  		return -NFS_RPC_DROP;
c3f9d4939   wdenk   * Patch by Yuli B...
481

cbd8a35c6   wdenk   * Patch by Masami...
482
483
  	if (rpc_pkt.u.reply.rstatus  ||
  	    rpc_pkt.u.reply.verifier ||
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
484
  	    rpc_pkt.u.reply.astatus)
cbd8a35c6   wdenk   * Patch by Masami...
485
  		return -1;
cbd8a35c6   wdenk   * Patch by Masami...
486
487
  
  	fs_mounted = 0;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
488
  	memset(dirfh, 0, sizeof(dirfh));
cbd8a35c6   wdenk   * Patch by Masami...
489
490
491
  
  	return 0;
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
492
  static int nfs_lookup_reply(uchar *pkt, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
493
494
  {
  	struct rpc_t rpc_pkt;
0ebf04c60   Robin Getz   minor debug clean...
495
496
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
497

0517cc45e   Joe Hershberger   net: nfs: Use con...
498
  	memcpy(&rpc_pkt.u.data[0], pkt, len);
cbd8a35c6   wdenk   * Patch by Masami...
499

fa84fa708   Matthias Brugger   net: nfs: add dyn...
500
501
502
503
  	if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
  		return -NFS_RPC_ERR;
  	else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
  		return -NFS_RPC_DROP;
c3f9d4939   wdenk   * Patch by Yuli B...
504

cbd8a35c6   wdenk   * Patch by Masami...
505
506
507
  	if (rpc_pkt.u.reply.rstatus  ||
  	    rpc_pkt.u.reply.verifier ||
  	    rpc_pkt.u.reply.astatus  ||
69fd0d413   Guillaume GARDET   NFS: Add error me...
508
509
  	    rpc_pkt.u.reply.data[0]) {
  		switch (ntohl(rpc_pkt.u.reply.astatus)) {
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
510
  		case NFS_RPC_SUCCESS: /* Not an error */
69fd0d413   Guillaume GARDET   NFS: Add error me...
511
  			break;
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
512
513
514
515
516
  		case NFS_RPC_PROG_MISMATCH:
  			/* Remote can't support NFS version */
  			switch (ntohl(rpc_pkt.u.reply.data[0])) {
  			/* Minimal supported NFS version */
  			case 3:
faecf84ab   Joe Hershberger   net: Always print...
517
518
  				debug("*** Warning: NFS version not supported: Requested: V%d, accepted: min V%d - max V%d
  ",
347a90159   Joe Hershberger   net: nfs: Fix lin...
519
520
  				      (supported_nfs_versions & NFSV2_FLAG) ?
  						2 : 3,
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
521
522
523
524
525
526
527
528
529
  				      ntohl(rpc_pkt.u.reply.data[0]),
  				      ntohl(rpc_pkt.u.reply.data[1]));
  				debug("Will retry with NFSv3
  ");
  				/* Clear NFSV2_FLAG from supported versions */
  				supported_nfs_versions &= ~NFSV2_FLAG;
  				return -NFS_RPC_PROG_MISMATCH;
  			case 4:
  			default:
d89ff2df3   Joe Hershberger   net: nfs: Move so...
530
531
532
533
  				puts("*** ERROR: NFS version not supported");
  				debug(": Requested: V%d, accepted: min V%d - max V%d
  ",
  				      (supported_nfs_versions & NFSV2_FLAG) ?
347a90159   Joe Hershberger   net: nfs: Fix lin...
534
  						2 : 3,
d89ff2df3   Joe Hershberger   net: nfs: Move so...
535
536
537
538
  				      ntohl(rpc_pkt.u.reply.data[0]),
  				      ntohl(rpc_pkt.u.reply.data[1]));
  				puts("
  ");
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
539
  			}
69fd0d413   Guillaume GARDET   NFS: Add error me...
540
  			break;
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
541
542
543
544
  		case NFS_RPC_PROG_UNAVAIL:
  		case NFS_RPC_PROC_UNAVAIL:
  		case NFS_RPC_GARBAGE_ARGS:
  		case NFS_RPC_SYSTEM_ERR:
69fd0d413   Guillaume GARDET   NFS: Add error me...
545
  		default: /* Unknown error on 'accept state' flag */
d89ff2df3   Joe Hershberger   net: nfs: Move so...
546
547
548
  			debug("*** ERROR: accept state error (%d)
  ",
  			      ntohl(rpc_pkt.u.reply.astatus));
69fd0d413   Guillaume GARDET   NFS: Add error me...
549
550
  			break;
  		}
cbd8a35c6   wdenk   * Patch by Masami...
551
  		return -1;
69fd0d413   Guillaume GARDET   NFS: Add error me...
552
  	}
cbd8a35c6   wdenk   * Patch by Masami...
553

b0baca982   Guillaume GARDET   net: NFS: Add NFS...
554
  	if (supported_nfs_versions & NFSV2_FLAG) {
5d14ee4e5   liucheng (G)   CVE-2019-14196: n...
555
556
  		if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + NFS_FHSIZE) > len)
  			return -NFS_RPC_DROP;
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
557
558
559
560
561
  		memcpy(filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
  	} else {  /* NFSV3_FLAG */
  		filefh3_length = ntohl(rpc_pkt.u.reply.data[1]);
  		if (filefh3_length > NFS3_FHSIZE)
  			filefh3_length  = NFS3_FHSIZE;
5d14ee4e5   liucheng (G)   CVE-2019-14196: n...
562
563
  		if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + filefh3_length) > len)
  			return -NFS_RPC_DROP;
5280c7691   Joe Hershberger   net: nfs: Share t...
564
  		memcpy(filefh, rpc_pkt.u.reply.data + 2, filefh3_length);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
565
  	}
cbd8a35c6   wdenk   * Patch by Masami...
566
567
568
  
  	return 0;
  }
051ed9af8   Joe Hershberger   net: nfs: Consoli...
569
570
  static int nfs3_get_attributes_offset(uint32_t *data)
  {
15eea9a1a   Heinrich Schuchardt   net: nfs: remove ...
571
  	if (data[1]) {
051ed9af8   Joe Hershberger   net: nfs: Consoli...
572
  		/* 'attributes_follow' flag is TRUE,
c629c45f3   Joe Hershberger   net: nfs: Correct...
573
  		 * so we have attributes on 21 dwords */
051ed9af8   Joe Hershberger   net: nfs: Consoli...
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
  		/* Skip unused values :
  			type;	32 bits value,
  			mode;	32 bits value,
  			nlink;	32 bits value,
  			uid;	32 bits value,
  			gid;	32 bits value,
  			size;	64 bits value,
  			used;	64 bits value,
  			rdev;	64 bits value,
  			fsid;	64 bits value,
  			fileid;	64 bits value,
  			atime;	64 bits value,
  			mtime;	64 bits value,
  			ctime;	64 bits value,
  		*/
  		return 22;
  	} else {
  		/* 'attributes_follow' flag is FALSE,
  		 * so we don't have any attributes */
  		return 1;
  	}
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
596
  static int nfs_readlink_reply(uchar *pkt, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
597
598
599
  {
  	struct rpc_t rpc_pkt;
  	int rlen;
051ed9af8   Joe Hershberger   net: nfs: Consoli...
600
  	int nfsv3_data_offset = 0;
cbd8a35c6   wdenk   * Patch by Masami...
601

0ebf04c60   Robin Getz   minor debug clean...
602
603
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
604

c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
605
  	memcpy((unsigned char *)&rpc_pkt, pkt, len);
cbd8a35c6   wdenk   * Patch by Masami...
606

fa84fa708   Matthias Brugger   net: nfs: add dyn...
607
608
609
610
  	if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
  		return -NFS_RPC_ERR;
  	else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
  		return -NFS_RPC_DROP;
c3f9d4939   wdenk   * Patch by Yuli B...
611

cbd8a35c6   wdenk   * Patch by Masami...
612
613
614
  	if (rpc_pkt.u.reply.rstatus  ||
  	    rpc_pkt.u.reply.verifier ||
  	    rpc_pkt.u.reply.astatus  ||
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
615
  	    rpc_pkt.u.reply.data[0])
cbd8a35c6   wdenk   * Patch by Masami...
616
  		return -1;
cbd8a35c6   wdenk   * Patch by Masami...
617

051ed9af8   Joe Hershberger   net: nfs: Consoli...
618
619
620
621
  	if (!(supported_nfs_versions & NFSV2_FLAG)) { /* NFSV3_FLAG */
  		nfsv3_data_offset =
  			nfs3_get_attributes_offset(rpc_pkt.u.reply.data);
  	}
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
622

051ed9af8   Joe Hershberger   net: nfs: Consoli...
623
624
  	/* new path length */
  	rlen = ntohl(rpc_pkt.u.reply.data[1 + nfsv3_data_offset]);
cf3a4f1e8   liucheng (G)   CVE-2019-14195: n...
625
626
  	if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + rlen) > len)
  		return -NFS_RPC_DROP;
051ed9af8   Joe Hershberger   net: nfs: Consoli...
627
628
629
630
631
632
633
634
635
636
637
638
639
640
  	if (*((char *)&(rpc_pkt.u.reply.data[2 + nfsv3_data_offset])) != '/') {
  		int pathlen;
  
  		strcat(nfs_path, "/");
  		pathlen = strlen(nfs_path);
  		memcpy(nfs_path + pathlen,
  		       (uchar *)&(rpc_pkt.u.reply.data[2 + nfsv3_data_offset]),
  		       rlen);
  		nfs_path[pathlen + rlen] = 0;
  	} else {
  		memcpy(nfs_path,
  		       (uchar *)&(rpc_pkt.u.reply.data[2 + nfsv3_data_offset]),
  		       rlen);
  		nfs_path[rlen] = 0;
cbd8a35c6   wdenk   * Patch by Masami...
641
642
643
  	}
  	return 0;
  }
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
644
  static int nfs_read_reply(uchar *pkt, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
645
646
647
  {
  	struct rpc_t rpc_pkt;
  	int rlen;
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
648
  	uchar *data_ptr;
cbd8a35c6   wdenk   * Patch by Masami...
649

0ebf04c60   Robin Getz   minor debug clean...
650
651
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
652

0517cc45e   Joe Hershberger   net: nfs: Use con...
653
  	memcpy(&rpc_pkt.u.data[0], pkt, sizeof(rpc_pkt.u.reply));
cbd8a35c6   wdenk   * Patch by Masami...
654

fa84fa708   Matthias Brugger   net: nfs: add dyn...
655
656
657
658
  	if (ntohl(rpc_pkt.u.reply.id) > rpc_id)
  		return -NFS_RPC_ERR;
  	else if (ntohl(rpc_pkt.u.reply.id) < rpc_id)
  		return -NFS_RPC_DROP;
c3f9d4939   wdenk   * Patch by Yuli B...
659

cbd8a35c6   wdenk   * Patch by Masami...
660
661
662
663
  	if (rpc_pkt.u.reply.rstatus  ||
  	    rpc_pkt.u.reply.verifier ||
  	    rpc_pkt.u.reply.astatus  ||
  	    rpc_pkt.u.reply.data[0]) {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
664
  		if (rpc_pkt.u.reply.rstatus)
cbd8a35c6   wdenk   * Patch by Masami...
665
  			return -9999;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
666
  		if (rpc_pkt.u.reply.astatus)
cbd8a35c6   wdenk   * Patch by Masami...
667
  			return -9999;
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
668
  		return -ntohl(rpc_pkt.u.reply.data[0]);
cbd8a35c6   wdenk   * Patch by Masami...
669
  	}
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
670
671
672
673
674
675
  	if ((nfs_offset != 0) && !((nfs_offset) %
  			(NFS_READ_SIZE / 2 * 10 * HASHES_PER_LINE)))
  		puts("
  \t ");
  	if (!(nfs_offset % ((NFS_READ_SIZE / 2) * 10)))
  		putc('#');
cbd8a35c6   wdenk   * Patch by Masami...
676

b0baca982   Guillaume GARDET   net: NFS: Add NFS...
677
678
679
680
  	if (supported_nfs_versions & NFSV2_FLAG) {
  		rlen = ntohl(rpc_pkt.u.reply.data[18]);
  		data_ptr = (uchar *)&(rpc_pkt.u.reply.data[19]);
  	} else {  /* NFSV3_FLAG */
051ed9af8   Joe Hershberger   net: nfs: Consoli...
681
682
683
684
685
686
687
688
689
690
691
  		int nfsv3_data_offset =
  			nfs3_get_attributes_offset(rpc_pkt.u.reply.data);
  
  		/* count value */
  		rlen = ntohl(rpc_pkt.u.reply.data[1 + nfsv3_data_offset]);
  		/* Skip unused values :
  			EOF:		32 bits value,
  			data_size:	32 bits value,
  		*/
  		data_ptr = (uchar *)
  			&(rpc_pkt.u.reply.data[4 + nfsv3_data_offset]);
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
692
  	}
aa207cf3a   liucheng (G)   CVE-2019-14194/CV...
693
694
  	if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + rlen) > len)
  			return -9999;
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
695
696
  	if (store_block(data_ptr, nfs_offset, rlen))
  			return -9999;
cbd8a35c6   wdenk   * Patch by Masami...
697
698
699
700
701
702
703
  
  	return rlen;
  }
  
  /**************************************************************************
  Interfaces of U-BOOT
  **************************************************************************/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
704
  static void nfs_timeout_handler(void)
a5725fabc   wdenk   * Patch by Ganapa...
705
  {
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
706
  	if (++nfs_timeout_count > NFS_RETRY_COUNT) {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
707
708
709
  		puts("
  Retry count exceeded; starting again
  ");
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
710
  		net_start_again();
aabb8cb08   Evan Samanas   nfs: NfsTimeout()...
711
712
  	} else {
  		puts("T ");
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
713
714
715
  		net_set_timeout_handler(nfs_timeout +
  					NFS_TIMEOUT * nfs_timeout_count,
  					nfs_timeout_handler);
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
716
  		nfs_send();
fe891ecf4   Hiroshi Ito   NFS Timeout with ...
717
  	}
a5725fabc   wdenk   * Patch by Ganapa...
718
  }
049a95a77   Joe Hershberger   net: cosmetic: Ch...
719
720
  static void nfs_handler(uchar *pkt, unsigned dest, struct in_addr sip,
  			unsigned src, unsigned len)
cbd8a35c6   wdenk   * Patch by Masami...
721
722
  {
  	int rlen;
fa84fa708   Matthias Brugger   net: nfs: add dyn...
723
  	int reply;
cbd8a35c6   wdenk   * Patch by Masami...
724

0ebf04c60   Robin Getz   minor debug clean...
725
726
  	debug("%s
  ", __func__);
cbd8a35c6   wdenk   * Patch by Masami...
727

741a8a08e   liucheng (G)   CVE: nfs: fix sta...
728
729
  	if (len > sizeof(struct rpc_t))
  		return;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
730
  	if (dest != nfs_our_port)
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
731
  		return;
cbd8a35c6   wdenk   * Patch by Masami...
732

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
733
  	switch (nfs_state) {
cbd8a35c6   wdenk   * Patch by Masami...
734
  	case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
fa84fa708   Matthias Brugger   net: nfs: add dyn...
735
736
  		if (rpc_lookup_reply(PROG_MOUNT, pkt, len) == -NFS_RPC_DROP)
  			break;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
737
738
  		nfs_state = STATE_PRCLOOKUP_PROG_NFS_REQ;
  		nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
739
740
741
  		break;
  
  	case STATE_PRCLOOKUP_PROG_NFS_REQ:
fa84fa708   Matthias Brugger   net: nfs: add dyn...
742
743
  		if (rpc_lookup_reply(PROG_NFS, pkt, len) == -NFS_RPC_DROP)
  			break;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
744
745
  		nfs_state = STATE_MOUNT_REQ;
  		nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
746
747
748
  		break;
  
  	case STATE_MOUNT_REQ:
fa84fa708   Matthias Brugger   net: nfs: add dyn...
749
  		reply = nfs_mount_reply(pkt, len);
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
750
  		if (reply == -NFS_RPC_DROP) {
fa84fa708   Matthias Brugger   net: nfs: add dyn...
751
  			break;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
752
  		} else if (reply == -NFS_RPC_ERR) {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
753
754
  			puts("*** ERROR: Cannot mount
  ");
cbd8a35c6   wdenk   * Patch by Masami...
755
  			/* just to be sure... */
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
756
757
  			nfs_state = STATE_UMOUNT_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
758
  		} else {
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
759
760
  			nfs_state = STATE_LOOKUP_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
761
762
763
764
  		}
  		break;
  
  	case STATE_UMOUNT_REQ:
fa84fa708   Matthias Brugger   net: nfs: add dyn...
765
  		reply = nfs_umountall_reply(pkt, len);
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
766
  		if (reply == -NFS_RPC_DROP) {
fa84fa708   Matthias Brugger   net: nfs: add dyn...
767
  			break;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
768
  		} else if (reply == -NFS_RPC_ERR) {
d89ff2df3   Joe Hershberger   net: nfs: Move so...
769
770
  			debug("*** ERROR: Cannot umount
  ");
22f6e99d5   Joe Hershberger   net: Refactor to ...
771
  			net_set_state(NETLOOP_FAIL);
cbd8a35c6   wdenk   * Patch by Masami...
772
  		} else {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
773
774
775
  			puts("
  done
  ");
22f6e99d5   Joe Hershberger   net: Refactor to ...
776
  			net_set_state(nfs_download_state);
cbd8a35c6   wdenk   * Patch by Masami...
777
778
779
780
  		}
  		break;
  
  	case STATE_LOOKUP_REQ:
fa84fa708   Matthias Brugger   net: nfs: add dyn...
781
  		reply = nfs_lookup_reply(pkt, len);
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
782
  		if (reply == -NFS_RPC_DROP) {
fa84fa708   Matthias Brugger   net: nfs: add dyn...
783
  			break;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
784
  		} else if (reply == -NFS_RPC_ERR) {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
785
786
  			puts("*** ERROR: File lookup fail
  ");
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
787
788
  			nfs_state = STATE_UMOUNT_REQ;
  			nfs_send();
347a90159   Joe Hershberger   net: nfs: Fix lin...
789
790
  		} else if (reply == -NFS_RPC_PROG_MISMATCH &&
  			   supported_nfs_versions != 0) {
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
791
792
793
794
795
796
  			/* umount */
  			nfs_state = STATE_UMOUNT_REQ;
  			nfs_send();
  			/* And retry with another supported version */
  			nfs_state = STATE_PRCLOOKUP_PROG_MOUNT_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
797
  		} else {
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
798
  			nfs_state = STATE_READ_REQ;
cbd8a35c6   wdenk   * Patch by Masami...
799
800
  			nfs_offset = 0;
  			nfs_len = NFS_READ_SIZE;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
801
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
802
803
804
805
  		}
  		break;
  
  	case STATE_READLINK_REQ:
fa84fa708   Matthias Brugger   net: nfs: add dyn...
806
  		reply = nfs_readlink_reply(pkt, len);
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
807
  		if (reply == -NFS_RPC_DROP) {
fa84fa708   Matthias Brugger   net: nfs: add dyn...
808
  			break;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
809
  		} else if (reply == -NFS_RPC_ERR) {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
810
811
  			puts("*** ERROR: Symlink fail
  ");
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
812
813
  			nfs_state = STATE_UMOUNT_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
814
  		} else {
0ebf04c60   Robin Getz   minor debug clean...
815
816
  			debug("Symlink --> %s
  ", nfs_path);
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
817
818
  			nfs_filename = basename(nfs_path);
  			nfs_path     = dirname(nfs_path);
cbd8a35c6   wdenk   * Patch by Masami...
819

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
820
821
  			nfs_state = STATE_MOUNT_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
822
823
824
825
  		}
  		break;
  
  	case STATE_READ_REQ:
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
826
  		rlen = nfs_read_reply(pkt, len);
d48d40a09   Vasily Khoruzhick   net: nfs: don't f...
827
828
  		if (rlen == -NFS_RPC_DROP)
  			break;
bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
829
  		net_set_timeout_handler(nfs_timeout, nfs_timeout_handler);
cbd8a35c6   wdenk   * Patch by Masami...
830
831
  		if (rlen > 0) {
  			nfs_offset += rlen;
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
832
  			nfs_send();
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
833
  		} else if ((rlen == -NFSERR_ISDIR) || (rlen == -NFSERR_INVAL)) {
cbd8a35c6   wdenk   * Patch by Masami...
834
  			/* symbolic link */
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
835
836
  			nfs_state = STATE_READLINK_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
837
  		} else {
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
838
  			if (!rlen)
22f6e99d5   Joe Hershberger   net: Refactor to ...
839
  				nfs_download_state = NETLOOP_SUCCESS;
b0baca982   Guillaume GARDET   net: NFS: Add NFS...
840
  			if (rlen < 0)
d89ff2df3   Joe Hershberger   net: nfs: Move so...
841
842
  				debug("NFS READ error (%d)
  ", rlen);
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
843
844
  			nfs_state = STATE_UMOUNT_REQ;
  			nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
845
846
847
848
  		}
  		break;
  	}
  }
cbd8a35c6   wdenk   * Patch by Masami...
849

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
850
  void nfs_start(void)
cbd8a35c6   wdenk   * Patch by Masami...
851
  {
0ebf04c60   Robin Getz   minor debug clean...
852
853
  	debug("%s
  ", __func__);
22f6e99d5   Joe Hershberger   net: Refactor to ...
854
  	nfs_download_state = NETLOOP_FAIL;
cbd8a35c6   wdenk   * Patch by Masami...
855

049a95a77   Joe Hershberger   net: cosmetic: Ch...
856
  	nfs_server_ip = net_server_ip;
cbd8a35c6   wdenk   * Patch by Masami...
857
858
859
  	nfs_path = (char *)nfs_path_buff;
  
  	if (nfs_path == NULL) {
22f6e99d5   Joe Hershberger   net: Refactor to ...
860
  		net_set_state(NETLOOP_FAIL);
faecf84ab   Joe Hershberger   net: Always print...
861
862
  		printf("*** ERROR: Fail allocate memory
  ");
cbd8a35c6   wdenk   * Patch by Masami...
863
864
  		return;
  	}
6ab128309   Joe Hershberger   net: Consolidate ...
865
866
  	if (!net_parse_bootfile(&nfs_server_ip, nfs_path,
  				sizeof(nfs_path_buff))) {
f8b26c7ad   Joe Hershberger   net: nfs: Remove ...
867
  		sprintf(nfs_path, "/nfsroot/%02X%02X%02X%02X.img",
049a95a77   Joe Hershberger   net: cosmetic: Ch...
868
869
870
871
  			net_ip.s_addr & 0xFF,
  			(net_ip.s_addr >>  8) & 0xFF,
  			(net_ip.s_addr >> 16) & 0xFF,
  			(net_ip.s_addr >> 24) & 0xFF);
cbd8a35c6   wdenk   * Patch by Masami...
872

faecf84ab   Joe Hershberger   net: Always print...
873
874
875
  		printf("*** Warning: no boot file name; using '%s'
  ",
  		       nfs_path);
cbd8a35c6   wdenk   * Patch by Masami...
876
  	}
c9f6c91b4   Joe Hershberger   net: cosmetic: nf...
877
878
  	nfs_filename = basename(nfs_path);
  	nfs_path     = dirname(nfs_path);
cbd8a35c6   wdenk   * Patch by Masami...
879

faecf84ab   Joe Hershberger   net: Always print...
880
881
  	printf("Using %s device
  ", eth_get_name());
cbd8a35c6   wdenk   * Patch by Masami...
882

faecf84ab   Joe Hershberger   net: Always print...
883
884
  	printf("File transfer via NFS from server %pI4; our IP address is %pI4",
  	       &nfs_server_ip, &net_ip);
cbd8a35c6   wdenk   * Patch by Masami...
885
886
  
  	/* Check if we need to send across this subnet */
049a95a77   Joe Hershberger   net: cosmetic: Ch...
887
888
889
  	if (net_gateway.s_addr && net_netmask.s_addr) {
  		struct in_addr our_net;
  		struct in_addr server_net;
cbd8a35c6   wdenk   * Patch by Masami...
890

049a95a77   Joe Hershberger   net: cosmetic: Ch...
891
  		our_net.s_addr = net_ip.s_addr & net_netmask.s_addr;
347e32b01   Joe Hershberger   net: Check subnet...
892
  		server_net.s_addr = nfs_server_ip.s_addr & net_netmask.s_addr;
049a95a77   Joe Hershberger   net: cosmetic: Ch...
893
  		if (our_net.s_addr != server_net.s_addr)
faecf84ab   Joe Hershberger   net: Always print...
894
895
  			printf("; sending through gateway %pI4",
  			       &net_gateway);
cbd8a35c6   wdenk   * Patch by Masami...
896
  	}
faecf84ab   Joe Hershberger   net: Always print...
897
898
  	printf("
  Filename '%s/%s'.", nfs_path, nfs_filename);
cbd8a35c6   wdenk   * Patch by Masami...
899

1411157d8   Joe Hershberger   net: cosmetic: Fi...
900
  	if (net_boot_file_expected_size_in_blocks) {
faecf84ab   Joe Hershberger   net: Always print...
901
902
  		printf(" Size is 0x%x Bytes = ",
  		       net_boot_file_expected_size_in_blocks << 9);
1411157d8   Joe Hershberger   net: cosmetic: Fi...
903
  		print_size(net_boot_file_expected_size_in_blocks << 9, "");
cbd8a35c6   wdenk   * Patch by Masami...
904
  	}
bb872dd93   Simon Glass   image: Rename loa...
905
906
907
  	printf("
  Load address: 0x%lx
  Loading: *\b", image_load_addr);
cbd8a35c6   wdenk   * Patch by Masami...
908

bc0571fc1   Joe Hershberger   net: cosmetic: Fi...
909
  	net_set_timeout_handler(nfs_timeout, nfs_timeout_handler);
049a95a77   Joe Hershberger   net: cosmetic: Ch...
910
  	net_set_udp_handler(nfs_handler);
cbd8a35c6   wdenk   * Patch by Masami...
911

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
912
913
  	nfs_timeout_count = 0;
  	nfs_state = STATE_PRCLOOKUP_PROG_MOUNT_REQ;
cbd8a35c6   wdenk   * Patch by Masami...
914

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
915
  	/*nfs_our_port = 4096 + (get_ticks() % 3072);*/
cbd8a35c6   wdenk   * Patch by Masami...
916
  	/*FIX ME !!!*/
68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
917
  	nfs_our_port = 1000;
cbd8a35c6   wdenk   * Patch by Masami...
918
919
  
  	/* zero out server ether in case the server ip has changed */
0adb5b761   Joe Hershberger   net: cosmetic: Na...
920
  	memset(net_server_ethaddr, 0, 6);
cbd8a35c6   wdenk   * Patch by Masami...
921

68c76a3a3   Joe Hershberger   net: cosmetic: Cl...
922
  	nfs_send();
cbd8a35c6   wdenk   * Patch by Masami...
923
  }