diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 5d13d0313..1fcc3d00d 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -74,6 +74,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h if COND_i386_pc KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h diff --git a/grub-core/commands/net.c b/grub-core/commands/net.c index 288ba4c2a..904c61a92 100644 --- a/grub-core/commands/net.c +++ b/grub-core/commands/net.c @@ -269,6 +269,37 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } +grub_net_app_level_t grub_net_app_level_list; + +static grub_net_t +grub_net_open_real (const char *name) +{ + const char *comma = grub_strchr (name, ','); + grub_net_app_level_t proto; + + if (!comma) + comma = name + grub_strlen (name); + FOR_NET_APP_LEVEL (proto) + { + if (comma - name == (grub_ssize_t) grub_strlen (proto->name) + && grub_memcmp (proto->name, name, comma - name) == 0) + { + grub_net_t ret = grub_malloc (sizeof (*ret)); + if (!ret) + return NULL; + ret->protocol = proto; + ret->name = grub_strdup (name); + if (!ret->name) + { + grub_free (ret); + return NULL; + } + return ret; + } + } + return NULL; +} + static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; GRUB_MOD_INIT(net) @@ -285,6 +316,7 @@ GRUB_MOD_INIT(net) cmd_delroute = grub_register_command ("net_del_route", grub_cmd_delroute, "SHORTNAME", N_("Delete a network route.")); + grub_net_open = grub_net_open_real; } GRUB_MOD_FINI(net) @@ -293,4 +325,5 @@ GRUB_MOD_FINI(net) grub_unregister_command (cmd_deladdr); grub_unregister_command (cmd_addroute); grub_unregister_command (cmd_delroute); + grub_net_open = NULL; } diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c index 4273fedfe..9de545910 100644 --- a/grub-core/kern/device.c +++ b/grub-core/kern/device.c @@ -26,6 +26,8 @@ #include #include +grub_net_t (*grub_net_open) (const char *name) = NULL; + grub_device_t grub_device_open (const char *name) { @@ -46,15 +48,16 @@ grub_device_open (const char *name) if (! dev) goto fail; + dev->net = NULL; /* Try to open a disk. */ - disk = grub_disk_open (name); - if (! disk) - goto fail; + dev->disk = grub_disk_open (name); + if (dev->disk) + return dev; + if (grub_net_open) + dev->net = grub_net_open (name); - dev->disk = disk; - dev->net = 0; /* FIXME */ - - return dev; + if (dev->net) + return dev; fail: if (disk) @@ -71,6 +74,12 @@ grub_device_close (grub_device_t device) if (device->disk) grub_disk_close (device->disk); + if (device->net) + { + grub_free (device->net->name); + grub_free (device->net); + } + grub_free (device); return grub_errno; diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c index 8ffb93c8b..c4d6efa96 100644 --- a/grub-core/kern/fs.c +++ b/grub-core/kern/fs.c @@ -95,7 +95,7 @@ grub_fs_probe (grub_device_t device) } } else if (device->net) - return device->net->fs; + return device->net->protocol; grub_error (GRUB_ERR_UNKNOWN_FS, "unknown filesystem"); return 0; diff --git a/include/grub/device.h b/include/grub/device.h index d68c26e66..f3e43bf60 100644 --- a/include/grub/device.h +++ b/include/grub/device.h @@ -24,12 +24,7 @@ #include struct grub_disk; -struct grub_fs; -struct grub_net -{ - char *name; - struct grub_fs *fs; -}; +struct grub_net; struct grub_device { diff --git a/include/grub/net.h b/include/grub/net.h index 4ca873f74..b5e852f9b 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -22,6 +22,17 @@ #include #include #include +#include + +typedef struct grub_fs *grub_net_app_level_t; + +typedef struct grub_net +{ + char *name; + grub_net_app_level_t protocol; +} *grub_net_t; + +extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); struct grub_net_card; @@ -46,7 +57,7 @@ struct grub_net_network_level_interface; typedef union grub_net_network_level_address { grub_uint32_t ipv4; -} grub_net_network_level_netaddress_t; +} grub_net_network_level_address_t; typedef union grub_net_network_level_netaddress { @@ -54,7 +65,7 @@ typedef union grub_net_network_level_netaddress grub_uint32_t base; int masksize; } ipv4; -} grub_net_network_level_address_t; +} grub_net_network_level_netaddress_t; typedef enum grub_network_level_protocol_id { @@ -163,6 +174,28 @@ grub_net_network_level_interface_unregister (struct grub_net_network_level_inter #define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next) +extern grub_net_app_level_t grub_net_app_level_list; + +#ifndef GRUB_LST_GENERATOR +static inline void +grub_net_app_level_register (grub_net_app_level_t proto) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_net_app_level_list), + GRUB_AS_LIST (proto)); +} +#endif + +static inline void +grub_net_app_level_unregister (grub_net_app_level_t proto) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_net_app_level_list), + GRUB_AS_LIST (proto)); +} + +#define FOR_NET_APP_LEVEL(var) FOR_LIST_ELEMENTS((var), \ + (grub_net_app_level_list)) + + extern struct grub_net_route *grub_net_routes; static inline void