Browse Source

Updated to protocol API

tags/v0.9.3
Michael Brown 19 years ago
parent
commit
5c2e5557f0
1 changed files with 65 additions and 70 deletions
  1. 65
    70
      src/proto/tftm.c

+ 65
- 70
src/proto/tftm.c View File

@@ -35,24 +35,17 @@
35 35
 *    Indent Options: indent -kr -i8
36 36
 ***************************************************************************/
37 37
 
38
-#ifdef DOWNLOAD_PROTO_TFTM
39 38
 #include "etherboot.h"
39
+#include "proto.h"
40 40
 #include "nic.h"
41 41
 
42
-//#define TFTM_DEBUG
43
-#ifdef TFTM_DEBUG
44
-#define debug(x) printf x
45
-#else
46
-#define debug(x)
47
-#endif
48 42
 struct tftm_info {
49
-	in_addr server_ip;
50
-	in_addr multicast_ip;
51
-	in_addr local_ip;
52
-	uint16_t server_port;
53
-	uint16_t multicast_port;
54
-	uint16_t local_port;
55
-	int (*fnc) (unsigned char *, unsigned int, unsigned int, int);
43
+	struct sockaddr_in server;
44
+	struct sockaddr_in local;
45
+	struct sockaddr_in multicast;
46
+	int ( * process ) ( unsigned char *data,
47
+			    unsigned int blocknum,
48
+			    unsigned int len, int eof );
56 49
 	int sent_nack;
57 50
 	const char *name;	/* Filename */
58 51
 };
@@ -72,11 +65,12 @@ struct tftm_state {
72 65
 #define TFTM_MIN_PACKET 1024
73 66
 
74 67
 
75
-int opt_get_multicast(struct tftp_t *tr, unsigned short *len,
76
-		      unsigned long *filesize, struct tftm_info *info);
68
+static int opt_get_multicast(struct tftp_t *tr, unsigned short *len,
69
+			     unsigned long *filesize, struct tftm_info *info);
77 70
 
78 71
 static int await_tftm(int ival, void *ptr, unsigned short ptype __unused,
79
-		      struct iphdr *ip, struct udphdr *udp)
72
+		      struct iphdr *ip, struct udphdr *udp,
73
+		      struct tcphdr *tcp __unused)
80 74
 {
81 75
 	struct tftm_info *info = ptr;
82 76
 
@@ -94,8 +88,8 @@ static int await_tftm(int ival, void *ptr, unsigned short ptype __unused,
94 88
 	}
95 89
 
96 90
 	/* Also check for Multicast data being received */
97
-	if ((ip->dest.s_addr == info->multicast_ip.s_addr) &&
98
-	    (ntohs(udp->dest) == info->multicast_port) &&
91
+	if ((ip->dest.s_addr == info->multicast.sin_addr.s_addr) &&
92
+	    (ntohs(udp->dest) == info->multicast.sin_port) &&
99 93
 	    (nic.packetlen >= ETH_HLEN + sizeof(struct iphdr) +
100 94
 	     sizeof(struct udphdr))) {
101 95
 		return 1;	/* Multicast data received */
@@ -103,7 +97,7 @@ static int await_tftm(int ival, void *ptr, unsigned short ptype __unused,
103 97
 	return 0;
104 98
 }
105 99
 
106
-int proto_tftm(struct tftm_info *info)
100
+static int proto_tftm(struct tftm_info *info)
107 101
 {
108 102
 	int retry = 0;
109 103
 	static unsigned short iport = 2000;
@@ -129,8 +123,8 @@ int proto_tftm(struct tftm_info *info)
129 123
 		    "%s%coctet%cmulticast%c%cblksize%c%d%ctsize%c",
130 124
 		    info->name, 0, 0, 0, 0, 0, TFTM_MIN_PACKET, 0, 0) + 1;
131 125
 
132
-	if (!udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr, ++iport,
133
-			  TFTM_PORT, len, &tp))
126
+	if (!udp_transmit(info->server.sin_addr.s_addr, ++iport,
127
+			  info->server.sin_port, len, &tp))
134 128
 		return (0);
135 129
 
136 130
 	/* loop to listen for packets and to receive the file */
@@ -148,17 +142,14 @@ int proto_tftm(struct tftm_info *info)
148 142
 		if (!await_reply(await_tftm, iport, info, timeout)) {
149 143
 			if (!block && retry++ < MAX_TFTP_RETRIES) {	/* maybe initial request was lost */
150 144
 				if (!udp_transmit
151
-				    (arptable[ARP_SERVER].ipaddr.s_addr,
152
-				     ++iport, TFTM_PORT, len, &tp))
145
+				    (info->server.sin_addr.s_addr, ++iport,
146
+				     info->server.sin_port, len, &tp))
153 147
 					return (0);
154 148
 				continue;
155 149
 			}
156 150
 #ifdef	CONGESTED
157 151
 			if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT)) {	/* we resend our last ack */
158
-#ifdef	MDEBUG
159
-				printf("<REXMT>\n");
160
-#endif
161
-				debug(("Timed out receiving file"));
152
+				DBG("Timed out receiving file");
162 153
 				len =
163 154
 				    sizeof(tp.ip) + sizeof(tp.udp) +
164 155
 				    sizeof(tp.opcode) +
@@ -168,8 +159,9 @@ int proto_tftm(struct tftm_info *info)
168 159
 					    TFTM_MIN_PACKET, 0, 0) + 1;
169 160
 
170 161
 				udp_transmit
171
-				    (arptable[ARP_SERVER].ipaddr.s_addr,
172
-				     ++iport, TFTM_PORT, len, &tp);
162
+					(info->server.sin_addr.s_addr,
163
+					 ++iport, info->server.sin_port,
164
+					 len, &tp);
173 165
 					continue;
174 166
 			}
175 167
 #endif
@@ -209,9 +201,9 @@ int proto_tftm(struct tftm_info *info)
209 201
 				     */
210 202
 				    sprintf((char *) tp.u.err.errmsg,
211 203
 					    "RFC2090 error") + 1;
212
-				udp_transmit(arptable[ARP_SERVER].ipaddr.
213
-					     s_addr, iport,
214
-					     ntohs(tr->udp.src), len, &tp);
204
+				udp_transmit(info->server.sin_addr.s_addr,
205
+					     iport, ntohs(tr->udp.src),
206
+					     len, &tp);
215 207
 				block = tp.u.ack.block = 0;	/* this ensures, that */
216 208
 				/* the packet does not get */
217 209
 				/* processed as data! */
@@ -245,8 +237,7 @@ int proto_tftm(struct tftm_info *info)
245 237
 					}
246 238
 					/* If I'm running over multicast join the multicast group */
247 239
 					join_group(IGMP_SERVER,
248
-						   info->multicast_ip.
249
-						   s_addr);
240
+					      info->multicast.sin_addr.s_addr);
250 241
 				}
251 242
 				state.recvd_oack = 1;
252 243
 			}
@@ -353,7 +344,8 @@ int proto_tftm(struct tftm_info *info)
353 344
 		if (state.ismaster) {
354 345
 			tp.opcode = htons(TFTP_ACK);
355 346
 			oport = ntohs(tr->udp.src);
356
-			udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr, iport, oport, TFTP_MIN_PACKET, &tp);	/* ack */
347
+			udp_transmit(info->server.sin_addr.s_addr, iport,
348
+				     oport, TFTP_MIN_PACKET, &tp); /* ack */
357 349
 		}
358 350
 		if (state.received_packets == state.total_packets) {
359 351
 			/* If the client is finished and not the master,
@@ -363,7 +355,9 @@ int proto_tftm(struct tftm_info *info)
363 355
 				/* Ack Last packet to end xfer */
364 356
 				tp.u.ack.block = htons(state.total_packets);
365 357
 				oport = ntohs(tr->udp.src);
366
-				udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr, iport, oport, TFTP_MIN_PACKET, &tp);	/* ack */
358
+				udp_transmit(info->server.sin_addr.s_addr,
359
+					     iport, oport,
360
+					     TFTP_MIN_PACKET, &tp); /* ack */
367 361
 			}
368 362
 			/* We are done get out */
369 363
 			forget(state.bitmap);
@@ -382,26 +376,29 @@ int proto_tftm(struct tftm_info *info)
382 376
 	}
383 377
 	/* Leave the multicast group */
384 378
 	leave_group(IGMP_SERVER);
385
-	return info->fnc(state.image, 1, filesize, 1);
379
+	return info->process(state.image, 1, filesize, 1);
386 380
 }
387 381
 
388
-int url_tftm(const char *name,
389
-	     int (*fnc) (unsigned char *, unsigned int, unsigned int, int))
390
-{
382
+static int url_tftm ( char *url __unused,
383
+		      struct sockaddr_in *server,
384
+		      char *file,
385
+		      int ( * process ) ( unsigned char *data,
386
+					  unsigned int blocknum,
387
+					  unsigned int len, int eof ) ) {
391 388
 
392 389
 	int ret;
393 390
 	struct tftm_info info;
394 391
 
395 392
 	/* Set the defaults */
396
-	info.server_ip.s_addr = arptable[ARP_SERVER].ipaddr.s_addr;
397
-	info.server_port = TFTM_PORT;
398
-	info.local_ip.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
399
-	info.local_port = TFTM_PORT;	/* Does not matter. So take tftm port too. */
400
-	info.multicast_ip.s_addr = info.local_ip.s_addr;
401
-	info.multicast_port = TFTM_PORT;
402
-	info.fnc = fnc;
393
+	info.server = *server;
394
+	if ( ! info.server.sin_port )
395
+		info.server.sin_port = TFTM_PORT;
396
+	info.local.sin_addr.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
397
+	info.local.sin_port = TFTM_PORT; /* Does not matter. */
398
+	info.multicast = info.local;
399
+	info.process = process;
403 400
 	state.ismaster = 0;
404
-	info.name = name;
401
+	info.name = file;
405 402
 
406 403
 	state.block_size = 0;
407 404
 	state.total_bytes = 0;
@@ -411,13 +408,8 @@ int url_tftm(const char *name,
411 408
 	state.bitmap = 0;
412 409
 	state.recvd_oack = 0;
413 410
 
414
-	if (name[0] != '/') {
415
-		/* server ip given, so use it */
416
-		name += inet_aton(info.name, &info.server_ip);
417
-		/* No way to specify another port for now */
418
-	}
419
-	if (name[0] != '/') {
420
-		printf("Bad tftm-URI: [%s]\n", info.name);
411
+	if (file[0] != '/') {
412
+		printf("Bad tftm-URI: [%s]\n", file);
421 413
 		return 0;
422 414
 	}
423 415
 
@@ -429,8 +421,8 @@ int url_tftm(const char *name,
429 421
 /******************************
430 422
 * Parse the multicast options
431 423
 *******************************/
432
-int opt_get_multicast(struct tftp_t *tr, unsigned short *len,
433
-		      unsigned long *filesize, struct tftm_info *info)
424
+static int opt_get_multicast(struct tftp_t *tr, unsigned short *len,
425
+			     unsigned long *filesize, struct tftm_info *info)
434 426
 {
435 427
 	const char *p = tr->u.oack.data, *e = 0;
436 428
 	int i = 0;
@@ -444,8 +436,8 @@ int opt_get_multicast(struct tftp_t *tr, unsigned short *len,
444 436
 			p += 6;
445 437
 			if ((*filesize = strtoul(p, &p, 10)) > 0)
446 438
 				i |= 4;
447
-			debug(("\n"));
448
-			debug(("tsize=%d\n", *filesize));
439
+			DBG("\n");
440
+			DBG("tsize=%d\n", *filesize);
449 441
 			while (p < e && *p)
450 442
 				p++;
451 443
 			if (p < e)
@@ -460,7 +452,7 @@ int opt_get_multicast(struct tftp_t *tr, unsigned short *len,
460 452
 				     TFTM_MIN_PACKET);
461 453
 				return 0;
462 454
 			}
463
-			debug(("blksize=%d\n", state.block_size));
455
+			DBG("blksize=%d\n", state.block_size);
464 456
 			while (p < e && *p)
465 457
 				p++;
466 458
 			if (p < e)
@@ -468,16 +460,16 @@ int opt_get_multicast(struct tftp_t *tr, unsigned short *len,
468 460
 		} else if (!strncmp(p, "multicast", 10)) {
469 461
 			i |= 1;
470 462
 			p += 10;
471
-			debug(("multicast options: %s\n", p));
472
-			p += 1 + inet_aton(p, &info->multicast_ip);
473
-			debug(("multicast ip = %@\n", info->multicast_ip));
474
-			info->multicast_port = strtoul(p, &p, 10);
463
+			DBG("multicast options: %s\n", p);
464
+			p += 1 + inet_aton(p, &info->multicast.sin_addr);
465
+			DBG("multicast ip = %@\n", info->multicast_ip);
466
+			info->multicast.sin_port = strtoul(p, &p, 10);
475 467
 			++p;
476
-			debug(("multicast port = %d\n",
477
-			       info->multicast_port));
468
+			DBG("multicast port = %d\n",
469
+			    info->multicast.sin_port);
478 470
 			state.ismaster = (*p == '1' ? 1 : 0);
479
-			debug(("multicast ismaster = %d\n",
480
-			       state.ismaster));
471
+			DBG("multicast ismaster = %d\n",
472
+			       state.ismaster);
481 473
 			while (p < e && *p)
482 474
 				p++;
483 475
 			if (p < e)
@@ -488,4 +480,7 @@ int opt_get_multicast(struct tftp_t *tr, unsigned short *len,
488 480
 		return 0;
489 481
 	return i;
490 482
 }
491
-#endif				/* DOWNLOAD_PROTO_TFTP */
483
+
484
+static struct protocol tftm_protocol __protocol = {
485
+	"tftm", url_tftm
486
+};

Loading…
Cancel
Save