david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

Updated to protocol API

This commit is contained in:
Michael Brown 2005-05-01 15:36:39 +00:00
parent 5c2e5557f0
commit 6afffc0771
1 changed files with 38 additions and 43 deletions

View File

@ -1,5 +1,5 @@
#ifdef DOWNLOAD_PROTO_SLAM
#include "etherboot.h" #include "etherboot.h"
#include "proto.h"
#include "nic.h" #include "nic.h"
#define SLAM_PORT 10000 #define SLAM_PORT 10000
@ -101,13 +101,12 @@ static void init_slam_state(void)
} }
struct slam_info { struct slam_info {
in_addr server_ip; struct sockaddr_in server;
in_addr multicast_ip; struct sockaddr_in local;
in_addr local_ip; struct sockaddr_in multicast;
uint16_t server_port; int ( * process ) ( unsigned char *data,
uint16_t multicast_port; unsigned int blocknum,
uint16_t local_port; unsigned int len, int eof );
int (*fnc)(unsigned char *, unsigned int, unsigned int, int);
int sent_nack; int sent_nack;
}; };
@ -115,7 +114,8 @@ struct slam_info {
#define SLAM_REQUEST 1 #define SLAM_REQUEST 1
#define SLAM_DATA 2 #define SLAM_DATA 2
static int await_slam(int ival __unused, void *ptr, static int await_slam(int ival __unused, void *ptr,
unsigned short ptype __unused, struct iphdr *ip, struct udphdr *udp) unsigned short ptype __unused, struct iphdr *ip,
struct udphdr *udp, struct tcphdr *tcp __unused)
{ {
struct slam_info *info = ptr; struct slam_info *info = ptr;
if (!udp) { if (!udp) {
@ -126,7 +126,7 @@ static int await_slam(int ival __unused, void *ptr,
*/ */
/* Check for a data request packet */ /* Check for a data request packet */
if ((ip->dest.s_addr == arptable[ARP_CLIENT].ipaddr.s_addr) && if ((ip->dest.s_addr == arptable[ARP_CLIENT].ipaddr.s_addr) &&
(ntohs(udp->dest) == info->local_port) && (ntohs(udp->dest) == info->local.sin_port) &&
(nic.packetlen >= (nic.packetlen >=
ETH_HLEN + ETH_HLEN +
sizeof(struct iphdr) + sizeof(struct iphdr) +
@ -135,8 +135,8 @@ static int await_slam(int ival __unused, void *ptr,
return SLAM_REQUEST; return SLAM_REQUEST;
} }
/* Check for a multicast data packet */ /* Check for a multicast data packet */
if ((ip->dest.s_addr == info->multicast_ip.s_addr) && if ((ip->dest.s_addr == info->multicast.sin_addr.s_addr) &&
(ntohs(udp->dest) == info->multicast_port) && (ntohs(udp->dest) == info->multicast.sin_port) &&
(nic.packetlen >= (nic.packetlen >=
ETH_HLEN + ETH_HLEN +
sizeof(struct iphdr) + sizeof(struct iphdr) +
@ -203,7 +203,8 @@ static int slam_skip(unsigned char **ptr, unsigned char *end)
} }
static unsigned long slam_decode(unsigned char **ptr, unsigned char *end, int *err) static unsigned long slam_decode(unsigned char **ptr, unsigned char *end,
int *err)
{ {
unsigned long value; unsigned long value;
unsigned bytes; unsigned bytes;
@ -368,8 +369,8 @@ static void transmit_nack(unsigned char *ptr, struct slam_info *info)
/* Ensure the packet is null terminated */ /* Ensure the packet is null terminated */
*ptr++ = 0; *ptr++ = 0;
nack_len = ptr - (unsigned char *)&nack; nack_len = ptr - (unsigned char *)&nack;
build_udp_hdr(info->server_ip.s_addr, build_udp_hdr(info->server.sin_addr.s_addr, info->local.sin_port,
info->local_port, info->server_port, 1, nack_len, &nack); info->server.sin_port, 1, nack_len, &nack);
ip_transmit(nack_len, &nack); ip_transmit(nack_len, &nack);
#if defined(MDEBUG) && 0 #if defined(MDEBUG) && 0
printf("Sent NACK to %@ bytes: %d have:%ld/%ld\n", printf("Sent NACK to %@ bytes: %d have:%ld/%ld\n",
@ -443,12 +444,12 @@ static int proto_slam(struct slam_info *info)
retry = -1; retry = -1;
rx_qdrain(); rx_qdrain();
/* Arp for my server */ /* Arp for my server */
if (arptable[ARP_SERVER].ipaddr.s_addr != info->server_ip.s_addr) { if (arptable[ARP_SERVER].ipaddr.s_addr != info->server.sin_addr.s_addr) {
arptable[ARP_SERVER].ipaddr.s_addr = info->server_ip.s_addr; arptable[ARP_SERVER].ipaddr.s_addr = info->server.sin_addr.s_addr;
memset(arptable[ARP_SERVER].node, 0, ETH_ALEN); memset(arptable[ARP_SERVER].node, 0, ETH_ALEN);
} }
/* If I'm running over multicast join the multicast group */ /* If I'm running over multicast join the multicast group */
join_group(IGMP_SERVER, info->multicast_ip.s_addr); join_group(IGMP_SERVER, info->multicast.sin_addr.s_addr);
for(;;) { for(;;) {
unsigned char *header; unsigned char *header;
unsigned char *data; unsigned char *data;
@ -503,39 +504,33 @@ static int proto_slam(struct slam_info *info)
leave_group(IGMP_SERVER); leave_group(IGMP_SERVER);
/* FIXME don't overwrite myself */ /* FIXME don't overwrite myself */
/* load file to correct location */ /* load file to correct location */
return info->fnc(state.image, 1, state.total_bytes, 1); return info->process(state.image, 1, state.total_bytes, 1);
} }
static int url_slam ( char *url __unused,
int url_slam(const char *name, int (*fnc)(unsigned char *, unsigned int, unsigned int, int)) struct sockaddr_in *server,
{ char *file,
int ( * process ) ( unsigned char *data,
unsigned int blocknum,
unsigned int len, int eof ) ) {
struct slam_info info; struct slam_info info;
/* Set the defaults */ /* Set the defaults */
info.server_ip.s_addr = arptable[ARP_SERVER].ipaddr.s_addr; info.server = *server;
info.server_port = SLAM_PORT; if ( ! info.server.sin_port )
info.multicast_ip.s_addr = htonl(SLAM_MULTICAST_IP); info.server.sin_port = SLAM_PORT;
info.multicast_port = SLAM_MULTICAST_PORT; info.multicast.sin_addr.s_addr = htonl(SLAM_MULTICAST_IP);
info.local_ip.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr; info.multicast.sin_port = SLAM_MULTICAST_PORT;
info.local_port = SLAM_LOCAL_PORT; info.local.sin_addr.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
info.fnc = fnc; info.local.sin_port = SLAM_LOCAL_PORT;
info.process = process;
info.sent_nack = 0; info.sent_nack = 0;
/* Now parse the url */ if (file[0]) {
if (url_port != -1) {
info.server_port = url_port;
}
if (name[0]) {
/* multicast ip */
name += inet_aton(name, &info.multicast_ip);
if (name[0] == ':') {
name++;
info.multicast_port = strtoul(name, &name, 10);
}
}
if (name[0]) {
printf("\nBad url\n"); printf("\nBad url\n");
return 0; return 0;
} }
return proto_slam(&info); return proto_slam(&info);
} }
#endif /* DOWNLOAD_PROTO_SLAM */ static struct protocol slam_protocol __protocol = {
"slam", url_slam
};