Use bootp packet to set prefix and card address.
This commit is contained in:
parent
6d5c2ed68a
commit
59b361a2df
4 changed files with 77 additions and 38 deletions
|
@ -31,6 +31,8 @@
|
||||||
#include <grub/ieee1275/console.h>
|
#include <grub/ieee1275/console.h>
|
||||||
#include <grub/ieee1275/ofdisk.h>
|
#include <grub/ieee1275/ofdisk.h>
|
||||||
#include <grub/ieee1275/ieee1275.h>
|
#include <grub/ieee1275/ieee1275.h>
|
||||||
|
#include <grub/ieee1275/ofnet.h>
|
||||||
|
#include <grub/net.h>
|
||||||
#include <grub/offsets.h>
|
#include <grub/offsets.h>
|
||||||
#include <grub/memory.h>
|
#include <grub/memory.h>
|
||||||
|
|
||||||
|
@ -74,6 +76,21 @@ grub_machine_set_prefix (void)
|
||||||
char bootpath[64]; /* XXX check length */
|
char bootpath[64]; /* XXX check length */
|
||||||
char *filename;
|
char *filename;
|
||||||
char *prefix;
|
char *prefix;
|
||||||
|
grub_bootp_t bootp_pckt;
|
||||||
|
char addr[GRUB_NET_MAX_STR_ADDR_LEN];
|
||||||
|
|
||||||
|
/* Set the net prefix when possible. */
|
||||||
|
if (grub_getbootp && (bootp_pckt = grub_getbootp()))
|
||||||
|
{
|
||||||
|
grub_uint32_t n = bootp_pckt->siaddr;
|
||||||
|
grub_snprintf (addr, GRUB_NET_MAX_STR_ADDR_LEN, "%d.%d.%d.%d",
|
||||||
|
((n >> 24) & 0xff), ((n >> 16) & 0xff),
|
||||||
|
((n >> 8) & 0xff), ((n >> 0) & 0xff));
|
||||||
|
prefix = grub_xasprintf ("(tftp,%s)%s", addr,grub_prefix);
|
||||||
|
grub_env_set ("prefix", prefix);
|
||||||
|
grub_free (prefix);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (grub_prefix[0])
|
if (grub_prefix[0])
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <grub/net/disknet.h>
|
#include <grub/net/disknet.h>
|
||||||
#include <grub/net/tftp.h>
|
#include <grub/net/tftp.h>
|
||||||
|
|
||||||
|
grub_bootp_t (*grub_getbootp) (void);
|
||||||
enum grub_ieee1275_parse_type
|
enum grub_ieee1275_parse_type
|
||||||
{
|
{
|
||||||
GRUB_PARSE_FILENAME,
|
GRUB_PARSE_FILENAME,
|
||||||
|
|
|
@ -78,12 +78,11 @@ bootp_response_properties[] =
|
||||||
{ .name = "bootpreply-packet", .offset = 0x2a },
|
{ .name = "bootpreply-packet", .offset = 0x2a },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static grub_bootp_t
|
||||||
grub_bootp_t
|
grub_getbootp_real ( void )
|
||||||
grub_getbootp( void )
|
|
||||||
{
|
{
|
||||||
grub_bootp_t packet = grub_malloc(sizeof *packet);
|
grub_bootp_t packet = grub_malloc (sizeof *packet);
|
||||||
void *bootp_response = NULL;
|
char *bootp_response;
|
||||||
grub_ssize_t size;
|
grub_ssize_t size;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -94,30 +93,27 @@ grub_getbootp( void )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
{
|
|
||||||
grub_printf("Error to get bootp\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
|
bootp_response = grub_malloc (size);
|
||||||
if (grub_ieee1275_get_property (grub_ieee1275_chosen,
|
if (grub_ieee1275_get_property (grub_ieee1275_chosen,
|
||||||
bootp_response_properties[i].name,
|
bootp_response_properties[i].name,
|
||||||
bootp_response ,
|
bootp_response ,
|
||||||
size, 0) < 0)
|
size, 0) < 0)
|
||||||
{
|
|
||||||
grub_printf("Error to get bootp\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
packet = (void *) ((int)bootp_response
|
grub_memcpy (packet, bootp_response + bootp_response_properties[i].offset, sizeof (*packet));
|
||||||
+ bootp_response_properties[i].offset);
|
grub_free (bootp_response);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
void grub_ofnet_findcards (void)
|
void grub_ofnet_findcards (void)
|
||||||
{
|
{
|
||||||
struct grub_net_card *card;
|
struct grub_net_card *card;
|
||||||
|
grub_ieee1275_phandle_t devhandle;
|
||||||
|
grub_net_link_level_address_t lla;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
auto int search_net_devices (struct grub_ieee1275_devalias *alias);
|
auto int search_net_devices (struct grub_ieee1275_devalias *alias);
|
||||||
|
|
||||||
int search_net_devices (struct grub_ieee1275_devalias *alias)
|
int search_net_devices (struct grub_ieee1275_devalias *alias)
|
||||||
|
@ -128,53 +124,82 @@ void grub_ofnet_findcards (void)
|
||||||
card = grub_malloc (sizeof (struct grub_net_card));
|
card = grub_malloc (sizeof (struct grub_net_card));
|
||||||
struct grub_ofnetcard_data *ofdata = grub_malloc (sizeof (struct grub_ofnetcard_data));
|
struct grub_ofnetcard_data *ofdata = grub_malloc (sizeof (struct grub_ofnetcard_data));
|
||||||
ofdata->path = grub_strdup (alias->path);
|
ofdata->path = grub_strdup (alias->path);
|
||||||
|
|
||||||
|
grub_ieee1275_finddevice (ofdata->path, &devhandle);
|
||||||
|
|
||||||
|
if (grub_ieee1275_get_integer_property
|
||||||
|
(devhandle, "max-frame-size", &(ofdata->mtu), sizeof (ofdata->mtu), 0))
|
||||||
|
return grub_error (GRUB_ERR_IO, "Couldn't retrieve mtu size.");
|
||||||
|
|
||||||
|
if (grub_ieee1275_get_property (devhandle, "mac-address", &(lla.mac), 6, 0))
|
||||||
|
return grub_error (GRUB_ERR_IO, "Couldn't retrieve mac address.");
|
||||||
|
|
||||||
|
lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
||||||
|
card->default_address = lla;
|
||||||
|
|
||||||
card->data = ofdata;
|
card->data = ofdata;
|
||||||
|
card->flags = 0;
|
||||||
card->name = grub_xasprintf("eth%d",i++); // grub_strdup (alias->name);
|
card->name = grub_xasprintf("eth%d",i++); // grub_strdup (alias->name);
|
||||||
grub_net_card_register (card);
|
grub_net_card_register (card);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Look at all nodes for devices of the type network*/
|
/* Look at all nodes for devices of the type network. */
|
||||||
grub_ieee1275_devices_iterate (search_net_devices);
|
grub_ieee1275_devices_iterate (search_net_devices);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
void grub_ofnet_probecards (void)
|
void grub_ofnet_probecards (void)
|
||||||
{
|
{
|
||||||
struct grub_net_card *card;
|
struct grub_net_card *card;
|
||||||
struct grub_net_card_driver *driver;
|
struct grub_net_card_driver *driver;
|
||||||
|
struct grub_net_network_level_interface *inter;
|
||||||
|
grub_bootp_t bootp_pckt;
|
||||||
|
grub_net_network_level_address_t addr;
|
||||||
|
grub_net_network_level_netaddress_t net;
|
||||||
|
|
||||||
/*Assign correspondent driver for each device. */
|
/* Assign correspondent driver for each device. */
|
||||||
FOR_NET_CARDS (card)
|
FOR_NET_CARDS (card)
|
||||||
{
|
{
|
||||||
FOR_NET_CARD_DRIVERS (driver)
|
FOR_NET_CARD_DRIVERS (driver)
|
||||||
{
|
{
|
||||||
if (driver->init(card) == GRUB_ERR_NONE)
|
if (driver->init(card) == GRUB_ERR_NONE)
|
||||||
{
|
{
|
||||||
card->driver = driver;
|
card->driver = driver;
|
||||||
continue;
|
bootp_pckt = grub_getbootp ();
|
||||||
}
|
if (bootp_pckt)
|
||||||
|
{
|
||||||
|
addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
|
||||||
|
addr.ipv4 = bootp_pckt->yiaddr;
|
||||||
|
grub_net_add_addr ("bootp_cli_addr", card, addr, card->default_address, 0);
|
||||||
|
FOR_NET_NETWORK_LEVEL_INTERFACES (inter)
|
||||||
|
if (grub_strcmp (inter->name, "bootp_cli_addr") == 0)
|
||||||
|
break;
|
||||||
|
net.type = addr.type;
|
||||||
|
net.ipv4.base = addr.ipv4;
|
||||||
|
net.ipv4.masksize = 24;
|
||||||
|
grub_net_add_route ("bootp-router", net, inter);
|
||||||
|
}
|
||||||
|
grub_free (bootp_pckt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_MOD_INIT(ofnet)
|
GRUB_MOD_INIT (ofnet)
|
||||||
{
|
{
|
||||||
|
grub_getbootp = grub_getbootp_real;
|
||||||
grub_net_card_driver_register (&ofdriver);
|
grub_net_card_driver_register (&ofdriver);
|
||||||
grub_ofnet_findcards();
|
grub_ofnet_findcards ();
|
||||||
grub_ofnet_probecards();
|
grub_ofnet_probecards ();
|
||||||
|
|
||||||
/*init tftp stack - will be handled by module subsystem in the future*/
|
|
||||||
tftp_ini ();
|
|
||||||
/*get bootp packet - won't be needed in the future*/
|
|
||||||
bootp_pckt = grub_getbootp ();
|
|
||||||
grub_disknet_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_MODE_FINI(ofnet)
|
GRUB_MOD_FINI (ofnet)
|
||||||
{
|
{
|
||||||
grub_net_card_driver_unregister (&ofdriver);
|
grub_net_card_driver_unregister (&ofdriver);
|
||||||
|
grub_getbootp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -60,14 +60,10 @@ struct grub_bootp {
|
||||||
unsigned char chaddr [16]; /* Client hardware address */
|
unsigned char chaddr [16]; /* Client hardware address */
|
||||||
char sname [64]; /* Server name */
|
char sname [64]; /* Server name */
|
||||||
char file [128]; /* Boot filename */
|
char file [128]; /* Boot filename */
|
||||||
// grub_uint32_t filesize ; /*File size (testing)*/
|
|
||||||
unsigned char vend [64];
|
unsigned char vend [64];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct grub_bootp* grub_bootp_t;
|
typedef struct grub_bootp* grub_bootp_t;
|
||||||
|
|
||||||
char * grub_get_filestr(const char * );
|
extern grub_bootp_t (*EXPORT_VAR (grub_getbootp)) (void);
|
||||||
char * grub_ip2str (grub_uint32_t ip);
|
|
||||||
void grub_get_netinfo (grub_ofnet_t netinfo,grub_bootp_t packet);
|
|
||||||
grub_bootp_t grub_getbootp (void);
|
|
||||||
#endif /* ! GRUB_NET_HEADER */
|
#endif /* ! GRUB_NET_HEADER */
|
||||||
|
|
Loading…
Reference in a new issue