Browse Source

Updated to new protocol API, made to compile.

tags/v0.9.3
Michael Brown 20 years ago
parent
commit
3af0af65a0
1 changed files with 85 additions and 68 deletions
  1. 85
    68
      src/proto/nfs.c

+ 85
- 68
src/proto/nfs.c View File

1
-#ifdef	DOWNLOAD_PROTO_NFS
2
-
3
 #include "etherboot.h"
1
 #include "etherboot.h"
2
+#include "init.h"
3
+#include "proto.h"
4
+#include "in.h"
4
 #include "nic.h"
5
 #include "nic.h"
5
 
6
 
6
 /* NOTE: the NFS code is heavily inspired by the NetBSD netboot code (read:
7
 /* NOTE: the NFS code is heavily inspired by the NetBSD netboot code (read:
24
 #define OPORT_SWEEP 200		/* make sure we don't leave secure range */
25
 #define OPORT_SWEEP 200		/* make sure we don't leave secure range */
25
 
26
 
26
 static int oport = START_OPORT;
27
 static int oport = START_OPORT;
27
-static int mount_port = -1;
28
-static int nfs_port = -1;
29
-static int fs_mounted = 0;
28
+static struct sockaddr_in mount_server;
29
+static struct sockaddr_in nfs_server;
30
 static unsigned long rpc_id;
30
 static unsigned long rpc_id;
31
 
31
 
32
 /**************************************************************************
32
 /**************************************************************************
33
 RPC_INIT - set up the ID counter to something fairly random
33
 RPC_INIT - set up the ID counter to something fairly random
34
 **************************************************************************/
34
 **************************************************************************/
35
-void rpc_init(void)
35
+static void rpc_init(void)
36
 {
36
 {
37
 	unsigned long t;
37
 	unsigned long t;
38
 
38
 
40
 	rpc_id = t ^ (t << 8) ^ (t << 16);
40
 	rpc_id = t ^ (t << 8) ^ (t << 16);
41
 }
41
 }
42
 
42
 
43
-
44
 /**************************************************************************
43
 /**************************************************************************
45
 RPC_PRINTERROR - Print a low level RPC error message
44
 RPC_PRINTERROR - Print a low level RPC error message
46
 **************************************************************************/
45
 **************************************************************************/
50
 	    rpc->u.reply.astatus) {
49
 	    rpc->u.reply.astatus) {
51
 		/* rpc_printerror() is called for any RPC related error,
50
 		/* rpc_printerror() is called for any RPC related error,
52
 		 * suppress output if no low level RPC error happened.  */
51
 		 * suppress output if no low level RPC error happened.  */
53
-		printf("RPC error: (%d,%d,%d)\n", ntohl(rpc->u.reply.rstatus),
54
-			ntohl(rpc->u.reply.verifier),
55
-			ntohl(rpc->u.reply.astatus));
52
+		DBG("RPC error: (%d,%d,%d)\n", ntohl(rpc->u.reply.rstatus),
53
+		    ntohl(rpc->u.reply.verifier),
54
+		    ntohl(rpc->u.reply.astatus));
56
 	}
55
 	}
57
 }
56
 }
58
 
57
 
60
 AWAIT_RPC - Wait for an rpc packet
59
 AWAIT_RPC - Wait for an rpc packet
61
 **************************************************************************/
60
 **************************************************************************/
62
 static int await_rpc(int ival, void *ptr,
61
 static int await_rpc(int ival, void *ptr,
63
-	unsigned short ptype, struct iphdr *ip, struct udphdr *udp)
62
+		     unsigned short ptype __unused, struct iphdr *ip,
63
+		     struct udphdr *udp, struct tcphdr *tcp __unused)
64
 {
64
 {
65
 	struct rpc_t *rpc;
65
 	struct rpc_t *rpc;
66
 	if (!udp) 
66
 	if (!udp) 
82
 /**************************************************************************
82
 /**************************************************************************
83
 RPC_LOOKUP - Lookup RPC Port numbers
83
 RPC_LOOKUP - Lookup RPC Port numbers
84
 **************************************************************************/
84
 **************************************************************************/
85
-static int rpc_lookup(int addr, int prog, int ver, int sport)
85
+static int rpc_lookup(struct sockaddr_in *addr, int prog, int ver, int sport)
86
 {
86
 {
87
 	struct rpc_t buf, *rpc;
87
 	struct rpc_t buf, *rpc;
88
 	unsigned long id;
88
 	unsigned long id;
103
 	*p++ = htonl(ver);
103
 	*p++ = htonl(ver);
104
 	*p++ = htonl(IP_UDP);
104
 	*p++ = htonl(IP_UDP);
105
 	*p++ = 0;
105
 	*p++ = 0;
106
+	if ( ! addr->sin_port ) {
107
+		addr->sin_port = SUNRPC_PORT;
108
+	}
106
 	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
109
 	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
107
 		long timeout;
110
 		long timeout;
108
-		udp_transmit(arptable[addr].ipaddr.s_addr, sport, SUNRPC_PORT,
111
+		udp_transmit(addr->sin_addr.s_addr, sport, addr->sin_port,
109
 			(char *)p - (char *)&buf, &buf);
112
 			(char *)p - (char *)&buf, &buf);
110
 		timeout = rfc2131_sleep_interval(TIMEOUT, retries);
113
 		timeout = rfc2131_sleep_interval(TIMEOUT, retries);
111
 		if (await_reply(await_rpc, sport, &id, timeout)) {
114
 		if (await_reply(await_rpc, sport, &id, timeout)) {
113
 			if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||
116
 			if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||
114
 			    rpc->u.reply.astatus) {
117
 			    rpc->u.reply.astatus) {
115
 				rpc_printerror(rpc);
118
 				rpc_printerror(rpc);
116
-				return -1;
119
+				return 0;
117
 			} else {
120
 			} else {
118
 				return ntohl(rpc->u.reply.data[0]);
121
 				return ntohl(rpc->u.reply.data[0]);
119
 			}
122
 			}
120
 		}
123
 		}
121
 	}
124
 	}
122
-	return -1;
125
+	return 0;
123
 }
126
 }
124
 
127
 
125
 /**************************************************************************
128
 /**************************************************************************
197
 /**************************************************************************
200
 /**************************************************************************
198
 NFS_MOUNT - Mount an NFS Filesystem
201
 NFS_MOUNT - Mount an NFS Filesystem
199
 **************************************************************************/
202
 **************************************************************************/
200
-static int nfs_mount(int server, int port, char *path, char *fh, int sport)
203
+static int nfs_mount(struct sockaddr_in *server, char *path, char *fh, int sport)
201
 {
204
 {
202
 	struct rpc_t buf, *rpc;
205
 	struct rpc_t buf, *rpc;
203
 	unsigned long id;
206
 	unsigned long id;
221
 	p += (pathlen + 3) / 4;
224
 	p += (pathlen + 3) / 4;
222
 	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
225
 	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
223
 		long timeout;
226
 		long timeout;
224
-		udp_transmit(arptable[server].ipaddr.s_addr, sport, port,
227
+		udp_transmit(server->sin_addr.s_addr, sport, server->sin_port,
225
 			(char *)p - (char *)&buf, &buf);
228
 			(char *)p - (char *)&buf, &buf);
226
 		timeout = rfc2131_sleep_interval(TIMEOUT, retries);
229
 		timeout = rfc2131_sleep_interval(TIMEOUT, retries);
227
 		if (await_reply(await_rpc, sport, &id, timeout)) {
230
 		if (await_reply(await_rpc, sport, &id, timeout)) {
239
 				}
242
 				}
240
 				return -ntohl(rpc->u.reply.data[0]);
243
 				return -ntohl(rpc->u.reply.data[0]);
241
 			} else {
244
 			} else {
242
-				fs_mounted = 1;
243
 				memcpy(fh, rpc->u.reply.data + 1, NFS_FHSIZE);
245
 				memcpy(fh, rpc->u.reply.data + 1, NFS_FHSIZE);
244
 				return 0;
246
 				return 0;
245
 			}
247
 			}
251
 /**************************************************************************
253
 /**************************************************************************
252
 NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server
254
 NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server
253
 **************************************************************************/
255
 **************************************************************************/
254
-void nfs_umountall(int server)
256
+static void nfs_umountall(struct sockaddr_in *server)
255
 {
257
 {
256
 	struct rpc_t buf, *rpc;
258
 	struct rpc_t buf, *rpc;
257
 	unsigned long id;
259
 	unsigned long id;
258
 	int retries;
260
 	int retries;
259
 	long *p;
261
 	long *p;
260
 
262
 
261
-	if (!arptable[server].ipaddr.s_addr) {
262
-		/* Haven't sent a single UDP packet to this server */
263
-		return;
264
-	}
265
-	if ((mount_port == -1) || (!fs_mounted)) {
266
-		/* Nothing mounted, nothing to umount */
267
-		return;
268
-	}
269
 	id = rpc_id++;
263
 	id = rpc_id++;
270
 	buf.u.call.id = htonl(id);
264
 	buf.u.call.id = htonl(id);
271
 	buf.u.call.type = htonl(MSG_CALL);
265
 	buf.u.call.type = htonl(MSG_CALL);
276
 	p = rpc_add_credentials((long *)buf.u.call.data);
270
 	p = rpc_add_credentials((long *)buf.u.call.data);
277
 	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
271
 	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
278
 		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);
272
 		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);
279
-		udp_transmit(arptable[server].ipaddr.s_addr, oport, mount_port,
273
+		udp_transmit(server->sin_addr.s_addr, oport, server->sin_port,
280
 			(char *)p - (char *)&buf, &buf);
274
 			(char *)p - (char *)&buf, &buf);
281
 		if (await_reply(await_rpc, oport, &id, timeout)) {
275
 		if (await_reply(await_rpc, oport, &id, timeout)) {
282
 			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];
276
 			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];
284
 			    rpc->u.reply.astatus) {
278
 			    rpc->u.reply.astatus) {
285
 				rpc_printerror(rpc);
279
 				rpc_printerror(rpc);
286
 			}
280
 			}
287
-			fs_mounted = 0;
288
-			return;
281
+			break;
289
 		}
282
 		}
290
 	}
283
 	}
291
 }
284
 }
285
+
286
+/**************************************************************************
287
+NFS_RESET - Reset the NFS subsystem
288
+**************************************************************************/
289
+static void nfs_reset ( void ) {
290
+	/* If we have a mount server, call nfs_umountall() */
291
+	if ( mount_server.sin_addr.s_addr ) {
292
+		nfs_umountall ( &mount_server );
293
+	}
294
+	/* Zero the data structures */
295
+	memset ( &mount_server, 0, sizeof ( mount_server ) );
296
+	memset ( &nfs_server, 0, sizeof ( nfs_server ) );
297
+}
298
+
292
 /***************************************************************************
299
 /***************************************************************************
293
  * NFS_READLINK (AH 2003-07-14)
300
  * NFS_READLINK (AH 2003-07-14)
294
  * This procedure is called when read of the first block fails -
301
  * This procedure is called when read of the first block fails -
296
  * In case of successful readlink(), the dirname is manipulated,
303
  * In case of successful readlink(), the dirname is manipulated,
297
  * so that inside the nfs() function a recursion can be done.
304
  * so that inside the nfs() function a recursion can be done.
298
  **************************************************************************/
305
  **************************************************************************/
299
-static int nfs_readlink(int server, int port, char *fh, char *path, char *nfh,
300
-	int sport)
306
+static int nfs_readlink(struct sockaddr_in *server, char *fh __unused,
307
+			char *path, char *nfh, int sport)
301
 {
308
 {
302
 	struct rpc_t buf, *rpc;
309
 	struct rpc_t buf, *rpc;
303
 	unsigned long id;
310
 	unsigned long id;
317
 	p += (NFS_FHSIZE / 4);
324
 	p += (NFS_FHSIZE / 4);
318
 	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
325
 	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
319
 		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);
326
 		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);
320
-		udp_transmit(arptable[server].ipaddr.s_addr, sport, port,
327
+		udp_transmit(server->sin_addr.s_addr, sport, server->sin_port,
321
 			(char *)p - (char *)&buf, &buf);
328
 			(char *)p - (char *)&buf, &buf);
322
 		if (await_reply(await_rpc, sport, &id, timeout)) {
329
 		if (await_reply(await_rpc, sport, &id, timeout)) {
323
 			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];
330
 			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];
361
 /**************************************************************************
368
 /**************************************************************************
362
 NFS_LOOKUP - Lookup Pathname
369
 NFS_LOOKUP - Lookup Pathname
363
 **************************************************************************/
370
 **************************************************************************/
364
-static int nfs_lookup(int server, int port, char *fh, char *path, char *nfh,
371
+static int nfs_lookup(struct sockaddr_in *server, char *fh, char *path, char *nfh,
365
 	int sport)
372
 	int sport)
366
 {
373
 {
367
 	struct rpc_t buf, *rpc;
374
 	struct rpc_t buf, *rpc;
388
 	p += (pathlen + 3) / 4;
395
 	p += (pathlen + 3) / 4;
389
 	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
396
 	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {
390
 		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);
397
 		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);
391
-		udp_transmit(arptable[server].ipaddr.s_addr, sport, port,
398
+		udp_transmit(server->sin_addr.s_addr, sport, server->sin_port,
392
 			(char *)p - (char *)&buf, &buf);
399
 			(char *)p - (char *)&buf, &buf);
393
 		if (await_reply(await_rpc, sport, &id, timeout)) {
400
 		if (await_reply(await_rpc, sport, &id, timeout)) {
394
 			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];
401
 			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];
416
 /**************************************************************************
423
 /**************************************************************************
417
 NFS_READ - Read File on NFS Server
424
 NFS_READ - Read File on NFS Server
418
 **************************************************************************/
425
 **************************************************************************/
419
-static int nfs_read(int server, int port, char *fh, int offset, int len,
426
+static int nfs_read(struct sockaddr_in *server, char *fh, int offset, int len,
420
 		    int sport)
427
 		    int sport)
421
 {
428
 {
422
 	struct rpc_t buf, *rpc;
429
 	struct rpc_t buf, *rpc;
450
 		if (tokens >= 2)
457
 		if (tokens >= 2)
451
 			timeout = TICKS_PER_SEC/2;
458
 			timeout = TICKS_PER_SEC/2;
452
 
459
 
453
-		udp_transmit(arptable[server].ipaddr.s_addr, sport, port,
460
+		udp_transmit(server->sin_addr.s_addr, sport, server->sin_port,
454
 			(char *)p - (char *)&buf, &buf);
461
 			(char *)p - (char *)&buf, &buf);
455
 		if (await_reply(await_rpc, sport, &id, timeout)) {
462
 		if (await_reply(await_rpc, sport, &id, timeout)) {
456
 			if (tokens < 256)
463
 			if (tokens < 256)
480
 /**************************************************************************
487
 /**************************************************************************
481
 NFS - Download extended BOOTP data, or kernel image from NFS server
488
 NFS - Download extended BOOTP data, or kernel image from NFS server
482
 **************************************************************************/
489
 **************************************************************************/
483
-int nfs(const char *name, int (*fnc)(unsigned char *, unsigned int, unsigned int, int))
484
-{
490
+static int nfs ( char *url __unused,
491
+		 struct sockaddr_in *server,
492
+		 char *name,
493
+		 int ( * process ) ( unsigned char *data,
494
+				     unsigned int blocknum,
495
+				     unsigned int len, int eof ) ) {
485
 	static int recursion = 0;
496
 	static int recursion = 0;
486
 	int sport;
497
 	int sport;
487
 	int err, namelen = strlen(name);
498
 	int err, namelen = strlen(name);
492
 	int rlen, size, offs, len;
503
 	int rlen, size, offs, len;
493
 	struct rpc_t *rpc;
504
 	struct rpc_t *rpc;
494
 
505
 
495
-	rx_qdrain();
496
-
497
 	sport = oport++;
506
 	sport = oport++;
498
 	if (oport > START_OPORT+OPORT_SWEEP) {
507
 	if (oport > START_OPORT+OPORT_SWEEP) {
499
 		oport = START_OPORT;
508
 		oport = START_OPORT;
500
 	}
509
 	}
510
+
511
+	mount_server.sin_addr = nfs_server.sin_addr = server->sin_addr;
512
+	mount_server.sin_port = rpc_lookup(server, PROG_MOUNT, 1, sport);
513
+	if ( ! mount_server.sin_port ) {
514
+		DBG ( "Cannot get mount port from %!:%d\n",
515
+		      server->sin_addr.s_addr, server->sin_port );
516
+		return 0;
517
+	}
518
+	nfs_server.sin_port = rpc_lookup(server, PROG_NFS, 2, sport);
519
+	if ( ! mount_server.sin_port ) {
520
+		DBG ( "Cannot get nfs port from %!:%d\n",
521
+		      server->sin_addr.s_addr, server->sin_port );
522
+		return 0;
523
+	}
524
+
501
 	if ( name != dirname ) {
525
 	if ( name != dirname ) {
502
 		memcpy(dirname, name, namelen + 1);
526
 		memcpy(dirname, name, namelen + 1);
503
 	}
527
 	}
504
 	recursion = 0;
528
 	recursion = 0;
505
 nfssymlink:
529
 nfssymlink:
506
 	if ( recursion > NFS_MAXLINKDEPTH ) {
530
 	if ( recursion > NFS_MAXLINKDEPTH ) {
507
-		printf ( "\nRecursion: More than %d symlinks followed. Abort.\n", NFS_MAXLINKDEPTH );
531
+		DBG ( "\nRecursion: More than %d symlinks followed. Abort.\n",
532
+		      NFS_MAXLINKDEPTH );
508
 		return	0;
533
 		return	0;
509
 	}
534
 	}
510
 	recursion++;
535
 	recursion++;
518
 		fname--;
543
 		fname--;
519
 	}
544
 	}
520
 	if (fname < dirname) {
545
 	if (fname < dirname) {
521
-		printf("can't parse file name %s\n", name);
546
+		DBG("can't parse file name %s\n", name);
522
 		return 0;
547
 		return 0;
523
 	}
548
 	}
524
 
549
 
525
-	if (mount_port == -1) {
526
-		mount_port = rpc_lookup(ARP_SERVER, PROG_MOUNT, 1, sport);
527
-	}
528
-	if (nfs_port == -1) {
529
-		nfs_port = rpc_lookup(ARP_SERVER, PROG_NFS, 2, sport);
530
-	}
531
-	if (nfs_port == -1 || mount_port == -1) {
532
-		printf("can't get nfs/mount ports from portmapper\n");
533
-		return 0;
534
-	}
535
-
536
-
537
-	err = nfs_mount(ARP_SERVER, mount_port, dirname, dirfh, sport);
550
+	err = nfs_mount(&mount_server, dirname, dirfh, sport);
538
 	if (err) {
551
 	if (err) {
539
-		printf("mounting %s: ", dirname);
552
+		DBG("mounting %s: ", dirname);
540
 		nfs_printerror(err);
553
 		nfs_printerror(err);
541
 		/* just to be sure... */
554
 		/* just to be sure... */
542
-		nfs_umountall(ARP_SERVER);
555
+		nfs_reset();
543
 		return 0;
556
 		return 0;
544
 	}
557
 	}
545
 
558
 
546
-	err = nfs_lookup(ARP_SERVER, nfs_port, dirfh, fname, filefh, sport);
559
+	err = nfs_lookup(&nfs_server, dirfh, fname, filefh, sport);
547
 	if (err) {
560
 	if (err) {
548
-		printf("looking up %s: ", fname);
561
+		DBG("looking up %s: ", fname);
549
 		nfs_printerror(err);
562
 		nfs_printerror(err);
550
-		nfs_umountall(ARP_SERVER);
563
+		nfs_reset();
551
 		return 0;
564
 		return 0;
552
 	}
565
 	}
553
 
566
 
556
 	size = -1;	/* will be set properly with the first reply */
569
 	size = -1;	/* will be set properly with the first reply */
557
 	len = NFS_READ_SIZE;	/* first request is always full size */
570
 	len = NFS_READ_SIZE;	/* first request is always full size */
558
 	do {
571
 	do {
559
-		err = nfs_read(ARP_SERVER, nfs_port, filefh, offs, len, sport);
572
+		err = nfs_read(&nfs_server, filefh, offs, len, sport);
560
                 if ((err <= -NFSERR_ISDIR)&&(err >= -NFSERR_INVAL) && (offs == 0)) {
573
                 if ((err <= -NFSERR_ISDIR)&&(err >= -NFSERR_INVAL) && (offs == 0)) {
561
 			// An error occured. NFS servers tend to sending
574
 			// An error occured. NFS servers tend to sending
562
 			// errors 21 / 22 when symlink instead of real file
575
 			// errors 21 / 22 when symlink instead of real file
563
 			// is requested. So check if it's a symlink!
576
 			// is requested. So check if it's a symlink!
564
-			block = nfs_readlink(ARP_SERVER, nfs_port, dirfh, dirname,
577
+			block = nfs_readlink(&nfs_server, dirfh, dirname,
565
 			                filefh, sport);
578
 			                filefh, sport);
566
 			if ( 0 == block ) {
579
 			if ( 0 == block ) {
567
 				printf("\nLoading symlink:%s ..",dirname);
580
 				printf("\nLoading symlink:%s ..",dirname);
568
 				goto nfssymlink;
581
 				goto nfssymlink;
569
 			}
582
 			}
570
 			nfs_printerror(err);
583
 			nfs_printerror(err);
571
-			nfs_umountall(ARP_SERVER);
584
+			nfs_reset();
572
 			return 0;
585
 			return 0;
573
 		}
586
 		}
574
 		if (err) {
587
 		if (err) {
575
 			printf("reading at offset %d: ", offs);
588
 			printf("reading at offset %d: ", offs);
576
 			nfs_printerror(err);
589
 			nfs_printerror(err);
577
-			nfs_umountall(ARP_SERVER);
590
+			nfs_reset();
578
 			return 0;
591
 			return 0;
579
 		}
592
 		}
580
 
593
 
589
 			rlen = len;	/* shouldn't happen...  */
602
 			rlen = len;	/* shouldn't happen...  */
590
 		}
603
 		}
591
 
604
 
592
-		err = fnc((char *)&rpc->u.reply.data[19], block, rlen,
605
+		err = process((char *)&rpc->u.reply.data[19], block, rlen,
593
 			(offs+rlen == size));
606
 			(offs+rlen == size));
594
 		if (err <= 0) {
607
 		if (err <= 0) {
595
-			nfs_umountall(ARP_SERVER);
608
+			nfs_reset();
596
 			return err;
609
 			return err;
597
 		}
610
 		}
598
 
611
 
607
 	return 1;
620
 	return 1;
608
 }
621
 }
609
 
622
 
610
-#endif	/* DOWNLOAD_PROTO_NFS */
623
+INIT_FN ( INIT_RPC, rpc_init, nfs_reset, nfs_reset );
624
+
625
+static struct protocol nfs_protocol __protocol = {
626
+	"nfs", nfs
627
+};

Loading…
Cancel
Save