| 
				
			 | 
			
			
				
				@@ -9,6 +9,7 @@ 
			 | 
		
		
	
		
			
			| 
				9
			 | 
			
				9
			 | 
			
			
				
				 #include <net/if.h> 
			 | 
		
		
	
		
			
			| 
				10
			 | 
			
				10
			 | 
			
			
				
				 #include <net/ethernet.h> 
			 | 
		
		
	
		
			
			| 
				11
			 | 
			
				11
			 | 
			
			
				
				 #include <netinet/in.h> 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				12
			 | 
			
			
				
				+#include <arpa/inet.h> 
			 | 
		
		
	
		
			
			| 
				12
			 | 
			
				13
			 | 
			
			
				
				 #include <getopt.h> 
			 | 
		
		
	
		
			
			| 
				13
			 | 
			
				14
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				14
			 | 
			
				15
			 | 
			
			
				
				 typedef int irq_action_t; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -29,6 +30,57 @@ struct nic_operations { 
			 | 
		
		
	
		
			
			| 
				29
			 | 
			
				30
			 | 
			
			
				
				 	void ( *irq ) ( struct nic *, irq_action_t ); 
			 | 
		
		
	
		
			
			| 
				30
			 | 
			
				31
			 | 
			
			
				
				 }; 
			 | 
		
		
	
		
			
			| 
				31
			 | 
			
				32
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				33
			 | 
			
			
				
				+/***************************************************************************** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				34
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				35
			 | 
			
			
				
				+ * Net device layer 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				36
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				37
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				38
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				39
			 | 
			
			
				
				+#include "../proto/uip/uip_arp.h" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				40
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				41
			 | 
			
			
				
				+static unsigned char node_addr[ETH_ALEN]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				42
			 | 
			
			
				
				+static unsigned char packet[ETH_FRAME_LEN]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				43
			 | 
			
			
				
				+struct nic static_nic = { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				44
			 | 
			
			
				
				+	.node_addr = node_addr, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				45
			 | 
			
			
				
				+	.packet = packet, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				46
			 | 
			
			
				
				+}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				47
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				48
			 | 
			
			
				
				+/* Must be a macro because priv_data[] is of variable size */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				49
			 | 
			
			
				
				+#define alloc_netdevice( priv_size ) ( {	\ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				50
			 | 
			
			
				
				+	static char priv_data[priv_size];	\ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				51
			 | 
			
			
				
				+	static_nic.priv_data = priv_data;	\ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				52
			 | 
			
			
				
				+	&static_nic; } ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				53
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				54
			 | 
			
			
				
				+static int register_netdevice ( struct nic *nic ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				55
			 | 
			
			
				
				+	struct uip_eth_addr hwaddr; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				56
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				57
			 | 
			
			
				
				+	memcpy ( &hwaddr, nic->node_addr, sizeof ( hwaddr ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				58
			 | 
			
			
				
				+	uip_setethaddr ( hwaddr ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				59
			 | 
			
			
				
				+	return 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				60
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				61
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				62
			 | 
			
			
				
				+static inline void unregister_netdevice ( struct nic *nic ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				63
			 | 
			
			
				
				+	/* Do nothing */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				64
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				65
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				66
			 | 
			
			
				
				+static inline void free_netdevice ( struct nic *nic ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				67
			 | 
			
			
				
				+	/* Do nothing */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				68
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				69
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				70
			 | 
			
			
				
				+static int netdev_poll ( int retrieve, void **data, size_t *len ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				71
			 | 
			
			
				
				+	int rc = static_nic.nic_op->poll ( &static_nic, retrieve ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				72
			 | 
			
			
				
				+	*data = static_nic.packet; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				73
			 | 
			
			
				
				+	*len = static_nic.packetlen; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				74
			 | 
			
			
				
				+	return rc; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				75
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				76
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				77
			 | 
			
			
				
				+static void netdev_transmit ( const void *data, size_t len ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				78
			 | 
			
			
				
				+	uint16_t type = ntohs ( *( ( uint16_t * ) ( data + 12 ) ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				79
			 | 
			
			
				
				+	static_nic.nic_op->transmit ( &static_nic, data, type, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				80
			 | 
			
			
				
				+				      len - ETH_HLEN, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				81
			 | 
			
			
				
				+				      data + ETH_HLEN ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				82
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				83
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				32
			 | 
			
				84
			 | 
			
			
				
				 /***************************************************************************** 
			 | 
		
		
	
		
			
			| 
				33
			 | 
			
				85
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				34
			 | 
			
				86
			 | 
			
			
				
				  * Hijack device interface 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -43,8 +95,18 @@ struct hijack { 
			 | 
		
		
	
		
			
			| 
				43
			 | 
			
				95
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				44
			 | 
			
				96
			 | 
			
			
				
				 struct hijack_device { 
			 | 
		
		
	
		
			
			| 
				45
			 | 
			
				97
			 | 
			
			
				
				 	char *name; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				98
			 | 
			
			
				
				+	void *priv; 
			 | 
		
		
	
		
			
			| 
				46
			 | 
			
				99
			 | 
			
			
				
				 }; 
			 | 
		
		
	
		
			
			| 
				47
			 | 
			
				100
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				101
			 | 
			
			
				
				+static inline void hijack_set_drvdata ( struct hijack_device *hijack_dev, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				102
			 | 
			
			
				
				+					void *data ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				103
			 | 
			
			
				
				+	hijack_dev->priv = data; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				104
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				105
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				106
			 | 
			
			
				
				+static inline void * hijack_get_drvdata ( struct hijack_device *hijack_dev ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				107
			 | 
			
			
				
				+	return hijack_dev->priv; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				108
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				109
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				48
			 | 
			
				110
			 | 
			
			
				
				 static int hijack_poll ( struct nic *nic, int retrieve ) { 
			 | 
		
		
	
		
			
			| 
				49
			 | 
			
				111
			 | 
			
			
				
				 	struct hijack *hijack = nic->priv_data; 
			 | 
		
		
	
		
			
			| 
				50
			 | 
			
				112
			 | 
			
			
				
				 	fd_set fdset; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -118,16 +180,23 @@ static struct nic_operations hijack_operations = { 
			 | 
		
		
	
		
			
			| 
				118
			 | 
			
				180
			 | 
			
			
				
				 	.irq		= hijack_irq, 
			 | 
		
		
	
		
			
			| 
				119
			 | 
			
				181
			 | 
			
			
				
				 }; 
			 | 
		
		
	
		
			
			| 
				120
			 | 
			
				182
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				121
			 | 
			
				
			 | 
			
			
				
				-static int hijack_probe ( struct nic *nic, struct hijack_device *hijack_dev ) { 
			 | 
		
		
	
		
			
			| 
				122
			 | 
			
				
			 | 
			
			
				
				-	static struct hijack hijack; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				183
			 | 
			
			
				
				+int hijack_probe ( struct hijack_device *hijack_dev ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				184
			 | 
			
			
				
				+	struct nic *nic; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				185
			 | 
			
			
				
				+	struct hijack *hijack; 
			 | 
		
		
	
		
			
			| 
				123
			 | 
			
				186
			 | 
			
			
				
				 	struct sockaddr_un sun; 
			 | 
		
		
	
		
			
			| 
				124
			 | 
			
				187
			 | 
			
			
				
				 	int i; 
			 | 
		
		
	
		
			
			| 
				125
			 | 
			
				188
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				126
			 | 
			
				
			 | 
			
			
				
				-	memset ( &hijack, 0, sizeof ( hijack ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				189
			 | 
			
			
				
				+	nic = alloc_netdevice ( sizeof ( *hijack ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				190
			 | 
			
			
				
				+	if ( ! nic ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				191
			 | 
			
			
				
				+		fprintf ( stderr, "alloc_netdevice() failed\n" ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				192
			 | 
			
			
				
				+		goto err_alloc; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				193
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				194
			 | 
			
			
				
				+	hijack = nic->priv_data; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				195
			 | 
			
			
				
				+	memset ( hijack, 0, sizeof ( *hijack ) ); 
			 | 
		
		
	
		
			
			| 
				127
			 | 
			
				196
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				128
			 | 
			
				197
			 | 
			
			
				
				 	/* Create socket */ 
			 | 
		
		
	
		
			
			| 
				129
			 | 
			
				
			 | 
			
			
				
				-	hijack.fd = socket ( PF_UNIX, SOCK_SEQPACKET, 0 ); 
			 | 
		
		
	
		
			
			| 
				130
			 | 
			
				
			 | 
			
			
				
				-	if ( hijack.fd < 0 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				198
			 | 
			
			
				
				+	hijack->fd = socket ( PF_UNIX, SOCK_SEQPACKET, 0 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				199
			 | 
			
			
				
				+	if ( hijack->fd < 0 ) { 
			 | 
		
		
	
		
			
			| 
				131
			 | 
			
				200
			 | 
			
			
				
				 		fprintf ( stderr, "socket() failed: %s\n", 
			 | 
		
		
	
		
			
			| 
				132
			 | 
			
				201
			 | 
			
			
				
				 			  strerror ( errno ) ); 
			 | 
		
		
	
		
			
			| 
				133
			 | 
			
				202
			 | 
			
			
				
				 		goto err; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -137,7 +206,7 @@ static int hijack_probe ( struct nic *nic, struct hijack_device *hijack_dev ) { 
			 | 
		
		
	
		
			
			| 
				137
			 | 
			
				206
			 | 
			
			
				
				 	sun.sun_family = AF_UNIX; 
			 | 
		
		
	
		
			
			| 
				138
			 | 
			
				207
			 | 
			
			
				
				 	snprintf ( sun.sun_path, sizeof ( sun.sun_path ), "/var/run/hijack-%s", 
			 | 
		
		
	
		
			
			| 
				139
			 | 
			
				208
			 | 
			
			
				
				 		   hijack_dev->name ); 
			 | 
		
		
	
		
			
			| 
				140
			 | 
			
				
			 | 
			
			
				
				-	if ( connect ( hijack.fd, ( struct sockaddr * ) &sun, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				209
			 | 
			
			
				
				+	if ( connect ( hijack->fd, ( struct sockaddr * ) &sun, 
			 | 
		
		
	
		
			
			| 
				141
			 | 
			
				210
			 | 
			
			
				
				 		       sizeof ( sun ) ) < 0 ) { 
			 | 
		
		
	
		
			
			| 
				142
			 | 
			
				211
			 | 
			
			
				
				 		fprintf ( stderr, "could not connect to %s: %s\n", 
			 | 
		
		
	
		
			
			| 
				143
			 | 
			
				212
			 | 
			
			
				
				 			  sun.sun_path, strerror ( errno ) ); 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -152,23 +221,166 @@ static int hijack_probe ( struct nic *nic, struct hijack_device *hijack_dev ) { 
			 | 
		
		
	
		
			
			| 
				152
			 | 
			
				221
			 | 
			
			
				
				 	nic->node_addr[0] &= 0xfe; /* clear multicast bit */ 
			 | 
		
		
	
		
			
			| 
				153
			 | 
			
				222
			 | 
			
			
				
				 	nic->node_addr[0] |= 0x02; /* set "locally-assigned" bit */ 
			 | 
		
		
	
		
			
			| 
				154
			 | 
			
				223
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				155
			 | 
			
				
			 | 
			
			
				
				-	nic->priv_data = &hijack; 
			 | 
		
		
	
		
			
			| 
				156
			 | 
			
				224
			 | 
			
			
				
				 	nic->nic_op = &hijack_operations; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				225
			 | 
			
			
				
				+	if ( register_netdevice ( nic ) < 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				226
			 | 
			
			
				
				+		goto err; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				227
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				228
			 | 
			
			
				
				+	hijack_set_drvdata ( hijack_dev, nic ); 
			 | 
		
		
	
		
			
			| 
				157
			 | 
			
				229
			 | 
			
			
				
				 	return 1; 
			 | 
		
		
	
		
			
			| 
				158
			 | 
			
				230
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				159
			 | 
			
				231
			 | 
			
			
				
				  err: 
			 | 
		
		
	
		
			
			| 
				160
			 | 
			
				
			 | 
			
			
				
				-	if ( hijack.fd >= 0 ) 
			 | 
		
		
	
		
			
			| 
				161
			 | 
			
				
			 | 
			
			
				
				-		close ( hijack.fd ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				232
			 | 
			
			
				
				+	if ( hijack->fd >= 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				233
			 | 
			
			
				
				+		close ( hijack->fd ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				234
			 | 
			
			
				
				+	free_netdevice ( nic ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				235
			 | 
			
			
				
				+ err_alloc: 
			 | 
		
		
	
		
			
			| 
				162
			 | 
			
				236
			 | 
			
			
				
				 	return 0; 
			 | 
		
		
	
		
			
			| 
				163
			 | 
			
				237
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				164
			 | 
			
				238
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				165
			 | 
			
				
			 | 
			
			
				
				-static void hijack_disable ( struct nic *nic, 
			 | 
		
		
	
		
			
			| 
				166
			 | 
			
				
			 | 
			
			
				
				-			     struct hijack_device *hijack_dev ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				239
			 | 
			
			
				
				+static void hijack_disable ( struct hijack_device *hijack_dev ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				240
			 | 
			
			
				
				+	struct nic *nic = hijack_get_drvdata ( hijack_dev ); 
			 | 
		
		
	
		
			
			| 
				167
			 | 
			
				241
			 | 
			
			
				
				 	struct hijack *hijack = nic->priv_data; 
			 | 
		
		
	
		
			
			| 
				168
			 | 
			
				242
			 | 
			
			
				
				 	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				243
			 | 
			
			
				
				+	unregister_netdevice ( nic ); 
			 | 
		
		
	
		
			
			| 
				169
			 | 
			
				244
			 | 
			
			
				
				 	close ( hijack->fd ); 
			 | 
		
		
	
		
			
			| 
				170
			 | 
			
				245
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				171
			 | 
			
				246
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				247
			 | 
			
			
				
				+/***************************************************************************** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				248
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				249
			 | 
			
			
				
				+ * uIP wrapper layer 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				250
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				251
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				252
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				253
			 | 
			
			
				
				+#include "../proto/uip/uip.h" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				254
			 | 
			
			
				
				+#include "../proto/uip/uip_arp.h" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				255
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				256
			 | 
			
			
				
				+void UIP_APPCALL ( void ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				257
			 | 
			
			
				
				+	printf ( "appcall\n" ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				258
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				259
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				260
			 | 
			
			
				
				+void udp_appcall ( void ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				261
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				262
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				263
			 | 
			
			
				
				+static void init_tcpip ( void ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				264
			 | 
			
			
				
				+	uip_init(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				265
			 | 
			
			
				
				+	uip_arp_init(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				266
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				267
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				268
			 | 
			
			
				
				+static void uip_transmit ( void ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				269
			 | 
			
			
				
				+	uip_arp_out(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				270
			 | 
			
			
				
				+	netdev_transmit ( uip_buf, uip_len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				271
			 | 
			
			
				
				+	uip_len = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				272
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				273
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				274
			 | 
			
			
				
				+static int tcp_connect ( struct sockaddr_in *sin ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				275
			 | 
			
			
				
				+	u16_t ipaddr[2]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				276
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				277
			 | 
			
			
				
				+	* ( ( uint32_t * ) ipaddr ) = sin->sin_addr.s_addr; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				278
			 | 
			
			
				
				+	return uip_connect ( ipaddr, sin->sin_port ) ? 1 : 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				279
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				280
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				281
			 | 
			
			
				
				+static void run_tcpip ( void ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				282
			 | 
			
			
				
				+	void *data; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				283
			 | 
			
			
				
				+	size_t len; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				284
			 | 
			
			
				
				+	uint16_t type; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				285
			 | 
			
			
				
				+	int i; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				286
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				287
			 | 
			
			
				
				+	if ( netdev_poll ( 1, &data, &len ) ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				288
			 | 
			
			
				
				+		/* We have data */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				289
			 | 
			
			
				
				+		memcpy ( uip_buf, data, len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				290
			 | 
			
			
				
				+		uip_len = len; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				291
			 | 
			
			
				
				+		type = ntohs ( *( ( uint16_t * ) ( uip_buf + 12 ) ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				292
			 | 
			
			
				
				+		if ( type == ETHERTYPE_ARP ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				293
			 | 
			
			
				
				+			uip_arp_arpin(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				294
			 | 
			
			
				
				+		} else { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				295
			 | 
			
			
				
				+			uip_arp_ipin(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				296
			 | 
			
			
				
				+			uip_input(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				297
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				298
			 | 
			
			
				
				+		if ( uip_len > 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				299
			 | 
			
			
				
				+			uip_transmit(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				300
			 | 
			
			
				
				+	} else { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				301
			 | 
			
			
				
				+		for ( i = 0 ; i < UIP_CONNS ; i++ ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				302
			 | 
			
			
				
				+			uip_periodic ( i ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				303
			 | 
			
			
				
				+			if ( uip_len > 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				304
			 | 
			
			
				
				+				uip_transmit(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				305
			 | 
			
			
				
				+		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				306
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				307
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				308
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				309
			 | 
			
			
				
				+/***************************************************************************** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				310
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				311
			 | 
			
			
				
				+ * HTTP protocol tester 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				312
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				313
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				314
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				315
			 | 
			
			
				
				+struct http_request { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				316
			 | 
			
			
				
				+	struct sockaddr_in sin; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				317
			 | 
			
			
				
				+	const char *filename; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				318
			 | 
			
			
				
				+	void ( *callback ) ( struct http_request *http ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				319
			 | 
			
			
				
				+	int complete; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				320
			 | 
			
			
				
				+}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				321
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				322
			 | 
			
			
				
				+static int http_get ( struct http_request *http ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				323
			 | 
			
			
				
				+	return tcp_connect ( &http->sin ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				324
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				325
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				326
			 | 
			
			
				
				+static void test_http_callback ( struct http_request *http ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				327
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				328
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				329
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				330
			 | 
			
			
				
				+static int test_http ( int argc, char **argv ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				331
			 | 
			
			
				
				+	struct http_request http; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				332
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				333
			 | 
			
			
				
				+	memset ( &http, 0, sizeof ( http ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				334
			 | 
			
			
				
				+	http.filename = "/"; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				335
			 | 
			
			
				
				+	http.callback = test_http_callback; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				336
			 | 
			
			
				
				+	inet_aton ( "192.168.0.1", &http.sin.sin_addr ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				337
			 | 
			
			
				
				+	http.sin.sin_port = htons ( 80 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				338
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				339
			 | 
			
			
				
				+	http_get ( &http ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				340
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				341
			 | 
			
			
				
				+	while ( ! http.complete ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				342
			 | 
			
			
				
				+		run_tcpip (); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				343
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				344
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				345
			 | 
			
			
				
				+	return 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				346
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				347
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				348
			 | 
			
			
				
				+/***************************************************************************** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				349
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				350
			 | 
			
			
				
				+ * Protocol tester 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				351
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				352
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				353
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				354
			 | 
			
			
				
				+struct protocol_test { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				355
			 | 
			
			
				
				+	const char *name; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				356
			 | 
			
			
				
				+	int ( *exec ) ( int argc, char **argv ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				357
			 | 
			
			
				
				+}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				358
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				359
			 | 
			
			
				
				+static struct protocol_test tests[] = { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				360
			 | 
			
			
				
				+	{ "http", test_http }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				361
			 | 
			
			
				
				+}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				362
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				363
			 | 
			
			
				
				+#define NUM_TESTS ( sizeof ( tests ) / sizeof ( tests[0] ) ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				364
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				365
			 | 
			
			
				
				+static void list_tests ( void ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				366
			 | 
			
			
				
				+	int i; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				367
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				368
			 | 
			
			
				
				+	for ( i = 0 ; i < NUM_TESTS ; i++ ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				369
			 | 
			
			
				
				+		printf ( "%s\n", tests[i].name ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				370
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				371
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				372
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				373
			 | 
			
			
				
				+static struct protocol_test * get_test_from_name ( const char *name ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				374
			 | 
			
			
				
				+	int i; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				375
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				376
			 | 
			
			
				
				+	for ( i = 0 ; i < NUM_TESTS ; i++ ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				377
			 | 
			
			
				
				+		if ( strcmp ( name, tests[i].name ) == 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				378
			 | 
			
			
				
				+			return &tests[i]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				379
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				380
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				381
			 | 
			
			
				
				+	return NULL; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				382
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				383
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				172
			 | 
			
				384
			 | 
			
			
				
				 /***************************************************************************** 
			 | 
		
		
	
		
			
			| 
				173
			 | 
			
				385
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				174
			 | 
			
				386
			 | 
			
			
				
				  * Parse command-line options 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -181,18 +393,22 @@ struct tester_options { 
			 | 
		
		
	
		
			
			| 
				181
			 | 
			
				393
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				182
			 | 
			
				394
			 | 
			
			
				
				 static void usage ( char **argv ) { 
			 | 
		
		
	
		
			
			| 
				183
			 | 
			
				395
			 | 
			
			
				
				 	fprintf ( stderr, 
			 | 
		
		
	
		
			
			| 
				184
			 | 
			
				
			 | 
			
			
				
				-		  "Usage: %s [options]\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				396
			 | 
			
			
				
				+		  "Usage: %s [global options] <test> [test-specific options]\n" 
			 | 
		
		
	
		
			
			| 
				185
			 | 
			
				397
			 | 
			
			
				
				 		  "\n" 
			 | 
		
		
	
		
			
			| 
				186
			 | 
			
				
			 | 
			
			
				
				-		  "Options:\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				398
			 | 
			
			
				
				+		  "Global options:\n" 
			 | 
		
		
	
		
			
			| 
				187
			 | 
			
				399
			 | 
			
			
				
				 		  "  -h|--help              Print this help message\n" 
			 | 
		
		
	
		
			
			| 
				188
			 | 
			
				
			 | 
			
			
				
				-		  "  -i|--interface intf    Use specified network interface\n", 
			 | 
		
		
	
		
			
			| 
				189
			 | 
			
				
			 | 
			
			
				
				-		  argv[0] ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				400
			 | 
			
			
				
				+		  "  -i|--interface intf    Use specified network interface\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				401
			 | 
			
			
				
				+		  "  -l|--list              List available tests\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				402
			 | 
			
			
				
				+		  "\n" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				403
			 | 
			
			
				
				+		  "Use \"%s <test> -h\" to view test-specific options\n", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				404
			 | 
			
			
				
				+		  argv[0], argv[0] ); 
			 | 
		
		
	
		
			
			| 
				190
			 | 
			
				405
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				191
			 | 
			
				406
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				192
			 | 
			
				407
			 | 
			
			
				
				 static int parse_options ( int argc, char **argv, 
			 | 
		
		
	
		
			
			| 
				193
			 | 
			
				408
			 | 
			
			
				
				 			   struct tester_options *options ) { 
			 | 
		
		
	
		
			
			| 
				194
			 | 
			
				409
			 | 
			
			
				
				 	static struct option long_options[] = { 
			 | 
		
		
	
		
			
			| 
				195
			 | 
			
				410
			 | 
			
			
				
				 		{ "interface", 1, NULL, 'i' }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				411
			 | 
			
			
				
				+		{ "list", 0, NULL, 'l' }, 
			 | 
		
		
	
		
			
			| 
				196
			 | 
			
				412
			 | 
			
			
				
				 		{ "help", 0, NULL, 'h' }, 
			 | 
		
		
	
		
			
			| 
				197
			 | 
			
				413
			 | 
			
			
				
				 		{ }, 
			 | 
		
		
	
		
			
			| 
				198
			 | 
			
				414
			 | 
			
			
				
				 	}; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -206,7 +422,7 @@ static int parse_options ( int argc, char **argv, 
			 | 
		
		
	
		
			
			| 
				206
			 | 
			
				422
			 | 
			
			
				
				 	while ( 1 ) { 
			 | 
		
		
	
		
			
			| 
				207
			 | 
			
				423
			 | 
			
			
				
				 		int option_index = 0; 
			 | 
		
		
	
		
			
			| 
				208
			 | 
			
				424
			 | 
			
			
				
				 		 
			 | 
		
		
	
		
			
			| 
				209
			 | 
			
				
			 | 
			
			
				
				-		c = getopt_long ( argc, argv, "i:h", long_options, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				425
			 | 
			
			
				
				+		c = getopt_long ( argc, argv, "+i:hl", long_options, 
			 | 
		
		
	
		
			
			| 
				210
			 | 
			
				426
			 | 
			
			
				
				 				  &option_index ); 
			 | 
		
		
	
		
			
			| 
				211
			 | 
			
				427
			 | 
			
			
				
				 		if ( c < 0 ) 
			 | 
		
		
	
		
			
			| 
				212
			 | 
			
				428
			 | 
			
			
				
				 			break; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -216,8 +432,11 @@ static int parse_options ( int argc, char **argv, 
			 | 
		
		
	
		
			
			| 
				216
			 | 
			
				432
			 | 
			
			
				
				 			strncpy ( options->interface, optarg, 
			 | 
		
		
	
		
			
			| 
				217
			 | 
			
				433
			 | 
			
			
				
				 				  sizeof ( options->interface ) ); 
			 | 
		
		
	
		
			
			| 
				218
			 | 
			
				434
			 | 
			
			
				
				 			break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				435
			 | 
			
			
				
				+		case 'l': 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				436
			 | 
			
			
				
				+			list_tests (); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				437
			 | 
			
			
				
				+			return -1; 
			 | 
		
		
	
		
			
			| 
				219
			 | 
			
				438
			 | 
			
			
				
				 		case 'h': 
			 | 
		
		
	
		
			
			| 
				220
			 | 
			
				
			 | 
			
			
				
				-			usage( argv ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				439
			 | 
			
			
				
				+			usage ( argv ); 
			 | 
		
		
	
		
			
			| 
				221
			 | 
			
				440
			 | 
			
			
				
				 			return -1; 
			 | 
		
		
	
		
			
			| 
				222
			 | 
			
				441
			 | 
			
			
				
				 		case '?': 
			 | 
		
		
	
		
			
			| 
				223
			 | 
			
				442
			 | 
			
			
				
				 			/* Unrecognised option */ 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -228,79 +447,13 @@ static int parse_options ( int argc, char **argv, 
			 | 
		
		
	
		
			
			| 
				228
			 | 
			
				447
			 | 
			
			
				
				 		} 
			 | 
		
		
	
		
			
			| 
				229
			 | 
			
				448
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				230
			 | 
			
				449
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				231
			 | 
			
				
			 | 
			
			
				
				-	/* Check there's nothing left over on the command line */ 
			 | 
		
		
	
		
			
			| 
				232
			 | 
			
				
			 | 
			
			
				
				-	if ( optind != argc ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				450
			 | 
			
			
				
				+	/* Check there is a test specified */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				451
			 | 
			
			
				
				+	if ( optind == argc ) { 
			 | 
		
		
	
		
			
			| 
				233
			 | 
			
				452
			 | 
			
			
				
				 		usage ( argv ); 
			 | 
		
		
	
		
			
			| 
				234
			 | 
			
				453
			 | 
			
			
				
				 		return -1; 
			 | 
		
		
	
		
			
			| 
				235
			 | 
			
				454
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				236
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				237
			 | 
			
				
			 | 
			
			
				
				-	return 0; 
			 | 
		
		
	
		
			
			| 
				238
			 | 
			
				
			 | 
			
			
				
				-} 
			 | 
		
		
	
		
			
			| 
				239
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				240
			 | 
			
				
			 | 
			
			
				
				-/***************************************************************************** 
			 | 
		
		
	
		
			
			| 
				241
			 | 
			
				
			 | 
			
			
				
				- * 
			 | 
		
		
	
		
			
			| 
				242
			 | 
			
				
			 | 
			
			
				
				- * uIP wrapper layer 
			 | 
		
		
	
		
			
			| 
				243
			 | 
			
				
			 | 
			
			
				
				- * 
			 | 
		
		
	
		
			
			| 
				244
			 | 
			
				
			 | 
			
			
				
				- */ 
			 | 
		
		
	
		
			
			| 
				245
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				246
			 | 
			
				
			 | 
			
			
				
				-#include "../proto/uip/uip.h" 
			 | 
		
		
	
		
			
			| 
				247
			 | 
			
				
			 | 
			
			
				
				-#include "../proto/uip/uip_arp.h" 
			 | 
		
		
	
		
			
			| 
				248
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				249
			 | 
			
				
			 | 
			
			
				
				-static int done; 
			 | 
		
		
	
		
			
			| 
				250
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				251
			 | 
			
				
			 | 
			
			
				
				-void UIP_APPCALL ( void ) { 
			 | 
		
		
	
		
			
			| 
				252
			 | 
			
				
			 | 
			
			
				
				-	printf ( "appcall\n" ); 
			 | 
		
		
	
		
			
			| 
				253
			 | 
			
				
			 | 
			
			
				
				-} 
			 | 
		
		
	
		
			
			| 
				254
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				255
			 | 
			
				
			 | 
			
			
				
				-void udp_appcall ( void ) { 
			 | 
		
		
	
		
			
			| 
				256
			 | 
			
				
			 | 
			
			
				
				-} 
			 | 
		
		
	
		
			
			| 
				257
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				258
			 | 
			
				
			 | 
			
			
				
				-static void uip_transmit ( struct nic *nic ) { 
			 | 
		
		
	
		
			
			| 
				259
			 | 
			
				
			 | 
			
			
				
				-	uip_arp_out(); 
			 | 
		
		
	
		
			
			| 
				260
			 | 
			
				
			 | 
			
			
				
				-	nic->nic_op->transmit ( nic, ( char * ) uip_buf, 
			 | 
		
		
	
		
			
			| 
				261
			 | 
			
				
			 | 
			
			
				
				-				ntohs ( *( ( uint16_t * ) ( uip_buf + 12 ) ) ), 
			 | 
		
		
	
		
			
			| 
				262
			 | 
			
				
			 | 
			
			
				
				-				uip_len - ETH_HLEN, 
			 | 
		
		
	
		
			
			| 
				263
			 | 
			
				
			 | 
			
			
				
				-				( char * ) uip_buf + ETH_HLEN ); 
			 | 
		
		
	
		
			
			| 
				264
			 | 
			
				
			 | 
			
			
				
				-	uip_len = 0; 
			 | 
		
		
	
		
			
			| 
				265
			 | 
			
				
			 | 
			
			
				
				-} 
			 | 
		
		
	
		
			
			| 
				266
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				267
			 | 
			
				
			 | 
			
			
				
				-static void run_stack ( struct nic *nic ) { 
			 | 
		
		
	
		
			
			| 
				268
			 | 
			
				
			 | 
			
			
				
				-	struct uip_eth_addr hwaddr; 
			 | 
		
		
	
		
			
			| 
				269
			 | 
			
				
			 | 
			
			
				
				-	u16_t ipaddr[2]; 
			 | 
		
		
	
		
			
			| 
				270
			 | 
			
				
			 | 
			
			
				
				-	uint16_t type; 
			 | 
		
		
	
		
			
			| 
				271
			 | 
			
				
			 | 
			
			
				
				-	int i; 
			 | 
		
		
	
		
			
			| 
				272
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				273
			 | 
			
				
			 | 
			
			
				
				-	uip_init(); 
			 | 
		
		
	
		
			
			| 
				274
			 | 
			
				
			 | 
			
			
				
				-	uip_arp_init(); 
			 | 
		
		
	
		
			
			| 
				275
			 | 
			
				
			 | 
			
			
				
				-	memcpy ( &hwaddr, nic->node_addr, sizeof ( hwaddr ) ); 
			 | 
		
		
	
		
			
			| 
				276
			 | 
			
				
			 | 
			
			
				
				-	uip_setethaddr ( hwaddr ); 
			 | 
		
		
	
		
			
			| 
				277
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				278
			 | 
			
				
			 | 
			
			
				
				-	uip_ipaddr(ipaddr, 192,168,0,1); 
			 | 
		
		
	
		
			
			| 
				279
			 | 
			
				
			 | 
			
			
				
				-	uip_connect(ipaddr, HTONS(80)); 
			 | 
		
		
	
		
			
			| 
				280
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				281
			 | 
			
				
			 | 
			
			
				
				-	done = 0; 
			 | 
		
		
	
		
			
			| 
				282
			 | 
			
				
			 | 
			
			
				
				-	while ( ! done ) { 
			 | 
		
		
	
		
			
			| 
				283
			 | 
			
				
			 | 
			
			
				
				-		if ( nic->nic_op->poll ( nic, 1 ) ) { 
			 | 
		
		
	
		
			
			| 
				284
			 | 
			
				
			 | 
			
			
				
				-			/* We have data */ 
			 | 
		
		
	
		
			
			| 
				285
			 | 
			
				
			 | 
			
			
				
				-			memcpy ( uip_buf, nic->packet, nic->packetlen ); 
			 | 
		
		
	
		
			
			| 
				286
			 | 
			
				
			 | 
			
			
				
				-			uip_len = nic->packetlen; 
			 | 
		
		
	
		
			
			| 
				287
			 | 
			
				
			 | 
			
			
				
				-			type = ntohs ( *( ( uint16_t * ) ( uip_buf + 12 ) ) ); 
			 | 
		
		
	
		
			
			| 
				288
			 | 
			
				
			 | 
			
			
				
				-			if ( type == ETHERTYPE_ARP ) { 
			 | 
		
		
	
		
			
			| 
				289
			 | 
			
				
			 | 
			
			
				
				-				uip_arp_arpin(); 
			 | 
		
		
	
		
			
			| 
				290
			 | 
			
				
			 | 
			
			
				
				-			} else { 
			 | 
		
		
	
		
			
			| 
				291
			 | 
			
				
			 | 
			
			
				
				-				uip_arp_ipin(); 
			 | 
		
		
	
		
			
			| 
				292
			 | 
			
				
			 | 
			
			
				
				-				uip_input(); 
			 | 
		
		
	
		
			
			| 
				293
			 | 
			
				
			 | 
			
			
				
				-			} 
			 | 
		
		
	
		
			
			| 
				294
			 | 
			
				
			 | 
			
			
				
				-			if ( uip_len > 0 ) 
			 | 
		
		
	
		
			
			| 
				295
			 | 
			
				
			 | 
			
			
				
				-				uip_transmit ( nic ); 
			 | 
		
		
	
		
			
			| 
				296
			 | 
			
				
			 | 
			
			
				
				-		} else { 
			 | 
		
		
	
		
			
			| 
				297
			 | 
			
				
			 | 
			
			
				
				-			for ( i = 0 ; i < UIP_CONNS ; i++ ) { 
			 | 
		
		
	
		
			
			| 
				298
			 | 
			
				
			 | 
			
			
				
				-				uip_periodic ( i ); 
			 | 
		
		
	
		
			
			| 
				299
			 | 
			
				
			 | 
			
			
				
				-				if ( uip_len > 0 ) 
			 | 
		
		
	
		
			
			| 
				300
			 | 
			
				
			 | 
			
			
				
				-					uip_transmit ( nic ); 
			 | 
		
		
	
		
			
			| 
				301
			 | 
			
				
			 | 
			
			
				
				-			} 
			 | 
		
		
	
		
			
			| 
				302
			 | 
			
				
			 | 
			
			
				
				-		} 
			 | 
		
		
	
		
			
			| 
				303
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				455
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				456
			 | 
			
			
				
				+	return optind; 
			 | 
		
		
	
		
			
			| 
				304
			 | 
			
				457
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				305
			 | 
			
				458
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				306
			 | 
			
				459
			 | 
			
			
				
				 /***************************************************************************** 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -311,28 +464,35 @@ static void run_stack ( struct nic *nic ) { 
			 | 
		
		
	
		
			
			| 
				311
			 | 
			
				464
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				312
			 | 
			
				465
			 | 
			
			
				
				 int main ( int argc, char **argv ) { 
			 | 
		
		
	
		
			
			| 
				313
			 | 
			
				466
			 | 
			
			
				
				 	struct tester_options options; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				467
			 | 
			
			
				
				+	struct protocol_test *test; 
			 | 
		
		
	
		
			
			| 
				314
			 | 
			
				468
			 | 
			
			
				
				 	struct hijack_device hijack_dev; 
			 | 
		
		
	
		
			
			| 
				315
			 | 
			
				
			 | 
			
			
				
				-	static unsigned char node_addr[ETH_ALEN]; 
			 | 
		
		
	
		
			
			| 
				316
			 | 
			
				
			 | 
			
			
				
				-	static unsigned char packet[ETH_FRAME_LEN]; 
			 | 
		
		
	
		
			
			| 
				317
			 | 
			
				
			 | 
			
			
				
				-	struct nic nic = { 
			 | 
		
		
	
		
			
			| 
				318
			 | 
			
				
			 | 
			
			
				
				-		.node_addr = node_addr, 
			 | 
		
		
	
		
			
			| 
				319
			 | 
			
				
			 | 
			
			
				
				-		.packet = packet, 
			 | 
		
		
	
		
			
			| 
				320
			 | 
			
				
			 | 
			
			
				
				-	}; 
			 | 
		
		
	
		
			
			| 
				321
			 | 
			
				469
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				322
			 | 
			
				470
			 | 
			
			
				
				 	/* Parse command-line options */ 
			 | 
		
		
	
		
			
			| 
				323
			 | 
			
				471
			 | 
			
			
				
				 	if ( parse_options ( argc, argv, &options ) < 0 ) 
			 | 
		
		
	
		
			
			| 
				324
			 | 
			
				472
			 | 
			
			
				
				 		exit ( 1 ); 
			 | 
		
		
	
		
			
			| 
				325
			 | 
			
				473
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				474
			 | 
			
			
				
				+	/* Identify test */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				475
			 | 
			
			
				
				+	test = get_test_from_name ( argv[optind] ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				476
			 | 
			
			
				
				+	if ( ! test ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				477
			 | 
			
			
				
				+		fprintf ( stderr, "Unrecognised test \"%s\"\n", argv[optind] ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				478
			 | 
			
			
				
				+		return -1; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				479
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				480
			 | 
			
			
				
				+	optind++; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				481
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				482
			 | 
			
			
				
				+	/* Initialise the protocol stack */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				483
			 | 
			
			
				
				+	init_tcpip(); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				484
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				326
			 | 
			
				485
			 | 
			
			
				
				 	/* Open the hijack device */ 
			 | 
		
		
	
		
			
			| 
				327
			 | 
			
				486
			 | 
			
			
				
				 	hijack_dev.name = options.interface; 
			 | 
		
		
	
		
			
			| 
				328
			 | 
			
				
			 | 
			
			
				
				-	if ( ! hijack_probe ( &nic, &hijack_dev ) ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				487
			 | 
			
			
				
				+	if ( ! hijack_probe ( &hijack_dev ) ) 
			 | 
		
		
	
		
			
			| 
				329
			 | 
			
				488
			 | 
			
			
				
				 		exit ( 1 ); 
			 | 
		
		
	
		
			
			| 
				330
			 | 
			
				489
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				331
			 | 
			
				
			 | 
			
			
				
				-	/* Run the stack to completion */ 
			 | 
		
		
	
		
			
			| 
				332
			 | 
			
				
			 | 
			
			
				
				-	run_stack ( &nic ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				490
			 | 
			
			
				
				+	/* Run the test */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				491
			 | 
			
			
				
				+	if ( test->exec ( argc, argv ) < 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				492
			 | 
			
			
				
				+		exit ( 1 ); 
			 | 
		
		
	
		
			
			| 
				333
			 | 
			
				493
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				334
			 | 
			
				494
			 | 
			
			
				
				 	/* Close the hijack device */ 
			 | 
		
		
	
		
			
			| 
				335
			 | 
			
				
			 | 
			
			
				
				-	hijack_disable ( &nic, &hijack_dev ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				495
			 | 
			
			
				
				+	hijack_disable ( &hijack_dev ); 
			 | 
		
		
	
		
			
			| 
				336
			 | 
			
				496
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				337
			 | 
			
				497
			 | 
			
			
				
				 	return 0; 
			 | 
		
		
	
		
			
			| 
				338
			 | 
			
				498
			 | 
			
			
				
				 } 
			 |