| 
				
			 | 
			
			
				
				@@ -101,16 +101,29 @@ void del_ipv4_address ( struct net_device *netdev ) { 
			 | 
		
		
	
		
			
			| 
				101
			 | 
			
				101
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				102
			 | 
			
				102
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				103
			 | 
			
				103
			 | 
			
			
				
				 /** 
			 | 
		
		
	
		
			
			| 
				104
			 | 
			
				
			 | 
			
			
				
				- * Dump IPv4 packet header 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				104
			 | 
			
			
				
				+ * Perform IPv4 routing 
			 | 
		
		
	
		
			
			| 
				105
			 | 
			
				105
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				106
			 | 
			
				
			 | 
			
			
				
				- * @v iphdr	IPv4 header 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				106
			 | 
			
			
				
				+ * @v dest		Final destination address 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				107
			 | 
			
			
				
				+ * @ret dest		Next hop destination address 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				108
			 | 
			
			
				
				+ * @ret miniroute	Routing table entry to use, or NULL if no route 
			 | 
		
		
	
		
			
			| 
				107
			 | 
			
				109
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				108
			 | 
			
				
			 | 
			
			
				
				-static void ipv4_dump ( struct iphdr *iphdr __unused ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				110
			 | 
			
			
				
				+static struct ipv4_miniroute * ipv4_route ( struct in_addr *dest ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				111
			 | 
			
			
				
				+	struct ipv4_miniroute *miniroute; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				112
			 | 
			
			
				
				+	int local; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				113
			 | 
			
			
				
				+	int has_gw; 
			 | 
		
		
	
		
			
			| 
				109
			 | 
			
				114
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				110
			 | 
			
				
			 | 
			
			
				
				-	DBG ( "IP4 %p transmitting %p+%d ident %d protocol %d header-csum %x\n", 
			 | 
		
		
	
		
			
			| 
				111
			 | 
			
				
			 | 
			
			
				
				-		&ipv4_protocol, iphdr, ntohs ( iphdr->len ), ntohs ( iphdr->ident ), 
			 | 
		
		
	
		
			
			| 
				112
			 | 
			
				
			 | 
			
			
				
				-		iphdr->protocol, ntohs ( iphdr->chksum ) ); 
			 | 
		
		
	
		
			
			| 
				113
			 | 
			
				
			 | 
			
			
				
				-	DBG ( "src %s, dest %s\n", inet_ntoa ( iphdr->src ), inet_ntoa ( iphdr->dest ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				115
			 | 
			
			
				
				+	list_for_each_entry ( miniroute, &miniroutes, list ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				116
			 | 
			
			
				
				+		local = ( ( ( dest->s_addr ^ miniroute->address.s_addr ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				117
			 | 
			
			
				
				+			    & miniroute->netmask.s_addr ) == 0 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				118
			 | 
			
			
				
				+		has_gw = ( miniroute->gateway.s_addr != INADDR_NONE ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				119
			 | 
			
			
				
				+		if ( local || has_gw ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				120
			 | 
			
			
				
				+			if ( ! local ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				121
			 | 
			
			
				
				+				*dest = miniroute->gateway; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				122
			 | 
			
			
				
				+			return miniroute; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				123
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				124
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				125
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				126
			 | 
			
			
				
				+	return NULL; 
			 | 
		
		
	
		
			
			| 
				114
			 | 
			
				127
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				115
			 | 
			
				128
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				116
			 | 
			
				129
			 | 
			
			
				
				 /** 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -280,59 +293,39 @@ static int ipv4_tx ( struct pk_buff *pkb, 
			 | 
		
		
	
		
			
			| 
				280
			 | 
			
				293
			 | 
			
			
				
				 	int rc; 
			 | 
		
		
	
		
			
			| 
				281
			 | 
			
				294
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				282
			 | 
			
				295
			 | 
			
			
				
				 	/* Fill up the IP header, except source address */ 
			 | 
		
		
	
		
			
			| 
				283
			 | 
			
				
			 | 
			
			
				
				-	iphdr->verhdrlen = ( IP_VER << 4 ) | ( sizeof ( *iphdr ) / 4 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				296
			 | 
			
			
				
				+	iphdr->verhdrlen = ( ( IP_VER << 4 ) | ( sizeof ( *iphdr ) / 4 ) ); 
			 | 
		
		
	
		
			
			| 
				284
			 | 
			
				297
			 | 
			
			
				
				 	iphdr->service = IP_TOS; 
			 | 
		
		
	
		
			
			| 
				285
			 | 
			
				298
			 | 
			
			
				
				 	iphdr->len = htons ( pkb_len ( pkb ) );	 
			 | 
		
		
	
		
			
			| 
				286
			 | 
			
				
			 | 
			
			
				
				-	iphdr->ident = htons ( next_ident++ ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				299
			 | 
			
			
				
				+	iphdr->ident = htons ( ++next_ident ); 
			 | 
		
		
	
		
			
			| 
				287
			 | 
			
				300
			 | 
			
			
				
				 	iphdr->frags = 0; 
			 | 
		
		
	
		
			
			| 
				288
			 | 
			
				301
			 | 
			
			
				
				 	iphdr->ttl = IP_TTL; 
			 | 
		
		
	
		
			
			| 
				289
			 | 
			
				302
			 | 
			
			
				
				 	iphdr->protocol = tcpip_protocol->tcpip_proto; 
			 | 
		
		
	
		
			
			| 
				290
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				291
			 | 
			
				
			 | 
			
			
				
				-	/* Copy destination address */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				303
			 | 
			
			
				
				+	iphdr->chksum = 0; 
			 | 
		
		
	
		
			
			| 
				292
			 | 
			
				304
			 | 
			
			
				
				 	iphdr->dest = sin_dest->sin_addr; 
			 | 
		
		
	
		
			
			| 
				293
			 | 
			
				305
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				294
			 | 
			
				
			 | 
			
			
				
				-	/** 
			 | 
		
		
	
		
			
			| 
				295
			 | 
			
				
			 | 
			
			
				
				-	 * All fields in the IP header filled in except the source network 
			 | 
		
		
	
		
			
			| 
				296
			 | 
			
				
			 | 
			
			
				
				-	 * address (which requires routing) and the header checksum (which 
			 | 
		
		
	
		
			
			| 
				297
			 | 
			
				
			 | 
			
			
				
				-	 * requires the source network address). As the pseudo header requires 
			 | 
		
		
	
		
			
			| 
				298
			 | 
			
				
			 | 
			
			
				
				-	 * the source address as well and the transport-layer checksum is 
			 | 
		
		
	
		
			
			| 
				299
			 | 
			
				
			 | 
			
			
				
				-	 * updated after routing. 
			 | 
		
		
	
		
			
			| 
				300
			 | 
			
				
			 | 
			
			
				
				-	 */ 
			 | 
		
		
	
		
			
			| 
				301
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				302
			 | 
			
				306
			 | 
			
			
				
				 	/* Use routing table to identify next hop and transmitting netdev */ 
			 | 
		
		
	
		
			
			| 
				303
			 | 
			
				307
			 | 
			
			
				
				 	next_hop = iphdr->dest; 
			 | 
		
		
	
		
			
			| 
				304
			 | 
			
				
			 | 
			
			
				
				-	list_for_each_entry ( miniroute, &miniroutes, list ) { 
			 | 
		
		
	
		
			
			| 
				305
			 | 
			
				
			 | 
			
			
				
				-		int local, has_gw; 
			 | 
		
		
	
		
			
			| 
				306
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				307
			 | 
			
				
			 | 
			
			
				
				-		local = ( ( ( iphdr->dest.s_addr ^ miniroute->address.s_addr ) 
			 | 
		
		
	
		
			
			| 
				308
			 | 
			
				
			 | 
			
			
				
				-			    & miniroute->netmask.s_addr ) == 0 ); 
			 | 
		
		
	
		
			
			| 
				309
			 | 
			
				
			 | 
			
			
				
				-		has_gw = ( miniroute->gateway.s_addr != INADDR_NONE ); 
			 | 
		
		
	
		
			
			| 
				310
			 | 
			
				
			 | 
			
			
				
				-		if ( local || has_gw ) { 
			 | 
		
		
	
		
			
			| 
				311
			 | 
			
				
			 | 
			
			
				
				-			netdev = miniroute->netdev; 
			 | 
		
		
	
		
			
			| 
				312
			 | 
			
				
			 | 
			
			
				
				-			iphdr->src = miniroute->address; 
			 | 
		
		
	
		
			
			| 
				313
			 | 
			
				
			 | 
			
			
				
				-			if ( ! local ) 
			 | 
		
		
	
		
			
			| 
				314
			 | 
			
				
			 | 
			
			
				
				-				next_hop = miniroute->gateway; 
			 | 
		
		
	
		
			
			| 
				315
			 | 
			
				
			 | 
			
			
				
				-			break; 
			 | 
		
		
	
		
			
			| 
				316
			 | 
			
				
			 | 
			
			
				
				-		} 
			 | 
		
		
	
		
			
			| 
				317
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				318
			 | 
			
				
			 | 
			
			
				
				-	/* Abort if no network device identified */ 
			 | 
		
		
	
		
			
			| 
				319
			 | 
			
				
			 | 
			
			
				
				-	if ( ! netdev ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				308
			 | 
			
			
				
				+	miniroute = ipv4_route ( &next_hop ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				309
			 | 
			
			
				
				+	if ( ! miniroute ) { 
			 | 
		
		
	
		
			
			| 
				320
			 | 
			
				310
			 | 
			
			
				
				 		DBG ( "No route to %s\n", inet_ntoa ( iphdr->dest ) ); 
			 | 
		
		
	
		
			
			| 
				321
			 | 
			
				311
			 | 
			
			
				
				 		rc = -EHOSTUNREACH; 
			 | 
		
		
	
		
			
			| 
				322
			 | 
			
				312
			 | 
			
			
				
				 		goto err; 
			 | 
		
		
	
		
			
			| 
				323
			 | 
			
				313
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				314
			 | 
			
			
				
				+	iphdr->src = miniroute->address; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				315
			 | 
			
			
				
				+	netdev = miniroute->netdev; 
			 | 
		
		
	
		
			
			| 
				324
			 | 
			
				316
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				325
			 | 
			
				317
			 | 
			
			
				
				 	/* Calculate the transport layer checksum */ 
			 | 
		
		
	
		
			
			| 
				326
			 | 
			
				
			 | 
			
			
				
				-	if ( tcpip_protocol->csum_offset > 0 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				318
			 | 
			
			
				
				+	if ( tcpip_protocol->csum_offset > 0 ) 
			 | 
		
		
	
		
			
			| 
				327
			 | 
			
				319
			 | 
			
			
				
				 		ipv4_tx_csum ( pkb, tcpip_protocol ); 
			 | 
		
		
	
		
			
			| 
				328
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				329
			 | 
			
				320
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				330
			 | 
			
				321
			 | 
			
			
				
				 	/* Calculate header checksum, in network byte order */ 
			 | 
		
		
	
		
			
			| 
				331
			 | 
			
				
			 | 
			
			
				
				-	iphdr->chksum = 0; 
			 | 
		
		
	
		
			
			| 
				332
			 | 
			
				322
			 | 
			
			
				
				 	iphdr->chksum = tcpip_chksum ( iphdr, sizeof ( *iphdr ) ); 
			 | 
		
		
	
		
			
			| 
				333
			 | 
			
				323
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				334
			 | 
			
				324
			 | 
			
			
				
				 	/* Print IP4 header for debugging */ 
			 | 
		
		
	
		
			
			| 
				335
			 | 
			
				
			 | 
			
			
				
				-	ipv4_dump ( iphdr ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				325
			 | 
			
			
				
				+	DBG ( "IPv4 TX %s->", inet_ntoa ( iphdr->src ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				326
			 | 
			
			
				
				+	DBG ( "%s len %d proto %d id %04x csum %04x\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				327
			 | 
			
			
				
				+	      inet_ntoa ( iphdr->dest ), ntohs ( iphdr->len ), iphdr->protocol, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				328
			 | 
			
			
				
				+	      ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) ); 
			 | 
		
		
	
		
			
			| 
				336
			 | 
			
				329
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				337
			 | 
			
				330
			 | 
			
			
				
				 	/* Determine link-layer destination address */ 
			 | 
		
		
	
		
			
			| 
				338
			 | 
			
				331
			 | 
			
			
				
				 	if ( next_hop.s_addr == INADDR_BROADCAST ) { 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -394,7 +387,10 @@ static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused, 
			 | 
		
		
	
		
			
			| 
				394
			 | 
			
				387
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				395
			 | 
			
				388
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				396
			 | 
			
				389
			 | 
			
			
				
				 	/* Print IP4 header for debugging */ 
			 | 
		
		
	
		
			
			| 
				397
			 | 
			
				
			 | 
			
			
				
				-	ipv4_dump ( iphdr ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				390
			 | 
			
			
				
				+	DBG ( "IPv4 RX %s<-", inet_ntoa ( iphdr->dest ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				391
			 | 
			
			
				
				+	DBG ( "%s len %d proto %d id %04x csum %04x\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				392
			 | 
			
			
				
				+	      inet_ntoa ( iphdr->src ), ntohs ( iphdr->len ), iphdr->protocol, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				393
			 | 
			
			
				
				+	      ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) ); 
			 | 
		
		
	
		
			
			| 
				398
			 | 
			
				394
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				399
			 | 
			
				395
			 | 
			
			
				
				 	/* Validate version and header length */ 
			 | 
		
		
	
		
			
			| 
				400
			 | 
			
				396
			 | 
			
			
				
				 	if ( iphdr->verhdrlen != 0x45 ) { 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -414,8 +410,8 @@ static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused, 
			 | 
		
		
	
		
			
			| 
				414
			 | 
			
				410
			 | 
			
			
				
				 		DBG ( "Bad checksum %x\n", chksum ); 
			 | 
		
		
	
		
			
			| 
				415
			 | 
			
				411
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				416
			 | 
			
				412
			 | 
			
			
				
				 	/* Fragment reassembly */ 
			 | 
		
		
	
		
			
			| 
				417
			 | 
			
				
			 | 
			
			
				
				-	if ( ( iphdr->frags & IP_MASK_MOREFRAGS ) ||  
			 | 
		
		
	
		
			
			| 
				418
			 | 
			
				
			 | 
			
			
				
				-	     ( ( iphdr->frags & IP_MASK_OFFSET ) != 0 ) ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				413
			 | 
			
			
				
				+	if ( ( iphdr->frags & htons ( IP_MASK_MOREFRAGS ) ) ||  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				414
			 | 
			
			
				
				+	     ( ( iphdr->frags & htons ( IP_MASK_OFFSET ) ) != 0 ) ) { 
			 | 
		
		
	
		
			
			| 
				419
			 | 
			
				415
			 | 
			
			
				
				 		/* Pass the fragment to the reassembler ipv4_ressable() which 
			 | 
		
		
	
		
			
			| 
				420
			 | 
			
				416
			 | 
			
			
				
				 		 * either returns a fully reassembled packet buffer or NULL. 
			 | 
		
		
	
		
			
			| 
				421
			 | 
			
				417
			 | 
			
			
				
				 		 */ 
			 |