📄 nfs.c
字号:
static intrpc_lookup_reply (int prog, uchar *pkt, unsigned len){ struct rpc_t rpc_pkt; memcpy ((unsigned char *)&rpc_pkt, pkt, len);#ifdef NFS_DEBUG printf ("%s\n", __FUNCTION__);#endif if (ntohl(rpc_pkt.u.reply.id) != rpc_id) return -1; if (rpc_pkt.u.reply.rstatus || rpc_pkt.u.reply.verifier || rpc_pkt.u.reply.astatus || rpc_pkt.u.reply.astatus) { return -1; } switch (prog) { case PROG_MOUNT: NfsSrvMountPort = ntohl(rpc_pkt.u.reply.data[0]); break; case PROG_NFS: NfsSrvNfsPort = ntohl(rpc_pkt.u.reply.data[0]); break; } return 0;}static intnfs_mount_reply (uchar *pkt, unsigned len){ struct rpc_t rpc_pkt;#ifdef NFS_DEBUG printf ("%s\n", __FUNCTION__);#endif memcpy ((unsigned char *)&rpc_pkt, pkt, len); if (ntohl(rpc_pkt.u.reply.id) != rpc_id) return -1; if (rpc_pkt.u.reply.rstatus || rpc_pkt.u.reply.verifier || rpc_pkt.u.reply.astatus || rpc_pkt.u.reply.data[0]) { return -1; } fs_mounted = 1; memcpy (dirfh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE); return 0;}static intnfs_umountall_reply (uchar *pkt, unsigned len){ struct rpc_t rpc_pkt;#ifdef NFS_DEBUG printf ("%s\n", __FUNCTION__);#endif memcpy ((unsigned char *)&rpc_pkt, pkt, len); if (ntohl(rpc_pkt.u.reply.id) != rpc_id) return -1; if (rpc_pkt.u.reply.rstatus || rpc_pkt.u.reply.verifier || rpc_pkt.u.reply.astatus) { return -1; } fs_mounted = 0; memset (dirfh, 0, sizeof(dirfh)); return 0;}static intnfs_lookup_reply (uchar *pkt, unsigned len){ struct rpc_t rpc_pkt;#ifdef NFS_DEBUG printf ("%s\n", __FUNCTION__);#endif memcpy ((unsigned char *)&rpc_pkt, pkt, len); if (ntohl(rpc_pkt.u.reply.id) != rpc_id) return -1; if (rpc_pkt.u.reply.rstatus || rpc_pkt.u.reply.verifier || rpc_pkt.u.reply.astatus || rpc_pkt.u.reply.data[0]) { return -1; } memcpy (filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE); return 0;}static intnfs_readlink_reply (uchar *pkt, unsigned len){ struct rpc_t rpc_pkt; int rlen;#ifdef NFS_DEBUG printf ("%s\n", __FUNCTION__);#endif memcpy ((unsigned char *)&rpc_pkt, pkt, len); if (ntohl(rpc_pkt.u.reply.id) != rpc_id) return -1; if (rpc_pkt.u.reply.rstatus || rpc_pkt.u.reply.verifier || rpc_pkt.u.reply.astatus || rpc_pkt.u.reply.data[0]) { return -1; } rlen = ntohl (rpc_pkt.u.reply.data[1]); /* new path length */ if (*((char *)&(rpc_pkt.u.reply.data[2])) != '/') { int pathlen; strcat (nfs_path, "/"); pathlen = strlen(nfs_path); memcpy (nfs_path+pathlen, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen); nfs_path[pathlen+rlen+1] = 0; } else { memcpy (nfs_path, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen); nfs_path[rlen] = 0; } return 0;}static intnfs_read_reply (uchar *pkt, unsigned len){ struct rpc_t rpc_pkt; int rlen;#ifdef NFS_DEBUG_nop printf ("%s\n", __FUNCTION__);#endif memcpy ((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply)); if (ntohl(rpc_pkt.u.reply.id) != rpc_id) return -1; if (rpc_pkt.u.reply.rstatus || rpc_pkt.u.reply.verifier || rpc_pkt.u.reply.astatus || rpc_pkt.u.reply.data[0]) { if (rpc_pkt.u.reply.rstatus) { return -9999; } if (rpc_pkt.u.reply.astatus) { return -9999; } return -ntohl(rpc_pkt.u.reply.data[0]);; } if ((nfs_offset!=0) && !((nfs_offset) % (NFS_READ_SIZE/2*10*HASHES_PER_LINE))) { puts ("\n\t "); } if (!(nfs_offset % ((NFS_READ_SIZE/2)*10))) { putc ('#'); } rlen = ntohl(rpc_pkt.u.reply.data[18]); if ( store_block ((uchar *)pkt+sizeof(rpc_pkt.u.reply), nfs_offset, rlen) ) return -9999; return rlen;}/**************************************************************************Interfaces of U-BOOT**************************************************************************/static voidNfsTimeout (void){ puts ("Timeout\n"); NetState = NETLOOP_FAIL; return;}static voidNfsHandler (uchar *pkt, unsigned dest, unsigned src, unsigned len){ int rlen;#ifdef NFS_DEBUG printf ("%s\n", __FUNCTION__);#endif if (dest != NfsOurPort) return; switch (NfsState) { case STATE_PRCLOOKUP_PROG_MOUNT_REQ: rpc_lookup_reply (PROG_MOUNT, pkt, len); NfsState = STATE_PRCLOOKUP_PROG_NFS_REQ; NfsSend (); break; case STATE_PRCLOOKUP_PROG_NFS_REQ: rpc_lookup_reply (PROG_NFS, pkt, len); NfsState = STATE_MOUNT_REQ; NfsSend (); break; case STATE_MOUNT_REQ: if (nfs_mount_reply(pkt, len)) { puts ("*** ERROR: Cannot mount\n"); /* just to be sure... */ NfsState = STATE_UMOUNT_REQ; NfsSend (); } else { NfsState = STATE_LOOKUP_REQ; NfsSend (); } break; case STATE_UMOUNT_REQ: if (nfs_umountall_reply(pkt, len)) { puts ("*** ERROR: Cannot umount\n"); NetState = NETLOOP_FAIL; } else { puts ("\ndone\n"); NetState = NfsDownloadState; } break; case STATE_LOOKUP_REQ: if (nfs_lookup_reply(pkt, len)) { puts ("*** ERROR: File lookup fail\n"); NfsState = STATE_UMOUNT_REQ; NfsSend (); } else { NfsState = STATE_READ_REQ; nfs_offset = 0; nfs_len = NFS_READ_SIZE; NfsSend (); } break; case STATE_READLINK_REQ: if (nfs_readlink_reply(pkt, len)) { puts ("*** ERROR: Symlink fail\n"); NfsState = STATE_UMOUNT_REQ; NfsSend (); } else {#ifdef NFS_DEBUG printf ("Symlink --> %s\n", nfs_path);#endif nfs_filename = basename (nfs_path); nfs_path = dirname (nfs_path); NfsState = STATE_MOUNT_REQ; NfsSend (); } break; case STATE_READ_REQ: rlen = nfs_read_reply (pkt, len); NetSetTimeout (NFS_TIMEOUT * CFG_HZ, NfsTimeout); if (rlen > 0) { nfs_offset += rlen; NfsSend (); } else if ((rlen == -NFSERR_ISDIR)||(rlen == -NFSERR_INVAL)) { /* symbolic link */ NfsState = STATE_READLINK_REQ; NfsSend (); } else { if ( ! rlen ) NfsDownloadState = NETLOOP_SUCCESS; NfsState = STATE_UMOUNT_REQ; NfsSend (); } break; }}voidNfsStart (void){#ifdef NFS_DEBUG printf ("%s\n", __FUNCTION__);#endif NfsDownloadState = NETLOOP_FAIL; NfsServerIP = NetServerIP; nfs_path = (char *)nfs_path_buff; if (nfs_path == NULL) { NetState = NETLOOP_FAIL; puts ("*** ERROR: Fail allocate memory\n"); return; } if (BootFile[0] == '\0') { sprintf (default_filename, "/nfsroot/%02lX%02lX%02lX%02lX.img", NetOurIP & 0xFF, (NetOurIP >> 8) & 0xFF, (NetOurIP >> 16) & 0xFF, (NetOurIP >> 24) & 0xFF ); strcpy (nfs_path, default_filename); printf ("*** Warning: no boot file name; using '%s'\n", nfs_path); } else { char *p=BootFile; p = strchr (p, ':'); if (p != NULL) { NfsServerIP = string_to_ip (BootFile); ++p; strcpy (nfs_path, p); } else { strcpy (nfs_path, BootFile); } } nfs_filename = basename (nfs_path); nfs_path = dirname (nfs_path);#if defined(CONFIG_NET_MULTI) printf ("Using %s device\n", eth_get_name());#endif puts ("File transfer via NFS from server "); print_IPaddr (NfsServerIP); puts ("; our IP address is "); print_IPaddr (NetOurIP); /* Check if we need to send across this subnet */ if (NetOurGatewayIP && NetOurSubnetMask) { IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; IPaddr_t ServerNet = NetServerIP & NetOurSubnetMask; if (OurNet != ServerNet) { puts ("; sending through gateway "); print_IPaddr (NetOurGatewayIP) ; } } printf ("\nFilename '%s/%s'.", nfs_path, nfs_filename); if (NetBootFileSize) { printf (" Size is 0x%x Bytes = ", NetBootFileSize<<9); print_size (NetBootFileSize<<9, ""); } printf ("\nLoad address: 0x%lx\n" "Loading: *\b", load_addr); NetSetTimeout (NFS_TIMEOUT * CFG_HZ, NfsTimeout); NetSetHandler (NfsHandler); NfsTimeoutCount = 0; NfsState = STATE_PRCLOOKUP_PROG_MOUNT_REQ; /*NfsOurPort = 4096 + (get_ticks() % 3072);*/ /*FIX ME !!!*/ NfsOurPort = 1000; /* zero out server ether in case the server ip has changed */ memset (NetServerEther, 0, 6); NfsSend ();}#endif /* CONFIG_COMMANDS & CFG_CMD_NFS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -