⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nfs.c

📁 linux下从网卡远程启动
💻 C
📖 第 1 页 / 共 2 页
字号:
	id = rpc_id++;	buf.u.call.id = htonl(id);	buf.u.call.type = htonl(MSG_CALL);	buf.u.call.rpcvers = htonl(2);	/* use RPC version 2 */	buf.u.call.prog = htonl(PROG_NFS);	buf.u.call.vers = htonl(2);	/* nfsd is version 2 */	buf.u.call.proc = htonl(NFS_READLINK);	p = rpc_add_credentials((long *)buf.u.call.data);	memcpy(p, nfh, NFS_FHSIZE);	p += (NFS_FHSIZE / 4);	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);		udp_transmit(arptable[server].ipaddr.s_addr, sport, port,			(char *)p - (char *)&buf, &buf);		if (await_reply(await_rpc, sport, &id, timeout)) {			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];			if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||			    rpc->u.reply.astatus || rpc->u.reply.data[0]) {				rpc_printerror(rpc);				if (rpc->u.reply.rstatus) {					/* RPC failed, no verifier, data[0] */					return -9999;				}				if (rpc->u.reply.astatus) {					/* RPC couldn't decode parameters */					return -9998;				}				return -ntohl(rpc->u.reply.data[0]);			} else {				// It *is* a link.				// If it's a relative link, append everything to dirname, filename TOO!				retries = strlen ( (char *)(&(rpc->u.reply.data[2]) ));				if ( *((char *)(&(rpc->u.reply.data[2]))) != '/' ) {					path[pathlen++] = '/';					while ( ( retries + pathlen ) > 298 ) {						retries--;					}					if ( retries > 0 ) {						memcpy(path + pathlen, &(rpc->u.reply.data[2]), retries + 1);					} else { retries = 0; }					path[pathlen + retries] = 0;				} else {					// Else make it the only path.					if ( retries > 298 ) { retries = 298; }					memcpy ( path, &(rpc->u.reply.data[2]), retries + 1 );					path[retries] = 0;				}				return 0;			}		}	}	return -1;}/**************************************************************************NFS_LOOKUP - Lookup Pathname**************************************************************************/static int nfs_lookup(int server, int port, char *fh, char *path, char *nfh,	int sport){	struct rpc_t buf, *rpc;	unsigned long id;	long *p;	int retries;	int pathlen = strlen(path);	id = rpc_id++;	buf.u.call.id = htonl(id);	buf.u.call.type = htonl(MSG_CALL);	buf.u.call.rpcvers = htonl(2);	/* use RPC version 2 */	buf.u.call.prog = htonl(PROG_NFS);	buf.u.call.vers = htonl(2);	/* nfsd is version 2 */	buf.u.call.proc = htonl(NFS_LOOKUP);	p = rpc_add_credentials((long *)buf.u.call.data);	memcpy(p, fh, NFS_FHSIZE);	p += (NFS_FHSIZE / 4);	*p++ = htonl(pathlen);	if (pathlen & 3) {		*(p + pathlen / 4) = 0;	/* add zero padding */	}	memcpy(p, path, pathlen);	p += (pathlen + 3) / 4;	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);		udp_transmit(arptable[server].ipaddr.s_addr, sport, port,			(char *)p - (char *)&buf, &buf);		if (await_reply(await_rpc, sport, &id, timeout)) {			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];			if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||			    rpc->u.reply.astatus || rpc->u.reply.data[0]) {				rpc_printerror(rpc);				if (rpc->u.reply.rstatus) {					/* RPC failed, no verifier, data[0] */					return -9999;				}				if (rpc->u.reply.astatus) {					/* RPC couldn't decode parameters */					return -9998;				}				return -ntohl(rpc->u.reply.data[0]);			} else {				memcpy(nfh, rpc->u.reply.data + 1, NFS_FHSIZE);				return 0;			}		}	}	return -1;}/**************************************************************************NFS_READ - Read File on NFS Server**************************************************************************/static int nfs_read(int server, int port, char *fh, int offset, int len,		    int sport){	struct rpc_t buf, *rpc;	unsigned long id;	int retries;	long *p;	static int tokens=0;	/*	 * Try to implement something similar to a window protocol in	 * terms of response to losses. On successful receive, increment	 * the number of tokens by 1 (cap at 256). On failure, halve it.	 * When the number of tokens is >= 2, use a very short timeout.	 */	id = rpc_id++;	buf.u.call.id = htonl(id);	buf.u.call.type = htonl(MSG_CALL);	buf.u.call.rpcvers = htonl(2);	/* use RPC version 2 */	buf.u.call.prog = htonl(PROG_NFS);	buf.u.call.vers = htonl(2);	/* nfsd is version 2 */	buf.u.call.proc = htonl(NFS_READ);	p = rpc_add_credentials((long *)buf.u.call.data);	memcpy(p, fh, NFS_FHSIZE);	p += NFS_FHSIZE / 4;	*p++ = htonl(offset);	*p++ = htonl(len);	*p++ = 0;		/* unused parameter */	for (retries = 0; retries < MAX_RPC_RETRIES; retries++) {		long timeout = rfc2131_sleep_interval(TIMEOUT, retries);		if (tokens >= 2)			timeout = TICKS_PER_SEC/2;		udp_transmit(arptable[server].ipaddr.s_addr, sport, port,			(char *)p - (char *)&buf, &buf);		if (await_reply(await_rpc, sport, &id, timeout)) {			if (tokens < 256)				tokens++;			rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];			if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||			    rpc->u.reply.astatus || rpc->u.reply.data[0]) {				rpc_printerror(rpc);				if (rpc->u.reply.rstatus) {					/* RPC failed, no verifier, data[0] */					return -9999;				}				if (rpc->u.reply.astatus) {					/* RPC couldn't decode parameters */					return -9998;				}				return -ntohl(rpc->u.reply.data[0]);			} else {				return 0;			}		} else			tokens >>= 1;	}	return -1;}/**************************************************************************NFS - Download extended BOOTP data, or kernel image from NFS server**************************************************************************/int nfs(const char *name, int (*fnc)(unsigned char *, unsigned int, unsigned int, int)){	static int recursion = 0;	int sport;	int err, namelen = strlen(name);	char dirname[300], *fname;	char dirfh[NFS_FHSIZE];		/* file handle of directory */	char filefh[NFS_FHSIZE];	/* file handle of kernel image */	unsigned int block;	int rlen, size, offs, len;	struct rpc_t *rpc;	rx_qdrain();	sport = oport++;	if (oport > START_OPORT+OPORT_SWEEP) {		oport = START_OPORT;	}	if ( name != dirname ) {		memcpy(dirname, name, namelen + 1);	}	recursion = 0;nfssymlink:	if ( recursion > NFS_MAXLINKDEPTH ) {		printf ( "\nRecursion: More than %d symlinks followed. Abort.\n", NFS_MAXLINKDEPTH );		return	0;	}	recursion++;	fname = dirname + (namelen - 1);	while (fname >= dirname) {		if (*fname == '/') {			*fname = '\0';			fname++;			break;		}		fname--;	}	if (fname < dirname) {		printf("can't parse file name %s\n", name);		return 0;	}	if (mount_port == -1) {		mount_port = rpc_lookup(ARP_SERVER, PROG_MOUNT, 1, sport);	}	if (nfs_port == -1) {		nfs_port = rpc_lookup(ARP_SERVER, PROG_NFS, 2, sport);	}	if (nfs_port == -1 || mount_port == -1) {		printf("can't get nfs/mount ports from portmapper\n");		return 0;	}	err = nfs_mount(ARP_SERVER, mount_port, dirname, dirfh, sport);	if (err) {		printf("mounting %s: ", dirname);		nfs_printerror(err);		/* just to be sure... */		nfs_umountall(ARP_SERVER);		return 0;	}	err = nfs_lookup(ARP_SERVER, nfs_port, dirfh, fname, filefh, sport);	if (err) {		printf("looking up %s: ", fname);		nfs_printerror(err);		nfs_umountall(ARP_SERVER);		return 0;	}	offs = 0;	block = 1;	/* blocks are numbered starting from 1 */	size = -1;	/* will be set properly with the first reply */	len = NFS_READ_SIZE;	/* first request is always full size */	do {		err = nfs_read(ARP_SERVER, nfs_port, filefh, offs, len, sport);                if ((err <= -NFSERR_ISDIR)&&(err >= -NFSERR_INVAL) && (offs == 0)) {			// An error occured. NFS servers tend to sending			// errors 21 / 22 when symlink instead of real file			// is requested. So check if it's a symlink!			block = nfs_readlink(ARP_SERVER, nfs_port, dirfh, dirname,			                filefh, sport);			if ( 0 == block ) {				printf("\nLoading symlink:%s ..",dirname);				goto nfssymlink;			}			nfs_printerror(err);			nfs_umountall(ARP_SERVER);			return 0;		}		if (err) {			printf("reading at offset %d: ", offs);			nfs_printerror(err);			nfs_umountall(ARP_SERVER);			return 0;		}		rpc = (struct rpc_t *)&nic.packet[ETH_HLEN];		/* size must be found out early to allow EOF detection */		if (size == -1) {			size = ntohl(rpc->u.reply.data[6]);		}		rlen = ntohl(rpc->u.reply.data[18]);		if (rlen > len) {			rlen = len;	/* shouldn't happen...  */		}		err = fnc((char *)&rpc->u.reply.data[19], block, rlen,			(offs+rlen == size));		if (err <= 0) {			nfs_umountall(ARP_SERVER);			return err;		}		block++;		offs += rlen;		/* last request is done with matching requested read size */		if (size-offs < NFS_READ_SIZE) {			len = size-offs;		}	} while (len != 0);	/* len == 0 means that all the file has been read */	return 1;}#endif	/* DOWNLOAD_PROTO_NFS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -