|
@@ -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
|
+};
|