| 
				
			 | 
			
			
				
				@@ -1,5 +1,5 @@ 
			 | 
		
		
	
		
			
			| 
				1
			 | 
			
				
			 | 
			
			
				
				-#ifdef DOWNLOAD_PROTO_SLAM 
			 | 
		
		
	
		
			
			| 
				2
			 | 
			
				1
			 | 
			
			
				
				 #include "etherboot.h" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				2
			 | 
			
			
				
				+#include "proto.h" 
			 | 
		
		
	
		
			
			| 
				3
			 | 
			
				3
			 | 
			
			
				
				 #include "nic.h" 
			 | 
		
		
	
		
			
			| 
				4
			 | 
			
				4
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				5
			 | 
			
				5
			 | 
			
			
				
				 #define SLAM_PORT 10000 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -101,13 +101,12 @@ static void init_slam_state(void) 
			 | 
		
		
	
		
			
			| 
				101
			 | 
			
				101
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				102
			 | 
			
				102
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				103
			 | 
			
				103
			 | 
			
			
				
				 struct slam_info { 
			 | 
		
		
	
		
			
			| 
				104
			 | 
			
				
			 | 
			
			
				
				-	in_addr server_ip; 
			 | 
		
		
	
		
			
			| 
				105
			 | 
			
				
			 | 
			
			
				
				-	in_addr multicast_ip; 
			 | 
		
		
	
		
			
			| 
				106
			 | 
			
				
			 | 
			
			
				
				-	in_addr local_ip; 
			 | 
		
		
	
		
			
			| 
				107
			 | 
			
				
			 | 
			
			
				
				-	uint16_t server_port; 
			 | 
		
		
	
		
			
			| 
				108
			 | 
			
				
			 | 
			
			
				
				-	uint16_t multicast_port; 
			 | 
		
		
	
		
			
			| 
				109
			 | 
			
				
			 | 
			
			
				
				-	uint16_t local_port; 
			 | 
		
		
	
		
			
			| 
				110
			 | 
			
				
			 | 
			
			
				
				-	int (*fnc)(unsigned char *, unsigned int, unsigned int, int); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				104
			 | 
			
			
				
				+	struct sockaddr_in server; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				105
			 | 
			
			
				
				+	struct sockaddr_in local; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				106
			 | 
			
			
				
				+	struct sockaddr_in multicast; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				107
			 | 
			
			
				
				+	int ( * process ) ( unsigned char *data, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				108
			 | 
			
			
				
				+			    unsigned int blocknum, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				109
			 | 
			
			
				
				+			    unsigned int len, int eof ); 
			 | 
		
		
	
		
			
			| 
				111
			 | 
			
				110
			 | 
			
			
				
				 	int sent_nack; 
			 | 
		
		
	
		
			
			| 
				112
			 | 
			
				111
			 | 
			
			
				
				 }; 
			 | 
		
		
	
		
			
			| 
				113
			 | 
			
				112
			 | 
			
			
				
				  
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -115,7 +114,8 @@ struct slam_info { 
			 | 
		
		
	
		
			
			| 
				115
			 | 
			
				114
			 | 
			
			
				
				 #define SLAM_REQUEST 1 
			 | 
		
		
	
		
			
			| 
				116
			 | 
			
				115
			 | 
			
			
				
				 #define SLAM_DATA    2 
			 | 
		
		
	
		
			
			| 
				117
			 | 
			
				116
			 | 
			
			
				
				 static int await_slam(int ival __unused, void *ptr, 
			 | 
		
		
	
		
			
			| 
				118
			 | 
			
				
			 | 
			
			
				
				-	unsigned short ptype __unused, struct iphdr *ip, struct udphdr *udp) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				117
			 | 
			
			
				
				+		      unsigned short ptype __unused, struct iphdr *ip, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				118
			 | 
			
			
				
				+		      struct udphdr *udp, struct tcphdr *tcp __unused) 
			 | 
		
		
	
		
			
			| 
				119
			 | 
			
				119
			 | 
			
			
				
				 { 
			 | 
		
		
	
		
			
			| 
				120
			 | 
			
				120
			 | 
			
			
				
				 	struct slam_info *info = ptr; 
			 | 
		
		
	
		
			
			| 
				121
			 | 
			
				121
			 | 
			
			
				
				 	if (!udp) { 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -126,7 +126,7 @@ static int await_slam(int ival __unused, void *ptr, 
			 | 
		
		
	
		
			
			| 
				126
			 | 
			
				126
			 | 
			
			
				
				 	 */ 
			 | 
		
		
	
		
			
			| 
				127
			 | 
			
				127
			 | 
			
			
				
				 	/* Check for a data request packet */ 
			 | 
		
		
	
		
			
			| 
				128
			 | 
			
				128
			 | 
			
			
				
				 	if ((ip->dest.s_addr == arptable[ARP_CLIENT].ipaddr.s_addr) && 
			 | 
		
		
	
		
			
			| 
				129
			 | 
			
				
			 | 
			
			
				
				-		(ntohs(udp->dest) == info->local_port) &&  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				129
			 | 
			
			
				
				+		(ntohs(udp->dest) == info->local.sin_port) &&  
			 | 
		
		
	
		
			
			| 
				130
			 | 
			
				130
			 | 
			
			
				
				 		(nic.packetlen >=  
			 | 
		
		
	
		
			
			| 
				131
			 | 
			
				131
			 | 
			
			
				
				 			ETH_HLEN +  
			 | 
		
		
	
		
			
			| 
				132
			 | 
			
				132
			 | 
			
			
				
				 			sizeof(struct iphdr) +  
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -135,8 +135,8 @@ static int await_slam(int ival __unused, void *ptr, 
			 | 
		
		
	
		
			
			| 
				135
			 | 
			
				135
			 | 
			
			
				
				 		return SLAM_REQUEST; 
			 | 
		
		
	
		
			
			| 
				136
			 | 
			
				136
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				137
			 | 
			
				137
			 | 
			
			
				
				 	/* Check for a multicast data packet */ 
			 | 
		
		
	
		
			
			| 
				138
			 | 
			
				
			 | 
			
			
				
				-	if ((ip->dest.s_addr == info->multicast_ip.s_addr) && 
			 | 
		
		
	
		
			
			| 
				139
			 | 
			
				
			 | 
			
			
				
				-		(ntohs(udp->dest) == info->multicast_port) && 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				138
			 | 
			
			
				
				+	if ((ip->dest.s_addr == info->multicast.sin_addr.s_addr) && 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				139
			 | 
			
			
				
				+		(ntohs(udp->dest) == info->multicast.sin_port) && 
			 | 
		
		
	
		
			
			| 
				140
			 | 
			
				140
			 | 
			
			
				
				 		(nic.packetlen >=  
			 | 
		
		
	
		
			
			| 
				141
			 | 
			
				141
			 | 
			
			
				
				 			ETH_HLEN +  
			 | 
		
		
	
		
			
			| 
				142
			 | 
			
				142
			 | 
			
			
				
				 			sizeof(struct iphdr) +  
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -203,7 +203,8 @@ static int slam_skip(unsigned char **ptr, unsigned char *end) 
			 | 
		
		
	
		
			
			| 
				203
			 | 
			
				203
			 | 
			
			
				
				 	 
			 | 
		
		
	
		
			
			| 
				204
			 | 
			
				204
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				205
			 | 
			
				205
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				206
			 | 
			
				
			 | 
			
			
				
				-static unsigned long slam_decode(unsigned char **ptr, unsigned char *end, int *err) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				206
			 | 
			
			
				
				+static unsigned long slam_decode(unsigned char **ptr, unsigned char *end, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				207
			 | 
			
			
				
				+				 int *err) 
			 | 
		
		
	
		
			
			| 
				207
			 | 
			
				208
			 | 
			
			
				
				 { 
			 | 
		
		
	
		
			
			| 
				208
			 | 
			
				209
			 | 
			
			
				
				 	unsigned long value; 
			 | 
		
		
	
		
			
			| 
				209
			 | 
			
				210
			 | 
			
			
				
				 	unsigned bytes; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -368,8 +369,8 @@ static void transmit_nack(unsigned char *ptr, struct slam_info *info) 
			 | 
		
		
	
		
			
			| 
				368
			 | 
			
				369
			 | 
			
			
				
				 	/* Ensure the packet is null terminated */ 
			 | 
		
		
	
		
			
			| 
				369
			 | 
			
				370
			 | 
			
			
				
				 	*ptr++ = 0; 
			 | 
		
		
	
		
			
			| 
				370
			 | 
			
				371
			 | 
			
			
				
				 	nack_len = ptr - (unsigned char *)&nack; 
			 | 
		
		
	
		
			
			| 
				371
			 | 
			
				
			 | 
			
			
				
				-	build_udp_hdr(info->server_ip.s_addr,  
			 | 
		
		
	
		
			
			| 
				372
			 | 
			
				
			 | 
			
			
				
				-		info->local_port, info->server_port, 1, nack_len, &nack); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				372
			 | 
			
			
				
				+	build_udp_hdr(info->server.sin_addr.s_addr, info->local.sin_port, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				373
			 | 
			
			
				
				+		      info->server.sin_port, 1, nack_len, &nack); 
			 | 
		
		
	
		
			
			| 
				373
			 | 
			
				374
			 | 
			
			
				
				 	ip_transmit(nack_len, &nack); 
			 | 
		
		
	
		
			
			| 
				374
			 | 
			
				375
			 | 
			
			
				
				 #if defined(MDEBUG) && 0 
			 | 
		
		
	
		
			
			| 
				375
			 | 
			
				376
			 | 
			
			
				
				 	printf("Sent NACK to %@ bytes: %d have:%ld/%ld\n",  
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -443,12 +444,12 @@ static int proto_slam(struct slam_info *info) 
			 | 
		
		
	
		
			
			| 
				443
			 | 
			
				444
			 | 
			
			
				
				 	retry = -1; 
			 | 
		
		
	
		
			
			| 
				444
			 | 
			
				445
			 | 
			
			
				
				 	rx_qdrain(); 
			 | 
		
		
	
		
			
			| 
				445
			 | 
			
				446
			 | 
			
			
				
				 	/* Arp for my server */ 
			 | 
		
		
	
		
			
			| 
				446
			 | 
			
				
			 | 
			
			
				
				-	if (arptable[ARP_SERVER].ipaddr.s_addr != info->server_ip.s_addr) { 
			 | 
		
		
	
		
			
			| 
				447
			 | 
			
				
			 | 
			
			
				
				-		arptable[ARP_SERVER].ipaddr.s_addr = info->server_ip.s_addr; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				447
			 | 
			
			
				
				+	if (arptable[ARP_SERVER].ipaddr.s_addr != info->server.sin_addr.s_addr) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				448
			 | 
			
			
				
				+		arptable[ARP_SERVER].ipaddr.s_addr = info->server.sin_addr.s_addr; 
			 | 
		
		
	
		
			
			| 
				448
			 | 
			
				449
			 | 
			
			
				
				 		memset(arptable[ARP_SERVER].node, 0, ETH_ALEN); 
			 | 
		
		
	
		
			
			| 
				449
			 | 
			
				450
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				450
			 | 
			
				451
			 | 
			
			
				
				 	/* If I'm running over multicast join the multicast group */ 
			 | 
		
		
	
		
			
			| 
				451
			 | 
			
				
			 | 
			
			
				
				-	join_group(IGMP_SERVER, info->multicast_ip.s_addr); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				452
			 | 
			
			
				
				+	join_group(IGMP_SERVER, info->multicast.sin_addr.s_addr); 
			 | 
		
		
	
		
			
			| 
				452
			 | 
			
				453
			 | 
			
			
				
				 	for(;;) { 
			 | 
		
		
	
		
			
			| 
				453
			 | 
			
				454
			 | 
			
			
				
				 		unsigned char *header; 
			 | 
		
		
	
		
			
			| 
				454
			 | 
			
				455
			 | 
			
			
				
				 		unsigned char *data; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -503,39 +504,33 @@ static int proto_slam(struct slam_info *info) 
			 | 
		
		
	
		
			
			| 
				503
			 | 
			
				504
			 | 
			
			
				
				 	leave_group(IGMP_SERVER); 
			 | 
		
		
	
		
			
			| 
				504
			 | 
			
				505
			 | 
			
			
				
				 	/* FIXME don't overwrite myself */ 
			 | 
		
		
	
		
			
			| 
				505
			 | 
			
				506
			 | 
			
			
				
				 	/* load file to correct location */ 
			 | 
		
		
	
		
			
			| 
				506
			 | 
			
				
			 | 
			
			
				
				-	return info->fnc(state.image, 1, state.total_bytes, 1); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				507
			 | 
			
			
				
				+	return info->process(state.image, 1, state.total_bytes, 1); 
			 | 
		
		
	
		
			
			| 
				507
			 | 
			
				508
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				508
			 | 
			
				509
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				509
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				510
			 | 
			
				
			 | 
			
			
				
				-int url_slam(const char *name, int (*fnc)(unsigned char *, unsigned int, unsigned int, int)) 
			 | 
		
		
	
		
			
			| 
				511
			 | 
			
				
			 | 
			
			
				
				-{ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				510
			 | 
			
			
				
				+static int url_slam ( char *url __unused, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				511
			 | 
			
			
				
				+		      struct sockaddr_in *server, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				512
			 | 
			
			
				
				+		      char *file, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				513
			 | 
			
			
				
				+		      int ( * process ) ( unsigned char *data, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				514
			 | 
			
			
				
				+					  unsigned int blocknum, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				515
			 | 
			
			
				
				+					  unsigned int len, int eof ) ) { 
			 | 
		
		
	
		
			
			| 
				512
			 | 
			
				516
			 | 
			
			
				
				 	struct slam_info info; 
			 | 
		
		
	
		
			
			| 
				513
			 | 
			
				517
			 | 
			
			
				
				 	/* Set the defaults */ 
			 | 
		
		
	
		
			
			| 
				514
			 | 
			
				
			 | 
			
			
				
				-	info.server_ip.s_addr    = arptable[ARP_SERVER].ipaddr.s_addr; 
			 | 
		
		
	
		
			
			| 
				515
			 | 
			
				
			 | 
			
			
				
				-	info.server_port         = SLAM_PORT; 
			 | 
		
		
	
		
			
			| 
				516
			 | 
			
				
			 | 
			
			
				
				-	info.multicast_ip.s_addr = htonl(SLAM_MULTICAST_IP); 
			 | 
		
		
	
		
			
			| 
				517
			 | 
			
				
			 | 
			
			
				
				-	info.multicast_port      = SLAM_MULTICAST_PORT; 
			 | 
		
		
	
		
			
			| 
				518
			 | 
			
				
			 | 
			
			
				
				-	info.local_ip.s_addr     = arptable[ARP_CLIENT].ipaddr.s_addr; 
			 | 
		
		
	
		
			
			| 
				519
			 | 
			
				
			 | 
			
			
				
				-	info.local_port          = SLAM_LOCAL_PORT; 
			 | 
		
		
	
		
			
			| 
				520
			 | 
			
				
			 | 
			
			
				
				-	info.fnc                 = fnc; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				518
			 | 
			
			
				
				+	info.server = *server; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				519
			 | 
			
			
				
				+	if ( ! info.server.sin_port ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				520
			 | 
			
			
				
				+		info.server.sin_port = SLAM_PORT; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				521
			 | 
			
			
				
				+	info.multicast.sin_addr.s_addr = htonl(SLAM_MULTICAST_IP); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				522
			 | 
			
			
				
				+	info.multicast.sin_port      = SLAM_MULTICAST_PORT; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				523
			 | 
			
			
				
				+	info.local.sin_addr.s_addr   = arptable[ARP_CLIENT].ipaddr.s_addr; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				524
			 | 
			
			
				
				+	info.local.sin_port          = SLAM_LOCAL_PORT; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				525
			 | 
			
			
				
				+	info.process                 = process; 
			 | 
		
		
	
		
			
			| 
				521
			 | 
			
				526
			 | 
			
			
				
				 	info.sent_nack = 0; 
			 | 
		
		
	
		
			
			| 
				522
			 | 
			
				
			 | 
			
			
				
				-	/* Now parse the url */ 
			 | 
		
		
	
		
			
			| 
				523
			 | 
			
				
			 | 
			
			
				
				-	if (url_port != -1) { 
			 | 
		
		
	
		
			
			| 
				524
			 | 
			
				
			 | 
			
			
				
				-		info.server_port = url_port; 
			 | 
		
		
	
		
			
			| 
				525
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				526
			 | 
			
				
			 | 
			
			
				
				-	if (name[0]) { 
			 | 
		
		
	
		
			
			| 
				527
			 | 
			
				
			 | 
			
			
				
				-		/* multicast ip */ 
			 | 
		
		
	
		
			
			| 
				528
			 | 
			
				
			 | 
			
			
				
				-		name += inet_aton(name, &info.multicast_ip); 
			 | 
		
		
	
		
			
			| 
				529
			 | 
			
				
			 | 
			
			
				
				-		if (name[0] == ':') { 
			 | 
		
		
	
		
			
			| 
				530
			 | 
			
				
			 | 
			
			
				
				-			name++; 
			 | 
		
		
	
		
			
			| 
				531
			 | 
			
				
			 | 
			
			
				
				-			info.multicast_port = strtoul(name, &name, 10); 
			 | 
		
		
	
		
			
			| 
				532
			 | 
			
				
			 | 
			
			
				
				-		} 
			 | 
		
		
	
		
			
			| 
				533
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				534
			 | 
			
				
			 | 
			
			
				
				-	if (name[0]) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				527
			 | 
			
			
				
				+	if (file[0]) { 
			 | 
		
		
	
		
			
			| 
				535
			 | 
			
				528
			 | 
			
			
				
				 		printf("\nBad url\n"); 
			 | 
		
		
	
		
			
			| 
				536
			 | 
			
				529
			 | 
			
			
				
				 		return 0; 
			 | 
		
		
	
		
			
			| 
				537
			 | 
			
				530
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				538
			 | 
			
				531
			 | 
			
			
				
				 	return proto_slam(&info); 
			 | 
		
		
	
		
			
			| 
				539
			 | 
			
				532
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				540
			 | 
			
				533
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				541
			 | 
			
				
			 | 
			
			
				
				-#endif /* DOWNLOAD_PROTO_SLAM */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				534
			 | 
			
			
				
				+static struct protocol slam_protocol __protocol = { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				535
			 | 
			
			
				
				+	"slam", url_slam 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				536
			 | 
			
			
				
				+}; 
			 |