Procházet zdrojové kódy

Update ftp.c to work with Nikhil's TCP stack.

Remove the now-totally-obsolete sockaddr_in field from tcp.h.
tags/v0.9.3
Michael Brown před 17 roky
rodič
revize
89bcb57201
5 změnil soubory, kde provedl 99 přidání a 33 odebrání
  1. 2
    0
      src/include/gpxe/ftp.h
  2. 4
    4
      src/include/gpxe/tcp.h
  3. 43
    18
      src/net/tcp/ftp.c
  4. 47
    7
      src/tests/dhcptest.c
  5. 3
    4
      src/tests/ftptest.c

+ 2
- 0
src/include/gpxe/ftp.h Zobrazit soubor

49
 	 * remote server.
49
 	 * remote server.
50
 	 */
50
 	 */
51
 	void ( *callback ) ( char *data, size_t len );
51
 	void ( *callback ) ( char *data, size_t len );
52
+	/** Eventual return status */
53
+	int rc;
52
 	/** Asynchronous operation for this FTP operation */
54
 	/** Asynchronous operation for this FTP operation */
53
 	struct async_operation aop;
55
 	struct async_operation aop;
54
 
56
 

+ 4
- 4
src/include/gpxe/tcp.h Zobrazit soubor

144
  */
144
  */
145
 struct tcp_connection {
145
 struct tcp_connection {
146
 	struct sockaddr_tcpip peer;	/* Remote socket address */
146
 	struct sockaddr_tcpip peer;	/* Remote socket address */
147
-
148
-	/* FIXME: this field should no longer be present */
149
-	struct sockaddr_in sin;
150
-
151
 	uint16_t local_port;		/* Local port, in network byte order */
147
 	uint16_t local_port;		/* Local port, in network byte order */
152
 	int tcp_state;			/* TCP state */
148
 	int tcp_state;			/* TCP state */
153
 	int tcp_lstate;			/* Last TCP state */
149
 	int tcp_lstate;			/* Last TCP state */
206
 
202
 
207
 extern struct tcpip_protocol tcp_protocol;
203
 extern struct tcpip_protocol tcp_protocol;
208
 
204
 
205
+static inline int tcp_closed ( struct tcp_connection *conn ) {
206
+	return ( conn->tcp_state == TCP_CLOSED );
207
+}
208
+
209
 extern void tcp_init_conn ( struct tcp_connection *conn );
209
 extern void tcp_init_conn ( struct tcp_connection *conn );
210
 extern int tcp_connect ( struct tcp_connection *conn );
210
 extern int tcp_connect ( struct tcp_connection *conn );
211
 extern int tcp_connectto ( struct tcp_connection *conn,
211
 extern int tcp_connectto ( struct tcp_connection *conn,

+ 43
- 18
src/net/tcp/ftp.c Zobrazit soubor

67
 	return container_of ( conn, struct ftp_request, tcp );
67
 	return container_of ( conn, struct ftp_request, tcp );
68
 }
68
 }
69
 
69
 
70
+static void ftp_set_status ( struct ftp_request *ftp, int rc ) {
71
+	if ( ! ftp->rc )
72
+		ftp->rc = rc;
73
+}
74
+
75
+static void ftp_clear_status ( struct ftp_request *ftp ) {
76
+	ftp->rc = 0;
77
+}
78
+
70
 /**
79
 /**
71
- * Mark FTP request as complete
80
+ * Mark FTP operation as complete
72
  *
81
  *
73
  * @v ftp		FTP request
82
  * @v ftp		FTP request
74
- * @v rc		Return status code
75
- *
76
  */
83
  */
77
-static void ftp_done ( struct ftp_request *ftp, int rc ) {
78
-	tcp_close ( &ftp->tcp_data );
79
-	tcp_close ( &ftp->tcp );
80
-	async_done ( &ftp->aop, rc );
84
+static void ftp_done ( struct ftp_request *ftp ) {
85
+	async_done ( &ftp->aop, ftp->rc );
81
 }
86
 }
82
 
87
 
83
 /**
88
 /**
128
 	/* Open passive connection when we get "PASV" response */
133
 	/* Open passive connection when we get "PASV" response */
129
 	if ( ftp->state == FTP_PASV ) {
134
 	if ( ftp->state == FTP_PASV ) {
130
 		char *ptr = ftp->passive_text;
135
 		char *ptr = ftp->passive_text;
131
-
132
-		ftp_parse_value ( &ptr,
133
-				  ( uint8_t * ) &ftp->tcp_data.sin.sin_addr,
134
-				  sizeof ( ftp->tcp_data.sin.sin_addr ) );
135
-		ftp_parse_value ( &ptr,
136
-				  ( uint8_t * ) &ftp->tcp_data.sin.sin_port,
137
-				  sizeof ( ftp->tcp_data.sin.sin_port ) );
136
+		struct sockaddr_in *sin =
137
+			( struct sockaddr_in * ) &ftp->tcp_data.peer;
138
+
139
+		sin->sin_family = AF_INET;
140
+		ftp_parse_value ( &ptr, ( uint8_t * ) &sin->sin_addr,
141
+				  sizeof ( sin->sin_addr ) );
142
+		ftp_parse_value ( &ptr, ( uint8_t * ) &sin->sin_port,
143
+				  sizeof ( sin->sin_port ) );
138
 		tcp_connect ( &ftp->tcp_data );
144
 		tcp_connect ( &ftp->tcp_data );
139
 	}
145
 	}
140
 
146
 
146
 
152
 
147
  err:
153
  err:
148
 	/* Flag protocol error and close connections */
154
 	/* Flag protocol error and close connections */
149
-	ftp_done ( ftp, -EPROTO );
155
+	ftp_set_status ( ftp, -EPROTO );
156
+	tcp_close ( &ftp->tcp );
150
 }
157
 }
151
 
158
 
152
 /**
159
 /**
249
 static void ftp_closed ( struct tcp_connection *conn, int status ) {
256
 static void ftp_closed ( struct tcp_connection *conn, int status ) {
250
 	struct ftp_request *ftp = tcp_to_ftp ( conn );
257
 	struct ftp_request *ftp = tcp_to_ftp ( conn );
251
 
258
 
252
-	ftp_done ( ftp, status );
259
+	/* Close data channel and record status */
260
+	ftp_set_status ( ftp, status );
261
+	tcp_close ( &ftp->tcp_data );
262
+
263
+	/* Mark FTP operation as complete if we are the last
264
+	 * connection to close
265
+	 */
266
+	if ( tcp_closed ( &ftp->tcp_data ) )
267
+		ftp_done ( ftp );
253
 }
268
 }
254
 
269
 
255
 /** FTP control channel operations */
270
 /** FTP control channel operations */
290
  */
305
  */
291
 static void ftp_data_closed ( struct tcp_connection *conn, int status ) {
306
 static void ftp_data_closed ( struct tcp_connection *conn, int status ) {
292
 	struct ftp_request *ftp = tcp_to_ftp_data ( conn );
307
 	struct ftp_request *ftp = tcp_to_ftp_data ( conn );
308
+	
309
+	/* If there was an error, close control channel and record status */
310
+	if ( status ) {
311
+		ftp_set_status ( ftp, status );
312
+		tcp_close ( &ftp->tcp );
313
+	}
293
 
314
 
294
-	if ( status )
295
-		ftp_done ( ftp, status );
315
+	/* Mark FTP operation as complete if we are the last
316
+	 * connection to close
317
+	 */
318
+	if ( tcp_closed ( &ftp->tcp ) )
319
+		ftp_done ( ftp );
296
 }
320
 }
297
 
321
 
298
 /**
322
 /**
333
 	ftp->tcp_data.tcp_op = &ftp_data_tcp_operations;
357
 	ftp->tcp_data.tcp_op = &ftp_data_tcp_operations;
334
 	ftp->recvbuf = ftp->status_text;
358
 	ftp->recvbuf = ftp->status_text;
335
 	ftp->recvsize = sizeof ( ftp->status_text ) - 1;
359
 	ftp->recvsize = sizeof ( ftp->status_text ) - 1;
360
+	ftp_clear_status ( ftp );
336
 	tcp_connect ( &ftp->tcp );
361
 	tcp_connect ( &ftp->tcp );
337
 	return &ftp->aop;
362
 	return &ftp->aop;
338
 }
363
 }

+ 47
- 7
src/tests/dhcptest.c Zobrazit soubor

14
 	return test_aoeboot ( netdev, aoename, drivenum );
14
 	return test_aoeboot ( netdev, aoename, drivenum );
15
 }
15
 }
16
 
16
 
17
-static int test_dhcp_iscsi_boot ( struct net_device *netdev, char *iscsiname ) {
18
-	char *initiator_iqn = "iqn.1900-01.localdomain.localhost:initiator";
17
+static int test_dhcp_iscsi_boot ( struct net_device *netdev,
18
+				  char *iscsiname ) {
19
+	char initiator_iqn_buf[32];
20
+	char *initiator_iqn = initiator_iqn_buf;
19
 	char username[32];
21
 	char username[32];
20
 	char password[32];
22
 	char password[32];
21
 	char *target_iqn;
23
 	char *target_iqn;
24
 		struct sockaddr_tcpip st;
26
 		struct sockaddr_tcpip st;
25
 	} target;
27
 	} target;
26
 	unsigned int drivenum;
28
 	unsigned int drivenum;
29
+	struct dhcp_option *option;
27
 	
30
 	
28
 	memset ( &target, 0, sizeof ( target ) );
31
 	memset ( &target, 0, sizeof ( target ) );
29
 	target.sin.sin_family = AF_INET;
32
 	target.sin.sin_family = AF_INET;
36
 	}
39
 	}
37
 	inet_aton ( iscsiname, &target.sin.sin_addr );
40
 	inet_aton ( iscsiname, &target.sin.sin_addr );
38
 
41
 
42
+	dhcp_snprintf ( initiator_iqn, sizeof ( initiator_iqn ),
43
+			find_global_dhcp_option ( DHCP_ISCSI_INITIATOR_IQN ) );
44
+	if ( ! *initiator_iqn )
45
+		initiator_iqn = "iqn.1900-01.localdomain.localhost:initiator";
39
 	dhcp_snprintf ( username, sizeof ( username ),
46
 	dhcp_snprintf ( username, sizeof ( username ),
40
 			find_global_dhcp_option ( DHCP_EB_USERNAME ) );
47
 			find_global_dhcp_option ( DHCP_EB_USERNAME ) );
41
 	dhcp_snprintf ( password, sizeof ( password ),
48
 	dhcp_snprintf ( password, sizeof ( password ),
89
 	return 0;
96
 	return 0;
90
 }
97
 }
91
 
98
 
99
+static int test_dhcp_ftp ( struct net_device *netdev, char *ftpname ) {
100
+	union {
101
+		struct sockaddr_in sin;
102
+		struct sockaddr_tcpip st;
103
+	} target;
104
+	char *filename;
105
+
106
+	filename = strchr ( ftpname, ':' );
107
+	if ( ! filename ) {
108
+		printf ( "Invalid FTP path \"%s\"\n", ftpname );
109
+		return -EINVAL;
110
+	}
111
+	*filename++ = '\0';
112
+
113
+	memset ( &target, 0, sizeof ( target ) );
114
+	target.sin.sin_family = AF_INET;
115
+	target.sin.sin_port = htons ( 21 );
116
+	inet_aton ( ftpname, &target.sin.sin_addr );
117
+
118
+	test_ftp ( &target, filename );
119
+	return 0;	
120
+}
121
+
92
 static int test_dhcp_tftp ( struct net_device *netdev, char *tftpname ) {
122
 static int test_dhcp_tftp ( struct net_device *netdev, char *tftpname ) {
93
 	union {
123
 	union {
94
 		struct sockaddr_in sin;
124
 		struct sockaddr_in sin;
105
 }
135
 }
106
 
136
 
107
 static int test_dhcp_boot ( struct net_device *netdev, char *filename ) {
137
 static int test_dhcp_boot ( struct net_device *netdev, char *filename ) {
138
+	/*
108
 	if ( strncmp ( filename, "aoe:", 4 ) == 0 ) {
139
 	if ( strncmp ( filename, "aoe:", 4 ) == 0 ) {
109
 		return test_dhcp_aoe_boot ( netdev, &filename[4] );
140
 		return test_dhcp_aoe_boot ( netdev, &filename[4] );
110
-	} else if ( strncmp ( filename, "iscsi:", 6 ) == 0 ) {
141
+	} 
142
+	*/
143
+	if ( strncmp ( filename, "iscsi:", 6 ) == 0 ) {
111
 		return test_dhcp_iscsi_boot ( netdev, &filename[6] );
144
 		return test_dhcp_iscsi_boot ( netdev, &filename[6] );
112
-	} else if ( strncmp ( filename, "hello:", 6 ) == 0 ) {
145
+	}
146
+	if ( strncmp ( filename, "ftp:", 4 ) == 0 ) {
147
+		return test_dhcp_ftp ( netdev, &filename[4] );
148
+	}
149
+	/*
150
+	if ( strncmp ( filename, "hello:", 6 ) == 0 ) {
113
 		return test_dhcp_hello ( &filename[6] );
151
 		return test_dhcp_hello ( &filename[6] );
114
-	} else if ( strncmp ( filename, "http:", 5 ) == 0 ) {
152
+	}
153
+	if ( strncmp ( filename, "http:", 5 ) == 0 ) {
115
 		return test_dhcp_http ( netdev, filename );
154
 		return test_dhcp_http ( netdev, filename );
116
-	} else {
117
-		return test_dhcp_tftp ( netdev, filename );
118
 	}
155
 	}
156
+	return test_dhcp_tftp ( netdev, filename );
157
+	*/
158
+	return -EPROTONOSUPPORT;
119
 }
159
 }
120
 
160
 
121
 int test_dhcp ( struct net_device *netdev ) {
161
 int test_dhcp ( struct net_device *netdev ) {

+ 3
- 4
src/tests/ftptest.c Zobrazit soubor

22
 	}
22
 	}
23
 }
23
 }
24
 
24
 
25
-void test_ftp ( struct in_addr server, const char *filename ) {
25
+void test_ftp ( struct sockaddr_tcpip *server, const char *filename ) {
26
 	struct ftp_request ftp;
26
 	struct ftp_request ftp;
27
 	int rc;
27
 	int rc;
28
 
28
 
29
-	printf ( "FTP fetching %s:%s\n", inet_ntoa ( server ), filename );
29
+	printf ( "FTP fetching %s\n", filename );
30
 	
30
 	
31
 	memset ( &ftp, 0, sizeof ( ftp ) );
31
 	memset ( &ftp, 0, sizeof ( ftp ) );
32
-	ftp.tcp.sin.sin_addr.s_addr = server.s_addr;
33
-	ftp.tcp.sin.sin_port = htons ( FTP_PORT );
32
+	memcpy ( &ftp.tcp.peer, server, sizeof ( ftp.tcp.peer ) );
34
 	ftp.filename = filename;
33
 	ftp.filename = filename;
35
 	ftp.callback = test_ftp_callback;
34
 	ftp.callback = test_ftp_callback;
36
 
35
 

Načítá se…
Zrušit
Uložit