diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/link_local.c | 17 | ||||
| -rw-r--r-- | net/net.c | 3 | ||||
| -rw-r--r-- | net/nfs.c | 74 | ||||
| -rw-r--r-- | net/tftp.c | 12 | 
4 files changed, 74 insertions, 32 deletions
diff --git a/net/link_local.c b/net/link_local.c index 1ba796ebd..4152fae5b 100644 --- a/net/link_local.c +++ b/net/link_local.c @@ -206,6 +206,7 @@ void link_local_receive_arp(struct arp_hdr *arp, int len)  {  	int source_ip_conflict;  	int target_ip_conflict; +	IPaddr_t null_ip = 0;  	if (state == DISABLED)  		return; @@ -267,10 +268,18 @@ void link_local_receive_arp(struct arp_hdr *arp, int len)  	) {  		source_ip_conflict = 1;  	} -	if (arp->ar_op == htons(ARPOP_REQUEST) -	 && memcmp(&arp->ar_tpa, &ip, ARP_PLEN) == 0 -	 && memcmp(&arp->ar_tha, NetOurEther, ARP_HLEN) != 0 -	) { + +	/* +	 * According to RFC 3927, section 2.2.1: +	 * Check if packet is an ARP probe by checking for a null source IP +	 * then check that target IP is equal to ours and source hw addr +	 * is not equal to ours. This condition should cause a conflict only +	 * during probe. +	 */ +	if (arp->ar_op == htons(ARPOP_REQUEST) && +	    memcmp(&arp->ar_spa, &null_ip, ARP_PLEN) == 0 && +	    memcmp(&arp->ar_tpa, &ip, ARP_PLEN) == 0 && +	    memcmp(&arp->ar_sha, NetOurEther, ARP_HLEN) != 0) {  		target_ip_conflict = 1;  	} @@ -271,7 +271,8 @@ static void NetInitLoop(void)  #endif  		env_changed_id = env_id;  	} -	memcpy(NetOurEther, eth_get_dev()->enetaddr, 6); +	if (eth_get_dev()) +		memcpy(NetOurEther, eth_get_dev()->enetaddr, 6);  	return;  } @@ -37,10 +37,14 @@  # define NFS_TIMEOUT CONFIG_NFS_TIMEOUT  #endif +#define NFS_RPC_ERR	1 +#define NFS_RPC_DROP	124 +  static int fs_mounted;  static unsigned long rpc_id;  static int nfs_offset = -1;  static int nfs_len; +static ulong nfs_timeout = NFS_TIMEOUT;  static char dirfh[NFS_FHSIZE];	/* file handle of directory */  static char filefh[NFS_FHSIZE]; /* file handle of kernel image */ @@ -399,8 +403,10 @@ rpc_lookup_reply(int prog, uchar *pkt, unsigned len)  	debug("%s\n", __func__); -	if (ntohl(rpc_pkt.u.reply.id) != rpc_id) -		return -1; +	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;  	if (rpc_pkt.u.reply.rstatus  ||  	    rpc_pkt.u.reply.verifier || @@ -428,8 +434,10 @@ nfs_mount_reply(uchar *pkt, unsigned len)  	memcpy((unsigned char *)&rpc_pkt, pkt, len); -	if (ntohl(rpc_pkt.u.reply.id) != rpc_id) -		return -1; +	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;  	if (rpc_pkt.u.reply.rstatus  ||  	    rpc_pkt.u.reply.verifier || @@ -452,8 +460,10 @@ nfs_umountall_reply(uchar *pkt, unsigned len)  	memcpy((unsigned char *)&rpc_pkt, pkt, len); -	if (ntohl(rpc_pkt.u.reply.id) != rpc_id) -		return -1; +	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;  	if (rpc_pkt.u.reply.rstatus  ||  	    rpc_pkt.u.reply.verifier || @@ -475,8 +485,10 @@ nfs_lookup_reply(uchar *pkt, unsigned len)  	memcpy((unsigned char *)&rpc_pkt, pkt, len); -	if (ntohl(rpc_pkt.u.reply.id) != rpc_id) -		return -1; +	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;  	if (rpc_pkt.u.reply.rstatus  ||  	    rpc_pkt.u.reply.verifier || @@ -499,8 +511,10 @@ nfs_readlink_reply(uchar *pkt, unsigned len)  	memcpy((unsigned char *)&rpc_pkt, pkt, len); -	if (ntohl(rpc_pkt.u.reply.id) != rpc_id) -		return -1; +	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;  	if (rpc_pkt.u.reply.rstatus  ||  	    rpc_pkt.u.reply.verifier || @@ -534,8 +548,10 @@ nfs_read_reply(uchar *pkt, unsigned len)  	memcpy((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply)); -	if (ntohl(rpc_pkt.u.reply.id) != rpc_id) -		return -1; +	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;  	if (rpc_pkt.u.reply.rstatus  ||  	    rpc_pkt.u.reply.verifier || @@ -574,7 +590,8 @@ NfsTimeout(void)  		NetStartAgain();  	} else {  		puts("T "); -		NetSetTimeout(NFS_TIMEOUT, NfsTimeout); +		NetSetTimeout(nfs_timeout + NFS_TIMEOUT * NfsTimeoutCount, +			      NfsTimeout);  		NfsSend();  	}  } @@ -583,6 +600,7 @@ static void  NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)  {  	int rlen; +	int reply;  	debug("%s\n", __func__); @@ -591,19 +609,24 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)  	switch (NfsState) {  	case STATE_PRCLOOKUP_PROG_MOUNT_REQ: -		rpc_lookup_reply(PROG_MOUNT, pkt, len); +		if (rpc_lookup_reply(PROG_MOUNT, pkt, len) == -NFS_RPC_DROP) +			break;  		NfsState = STATE_PRCLOOKUP_PROG_NFS_REQ;  		NfsSend();  		break;  	case STATE_PRCLOOKUP_PROG_NFS_REQ: -		rpc_lookup_reply(PROG_NFS, pkt, len); +		if (rpc_lookup_reply(PROG_NFS, pkt, len) == -NFS_RPC_DROP) +			break;  		NfsState = STATE_MOUNT_REQ;  		NfsSend();  		break;  	case STATE_MOUNT_REQ: -		if (nfs_mount_reply(pkt, len)) { +		reply = nfs_mount_reply(pkt, len); +		if (reply == -NFS_RPC_DROP) +			break; +		else if (reply == -NFS_RPC_ERR) {  			puts("*** ERROR: Cannot mount\n");  			/* just to be sure... */  			NfsState = STATE_UMOUNT_REQ; @@ -615,7 +638,10 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)  		break;  	case STATE_UMOUNT_REQ: -		if (nfs_umountall_reply(pkt, len)) { +		reply = nfs_umountall_reply(pkt, len); +		if (reply == -NFS_RPC_DROP) +			break; +		else if (reply == -NFS_RPC_ERR) {  			puts("*** ERROR: Cannot umount\n");  			net_set_state(NETLOOP_FAIL);  		} else { @@ -625,7 +651,10 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)  		break;  	case STATE_LOOKUP_REQ: -		if (nfs_lookup_reply(pkt, len)) { +		reply = nfs_lookup_reply(pkt, len); +		if (reply == -NFS_RPC_DROP) +			break; +		else if (reply == -NFS_RPC_ERR) {  			puts("*** ERROR: File lookup fail\n");  			NfsState = STATE_UMOUNT_REQ;  			NfsSend(); @@ -638,7 +667,10 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)  		break;  	case STATE_READLINK_REQ: -		if (nfs_readlink_reply(pkt, len)) { +		reply = nfs_readlink_reply(pkt, len); +		if (reply == -NFS_RPC_DROP) +			break; +		else if (reply == -NFS_RPC_ERR) {  			puts("*** ERROR: Symlink fail\n");  			NfsState = STATE_UMOUNT_REQ;  			NfsSend(); @@ -654,7 +686,7 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)  	case STATE_READ_REQ:  		rlen = nfs_read_reply(pkt, len); -		NetSetTimeout(NFS_TIMEOUT, NfsTimeout); +		NetSetTimeout(nfs_timeout, NfsTimeout);  		if (rlen > 0) {  			nfs_offset += rlen;  			NfsSend(); @@ -738,7 +770,7 @@ NfsStart(void)  	printf("\nLoad address: 0x%lx\n"  		"Loading: *\b", load_addr); -	NetSetTimeout(NFS_TIMEOUT, NfsTimeout); +	NetSetTimeout(nfs_timeout, NfsTimeout);  	net_set_udp_handler(NfsHandler);  	NfsTimeoutCount = 0; diff --git a/net/tftp.c b/net/tftp.c index 09790eb7c..6d333d559 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -446,8 +446,8 @@ static void  TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,  	    unsigned len)  { -	ushort proto; -	ushort *s; +	__be16 proto; +	__be16 *s;  	int i;  	if (dest != TftpOurPort) { @@ -465,7 +465,7 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,  		return;  	len -= 2;  	/* warning: don't use increment (++) in ntohs() macros!! */ -	s = (ushort *)pkt; +	s = (__be16 *)pkt;  	proto = *s++;  	pkt = (uchar *)s;  	switch (ntohs(proto)) { @@ -556,7 +556,7 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,  		if (len < 2)  			return;  		len -= 2; -		TftpBlock = ntohs(*(ushort *)pkt); +		TftpBlock = ntohs(*(__be16 *)pkt);  		update_block_number(); @@ -644,9 +644,9 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,  	case TFTP_ERROR:  		printf("\nTFTP error: '%s' (%d)\n", -		       pkt + 2, ntohs(*(ushort *)pkt)); +		       pkt + 2, ntohs(*(__be16 *)pkt)); -		switch (ntohs(*(ushort *)pkt)) { +		switch (ntohs(*(__be16 *)pkt)) {  		case TFTP_ERR_FILE_NOT_FOUND:  		case TFTP_ERR_ACCESS_DENIED:  			puts("Not retrying...\n");  |