#include <grub/mm.h>
#include <grub/dl.h>
#include <grub/command.h>
+#include <grub/env.h>
struct grub_net_route
{
struct grub_net_card *grub_net_cards = NULL;
struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL;
-static inline void
-grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter)
-{
- grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces),
- GRUB_AS_LIST (inter));
-}
-
static inline void
grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter)
{
if (inter == NULL)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found"));
+ if (inter->flags & GRUB_NET_INTERFACE_PERMANENT)
+ return grub_error (GRUB_ERR_IO,
+ N_("you can't delete this address"));
+
grub_net_network_level_interface_unregister (inter);
grub_free (inter->name);
grub_free (inter);
return GRUB_ERR_NONE;
}
+/*
+ Currently suppoerted adresses:
+ IPv4: XXX.XXX.XXX.XXX
+ */
+#define MAX_STR_ADDR_LEN sizeof ("XXX.XXX.XXX.XXX")
+
+static void
+addr_to_str (const grub_net_network_level_address_t *target, char *buf)
+{
+ switch (target->type)
+ {
+ case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4:
+ {
+ grub_uint32_t n = grub_be_to_cpu32 (target->ipv4);
+ grub_snprintf (buf, MAX_STR_ADDR_LEN, "%d.%d.%d.%d",
+ ((n >> 24) & 0xff), ((n >> 16) & 0xff),
+ ((n >> 8) & 0xff), ((n >> 0) & 0xff));
+ }
+ return;
+ }
+ grub_printf ("Unknown address type %d\n", target->type);
+}
+
+/*
+ Currently suppoerted adresses:
+ ethernet: XX:XX:XX:XX:XX:XX
+ */
+
+#define MAX_STR_HWADDR_LEN (sizeof ("XX:XX:XX:XX:XX:XX"))
+
+static void
+hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str)
+{
+ str[0] = 0;
+ switch (addr->type)
+ {
+ case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET:
+ {
+ char *ptr;
+ unsigned i;
+ for (ptr = str, i = 0; i < ARRAY_SIZE (addr->mac); i++)
+ {
+ grub_snprintf (ptr, MAX_STR_HWADDR_LEN - (ptr - str),
+ "%02x:", addr->mac[i] & 0xff);
+ ptr += (sizeof ("XX:") - 1);
+ }
+ return;
+ }
+ }
+ grub_printf ("Unsupported hw address type %d\n", addr->type);
+}
+
+/* FIXME: implement this. */
+static char *
+hwaddr_set_env (struct grub_env_var *var __attribute__ ((unused)),
+ const char *val __attribute__ ((unused)))
+{
+ return NULL;
+}
+
+/* FIXME: implement this. */
+static char *
+addr_set_env (struct grub_env_var *var __attribute__ ((unused)),
+ const char *val __attribute__ ((unused)))
+{
+ return NULL;
+}
+
+static void
+grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter)
+{
+ {
+ char buf[MAX_STR_HWADDR_LEN];
+ char name[grub_strlen (inter->name) + sizeof ("net__mac")];
+ hwaddr_to_str (&inter->hwaddress, buf);
+ grub_snprintf (name, sizeof (name), "net_%s_mac", inter->name);
+ grub_env_set (name, buf);
+ grub_register_variable_hook (name, 0, hwaddr_set_env);
+ }
+
+ {
+ char buf[MAX_STR_ADDR_LEN];
+ char name[grub_strlen (inter->name) + sizeof ("net__ip")];
+ addr_to_str (&inter->address, buf);
+ grub_snprintf (name, sizeof (name), "net_%s_ip", inter->name);
+ grub_env_set (name, buf);
+ grub_register_variable_hook (name, 0, addr_set_env);
+ }
+
+ grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces),
+ GRUB_AS_LIST (inter));
+}
+
struct grub_net_network_level_interface *
grub_net_add_addr (const char *name, struct grub_net_card *card,
- grub_net_network_level_address_t addr)
+ grub_net_network_level_address_t addr,
+ grub_net_link_level_address_t hwaddress,
+ grub_net_interface_flags_t flags)
{
struct grub_net_network_level_interface *inter;
inter->name = grub_strdup (name);
grub_memcpy (&(inter->address), &addr, sizeof (inter->address));
+ grub_memcpy (&(inter->hwaddress), &hwaddress, sizeof (inter->hwaddress));
+ inter->flags = flags;
inter->card = card;
grub_net_network_level_interface_register (inter);
return inter;
}
+/* FIXME: support MAC specifying. */
static grub_err_t
grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)),
int argc, char **args)
struct grub_net_card *card;
grub_net_network_level_address_t addr;
grub_err_t err;
+ grub_net_interface_flags_t flags = 0;
if (argc != 3)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("three arguments expected"));
if (err)
return err;
- grub_net_add_addr (args[0], card, addr);
+ if (card->flags & GRUB_NET_CARD_NO_MANUAL_INTERFACES)
+ return grub_error (GRUB_ERR_IO,
+ "this card doesn't support address addition");
+
+ if (card->flags & GRUB_NET_CARD_HWADDRESS_IMMUTABLE)
+ flags |= GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE;
+
+ grub_net_add_addr (args[0], card, addr, card->default_address,
+ flags);
return grub_errno;
}
static void
print_address (const grub_net_network_level_address_t *target)
{
- switch (target->type)
- {
- case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4:
- {
- grub_uint32_t n = grub_be_to_cpu32 (target->ipv4);
- grub_printf ("%d.%d.%d.%d ", ((n >> 24) & 0xff),
- ((n >> 16) & 0xff),
- ((n >> 8) & 0xff),
- ((n >> 0) & 0xff));
- }
- return;
- }
- grub_printf ("Unknown address type %d\n", target->type);
+ char buf[MAX_STR_ADDR_LEN];
+ addr_to_str (target, buf);
+ grub_xputs (buf);
}
static grub_err_t
GRUB_MOD_INIT(net)
{
cmd_addaddr = grub_register_command ("net_add_addr", grub_cmd_addaddr,
- "SHORTNAME CARD ADDRESS",
+ "SHORTNAME CARD ADDRESS [HWADDRESS]",
N_("Add a network address."));
cmd_deladdr = grub_register_command ("net_del_addr", grub_cmd_deladdr,
"SHORTNAME",
static unsigned grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE;
static grub_file_t curr_file = 0;
+static grub_net_link_level_address_t pxe_hwaddr;
struct grub_pxe_data
{
return NULL;
}
-static void
-set_mac_env (grub_uint8_t *mac_addr, grub_size_t mac_len)
-{
- char buf[(sizeof ("XX:") - 1) * mac_len + 1];
- char *ptr = buf;
- unsigned i;
-
- for (i = 0; i < mac_len; i++)
- {
- grub_snprintf (ptr, sizeof (buf) - (ptr - buf),
- "%02x:", mac_addr[i] & 0xff);
- ptr += (sizeof ("XX:") - 1);
- }
- if (mac_len)
- *(ptr - 1) = 0;
- else
- buf[0] = 0;
-
- grub_env_set ("net_pxe_mac", buf);
- /* XXX: Is it possible to change MAC in PXE? */
- grub_register_variable_hook ("net_pxe_mac", 0, grub_env_write_readonly);
-}
-
static void
set_env_limn_ro (const char *varname, char *value, grub_size_t len)
{
grub_pxe_your_ip = bp->your_ip;
grub_pxe_default_server_ip = bp->server_ip;
grub_pxe_default_gateway_ip = bp->gateway_ip;
- set_mac_env (bp->mac_addr, bp->hw_len < sizeof (bp->mac_addr) ? bp->hw_len
- : sizeof (bp->mac_addr));
+ grub_memcpy (pxe_hwaddr.mac, bp->mac_addr,
+ bp->hw_len < sizeof (pxe_hwaddr.mac)
+ ? bp->hw_len : sizeof (pxe_hwaddr.mac));
+ pxe_hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
set_env_limn_ro ("net_pxe_boot_file", (char *) bp->boot_file,
sizeof (bp->boot_file));
set_env_limn_ro ("net_pxe_dhcp_server_name", (char *) bp->server_name,
grub_net_card_register (&grub_pxe_card);
addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
addr.ipv4 = grub_pxe_your_ip;
- inter = grub_net_add_addr ("pxe", &grub_pxe_card, addr);
+ inter = grub_net_add_addr ("pxe", &grub_pxe_card, addr, pxe_hwaddr,
+ GRUB_NET_INTERFACE_PERMANENT
+ | GRUB_NET_INTERFACE_ADDRESS_IMMUTABLE
+ | GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE);
if (grub_pxe_default_gateway_ip != grub_pxe_default_server_ip)
{
grub_net_network_level_netaddress_t target;
extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name);
+typedef enum grub_link_level_protocol_id
+{
+ GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
+} grub_link_level_protocol_id_t;
+
+typedef struct grub_net_link_level_address
+{
+ grub_link_level_protocol_id_t type;
+ union
+ {
+ grub_uint8_t mac[6];
+ };
+} grub_net_link_level_address_t;
+
+typedef enum grub_net_interface_flags
+ {
+ GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE = 1,
+ GRUB_NET_INTERFACE_ADDRESS_IMMUTABLE = 2,
+ GRUB_NET_INTERFACE_PERMANENT = 4
+ } grub_net_interface_flags_t;
+
+typedef enum grub_net_card_flags
+ {
+ GRUB_NET_CARD_HWADDRESS_IMMUTABLE = 1,
+ GRUB_NET_CARD_NO_MANUAL_INTERFACES = 2
+ } grub_net_card_flags_t;
+
struct grub_net_card;
struct grub_net_card_driver
struct grub_net_card *next;
char *name;
struct grub_net_card_driver *driver;
+ grub_net_link_level_address_t default_address;
+ grub_net_card_flags_t flags;
void *data;
};
char *name;
struct grub_net_card *card;
grub_net_network_level_address_t address;
+ grub_net_link_level_address_t hwaddress;
+ grub_net_interface_flags_t flags;
void *data;
};
struct grub_net_network_level_interface *
grub_net_add_addr (const char *name, struct grub_net_card *card,
- grub_net_network_level_address_t addr);
+ grub_net_network_level_address_t addr,
+ grub_net_link_level_address_t hwaddress,
+ grub_net_interface_flags_t flags);
extern struct grub_net_network_level_interface *grub_net_network_level_interfaces;