]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Restructure pxe
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 2 Sep 2010 15:18:02 +0000 (17:18 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 2 Sep 2010 15:18:02 +0000 (17:18 +0200)
Makefile.util.def
grub-core/commands/ls.c
grub-core/commands/net.c
grub-core/fs/i386/pc/pxe.c
include/grub/net.h

index 35bcd81b2fecd49a99643ad3f2b53eae9d76f0e8..fe68943066f579d91bbdb89d15d6a5675f99161a 100644 (file)
@@ -30,6 +30,7 @@ library = {
   common = grub-core/commands/blocklist.c;
   common = grub-core/commands/extcmd.c;
   common = grub-core/commands/ls.c;
+  common = grub-core/commands/net.c;
   common = grub-core/disk/dmraid_nvidia.c;
   common = grub-core/disk/host.c;
   common = grub-core/disk/loopback.c;
index 9ee0a7a3134425dcd2c532353b449038d1b5812a..3179d271ea0b23295b3f9459a0a69477756dae4c 100644 (file)
@@ -31,6 +31,7 @@
 #include <grub/extcmd.h>
 #include <grub/datetime.h>
 #include <grub/i18n.h>
+#include <grub/net.h>
 
 static const struct grub_arg_option options[] =
   {
@@ -45,6 +46,8 @@ static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'};
 static grub_err_t
 grub_ls_list_devices (int longlist)
 {
+  grub_net_app_level_t proto;
+
   auto int grub_ls_print_devices (const char *name);
   int grub_ls_print_devices (const char *name)
     {
@@ -58,6 +61,16 @@ grub_ls_list_devices (int longlist)
 
   grub_device_iterate (grub_ls_print_devices);
   grub_xputs ("\n");
+
+  grub_puts_ (N_ ("Network protocols:\n"));
+
+  FOR_NET_APP_LEVEL (proto)
+  {
+    grub_printf ("%s ", proto->name);
+  }
+
+  grub_xputs ("\n");
+
   grub_refresh ();
 
   return 0;
index 904c61a92574d805f1a774ec56fdaefd7ac862ec..2062e1bd0e22faea2fc731a34d787a6f0cfc161e 100644 (file)
 #include <grub/dl.h>
 #include <grub/command.h>
 
+struct grub_net_route
+{
+  struct grub_net_route *next;
+  grub_net_network_level_netaddress_t target;
+  char *name;
+  struct grub_net_network_level_protocol *prot;
+  int is_gateway;
+  union
+  {
+    struct grub_net_network_level_interface *interface;
+    grub_net_network_level_address_t gw;
+  };
+};
+
 struct grub_net_route *grub_net_routes = NULL;
 struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL;
 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)
+{
+  grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_interfaces),
+                   GRUB_AS_LIST (inter));
+}
+
+#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next)
+
+static inline void
+grub_net_route_register (struct grub_net_route *route)
+{
+  grub_list_push (GRUB_AS_LIST_P (&grub_net_routes),
+                 GRUB_AS_LIST (route));
+}
+
+static inline void
+grub_net_route_unregister (struct grub_net_route *route)
+{
+  grub_list_remove (GRUB_AS_LIST_P (&grub_net_routes),
+                   GRUB_AS_LIST (route));
+}
+
+#define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next)
+
+static int
+parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
+{
+  grub_uint32_t newip = 0;
+  unsigned long t;
+  int i;
+  const char *ptr = val;
+
+  for (i = 0; i < 4; i++)
+    {
+      t = grub_strtoul (ptr, (char **) &ptr, 0);
+      if (grub_errno)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         return 0;
+       }
+      if (t & ~0xff)
+       return 0;
+      newip >>= 8;
+      newip |= (t << 24);
+      if (i != 3 && *ptr != '.')
+       return 0;
+      ptr++;
+    }
+  *ip = newip;
+  if (rest)
+    *rest = ptr - 1;
+  return 0;
+}
+
+static int
+match_net (const grub_net_network_level_netaddress_t *net,
+          const grub_net_network_level_address_t *addr)
+{
+  if (net->type != addr->type)
+    return 0;
+  switch (net->type)
+    {
+    case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4:
+      {
+       grub_int32_t mask = (1 << net->ipv4.masksize) - 1;
+       return ((net->ipv4.base & mask) == (addr->ipv4 & mask));
+      }
+    }
+  return 0;
+}
+
 grub_err_t
-grub_net_resolve_address (struct grub_net_network_level_protocol **prot,
-                         char *name,
+grub_net_resolve_address (const char *name,
                          grub_net_network_level_address_t *addr)
 {
-  FOR_NET_NETWORK_LEVEL_PROTOCOLS (*prot)
+  if (parse_ip (name, &addr->ipv4, NULL))
     {
-      grub_err_t err;
-      err = grub_net_resolve_address_in_protocol (*prot, name, addr);
-      if (err == GRUB_ERR_NET_BAD_ADDRESS)
+      addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+      return GRUB_ERR_NONE;
+    }
+  return grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("unrecognised address %s"),
+                    name);
+}
+
+grub_err_t
+grub_net_resolve_net_address (const char *name,
+                             grub_net_network_level_netaddress_t *addr)
+{
+  const char *rest;
+  if (parse_ip (name, &addr->ipv4.base, &rest))
+    {
+      addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+      if (*rest == '/')
        {
-         grub_errno = GRUB_ERR_NONE;
-         continue;
+         addr->ipv4.masksize = grub_strtoul (rest + 1, NULL, 0);
+         if (!grub_errno)
+           return GRUB_ERR_NONE;           
        }
-      if (err)
-       return err;
+      addr->ipv4.masksize = 32;
       return GRUB_ERR_NONE;
     }
-  return grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("Unrecognised address %s"),
+  return grub_error (GRUB_ERR_NET_BAD_ADDRESS, N_("unrecognised address %s"),
                     name);
 }
 
@@ -71,8 +176,7 @@ grub_net_route_address (grub_net_network_level_address_t addr,
       {
        if (depth && prot != route->prot)
          continue;
-       prot = route->prot;
-       if (!route->prot->match_net (route->target, curtarget))
+       if (!match_net (&route->target, &curtarget))
          continue;
 
        if (route->is_gateway)
@@ -107,7 +211,6 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)),
   if (inter == NULL)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found"));
 
-  inter->protocol->fini (inter);
   grub_net_network_level_interface_unregister (inter);
   grub_free (inter->name);
   grub_free (inter);
@@ -115,18 +218,35 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)),
   return GRUB_ERR_NONE;  
 }
 
+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)
+{
+  struct grub_net_network_level_interface *inter;
+
+  inter = grub_zalloc (sizeof (*inter));
+  if (!inter)
+    return NULL;
+
+  inter->name = grub_strdup (name);
+  grub_memcpy (&(inter->address), &addr, sizeof (inter->address));
+  inter->card = card;
+
+  grub_net_network_level_interface_register (inter);
+
+  return inter;
+}
+
 static grub_err_t
 grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)),
                  int argc, char **args)
 {
   struct grub_net_card *card;
-  struct grub_net_network_level_protocol *prot;
-  grub_err_t err;
   grub_net_network_level_address_t addr;
-  struct grub_net_network_level_interface *inter;
+  grub_err_t err;
 
-  if (argc != 4)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("four arguments expected"));
+  if (argc != 3)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("three arguments expected"));
   
   FOR_NET_CARDS (card)
     if (grub_strcmp (card->name, args[1]))
@@ -134,36 +254,12 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)),
   if (card == NULL)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found")); 
 
-  FOR_NET_NETWORK_LEVEL_PROTOCOLS (prot)
-    if (grub_strcmp (prot->name, args[2]))
-      break;
-
-  if (card == NULL)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("protocol not found")); 
-
-  err = grub_net_resolve_address_in_protocol (prot, args[3], &addr);
+  err = grub_net_resolve_address (args[2], &addr);
   if (err)
     return err;
 
-  inter = grub_zalloc (sizeof (*inter));
-  if (!inter)
-    return grub_errno;
-
-  inter->name = grub_strdup (args[0]);
-  inter->protocol = prot;
-  grub_memcpy (&(inter->address), &addr, sizeof (inter->address));
-  inter->card = card;
-
-  err = prot->init (inter);
-  if (err)
-    {
-      grub_free (inter->name);
-      grub_free (inter);
-      return err;
-    }
-  grub_net_network_level_interface_register (inter);
-
-  return GRUB_ERR_NONE;
+  grub_net_add_addr (args[0], card, addr);
+  return grub_errno;
 }
 
 static grub_err_t
@@ -188,84 +284,157 @@ grub_cmd_delroute (struct grub_command *cmd __attribute__ ((unused)),
   return GRUB_ERR_NONE;
 }
 
-static grub_err_t
-grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)),
-                 int argc, char **args)
+grub_err_t
+grub_net_add_route (const char *name,
+                   grub_net_network_level_netaddress_t target,
+                   struct grub_net_network_level_interface *inter)
 {
-  struct grub_net_network_level_protocol *prot;
   struct grub_net_route *route;
 
-  if (argc < 3)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                      N_("At least 3 arguments are expected"));
-
   route = grub_zalloc (sizeof (*route));
   if (!route)
     return grub_errno;
 
-  route->name = grub_strdup (args[0]);
+  route->name = grub_strdup (name);
   if (!route->name)
     {
       grub_free (route);
       return grub_errno;
     }
 
-  FOR_NET_NETWORK_LEVEL_PROTOCOLS(prot)
-  {
-    grub_err_t err;
-    err = prot->net_ntoa (args[1], &(route->target));
-    if (err == GRUB_ERR_NET_BAD_ADDRESS)
-      {
-       grub_errno = GRUB_ERR_NONE;
-       continue;
-      }
-    if (err)
-      return err;
-    break;
-  }
-  
-  if (!prot)
+  route->target = target;
+  route->is_gateway = 0;
+  route->interface = inter;
+
+  grub_net_route_register (route);
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_net_add_route_gw (const char *name,
+                      grub_net_network_level_netaddress_t target,
+                      grub_net_network_level_address_t gw)
+{
+  struct grub_net_route *route;
+
+  route = grub_zalloc (sizeof (*route));
+  if (!route)
+    return grub_errno;
+
+  route->name = grub_strdup (name);
+  if (!route->name)
     {
-      grub_free (route->name);
       grub_free (route);
-      return grub_error (GRUB_ERR_NET_BAD_ADDRESS,
-                        N_("Unrecognised address %s"), args[1]);
+      return grub_errno;
     }
 
+  route->target = target;
+  route->is_gateway = 1;
+  route->gw = gw;
+
+  grub_net_route_register (route);
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)),
+                 int argc, char **args)
+{
+  grub_net_network_level_netaddress_t target;
+  if (argc < 3)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                      N_("At least 3 arguments are expected"));
+
+  grub_net_resolve_net_address  (args[1], &target);
+  
   if (grub_strcmp (args[2], "gw") == 0 && argc >= 4)
     {
       grub_err_t err;
-      route->is_gateway = 1;
-      err = grub_net_resolve_address_in_protocol (prot,
-                                                 args[3], &(route->gw));
+      grub_net_network_level_address_t gw;
+
+      err = grub_net_resolve_address (args[3], &gw);
       if (err)
-       {
-         grub_free (route->name);
-         grub_free (route);
-         return err;
-       }
+       return err;
+      return grub_net_add_route_gw (args[0], target, gw);
     }
   else
     {
       struct grub_net_network_level_interface *inter;
-      route->is_gateway = 0;
 
       FOR_NET_NETWORK_LEVEL_INTERFACES (inter)
        if (grub_strcmp (inter->name, args[2]))
          break;
 
       if (!inter)
-       {
-         grub_free (route->name);
-         grub_free (route);
-         return grub_error (GRUB_ERR_BAD_ARGUMENT,
-                            N_("Unrecognised interface %s"), args[2]);
-       }
-      route->interface = inter;
+       return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                          N_("unrecognised interface %s"), args[2]);
+      return grub_net_add_route (args[0], target, inter);
     }
+}
 
-  grub_net_route_register (route);
+static void
+print_net_address (const grub_net_network_level_netaddress_t *target)
+{
+  switch (target->type)
+    {
+    case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4:
+      grub_printf ("%d.%d.%d.%d/%d ", ((target->ipv4.base >> 24) & 0xff),
+                  ((target->ipv4.base >> 16) & 0xff),
+                  ((target->ipv4.base >> 8) & 0xff),
+                  ((target->ipv4.base >> 0) & 0xff),
+                  target->ipv4.masksize);
+      break;
+    }
+}
+
+static void
+print_address (const grub_net_network_level_address_t *target)
+{
+  switch (target->type)
+    {
+    case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4:
+      grub_printf ("%d.%d.%d.%d ", ((target->ipv4 >> 24) & 0xff),
+                  ((target->ipv4 >> 16) & 0xff),
+                  ((target->ipv4 >> 8) & 0xff),
+                  ((target->ipv4 >> 0) & 0xff));
+      break;
+    }
+}
+
+static grub_err_t
+grub_cmd_listroutes (struct grub_command *cmd __attribute__ ((unused)),
+                    int argc __attribute__ ((unused)),
+                    char **args __attribute__ ((unused)))
+{
+  struct grub_net_route *route;
+  FOR_NET_ROUTES(route)
+  {
+    grub_printf ("%s ", route->name);
+    print_net_address (&route->target);
+    if (route->is_gateway)
+      {
+       grub_printf ("gw ");
+       print_address (&route->gw);     
+      }
+    else
+      grub_printf ("%s", route->interface->name);      
+  }
+  return GRUB_ERR_NONE;
+}
 
+static grub_err_t
+grub_cmd_listcards (struct grub_command *cmd __attribute__ ((unused)),
+                   int argc __attribute__ ((unused)),
+                   char **args __attribute__ ((unused)))
+{
+  struct grub_net_card *card;
+  FOR_NET_CARDS(card)
+  {
+    grub_printf ("%s ", card->name);
+  }
+  grub_printf ("\n");
   return GRUB_ERR_NONE;
 }
 
@@ -301,11 +470,12 @@ grub_net_open_real (const char *name)
 }
 
 static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute;
+static grub_command_t cmd_lsroutes, cmd_lscards;
 
 GRUB_MOD_INIT(net)
 {
   cmd_addaddr = grub_register_command ("net_add_addr", grub_cmd_addaddr,
-                                      "SHORTNAME CARD PROTOCOL ADDRESS",
+                                      "SHORTNAME CARD ADDRESS",
                                       N_("Add a network address."));
   cmd_deladdr = grub_register_command ("net_del_addr", grub_cmd_deladdr,
                                       "SHORTNAME",
@@ -316,6 +486,11 @@ GRUB_MOD_INIT(net)
   cmd_delroute = grub_register_command ("net_del_route", grub_cmd_delroute,
                                        "SHORTNAME",
                                        N_("Delete a network route."));
+  cmd_lsroutes = grub_register_command ("net_ls_routes", grub_cmd_listroutes,
+                                       "", N_("list network routes"));
+  cmd_lscards = grub_register_command ("net_ls_cards", grub_cmd_listcards,
+                                      "", N_("list network cards"));
+
   grub_net_open = grub_net_open_real;
 }
 
@@ -325,5 +500,7 @@ GRUB_MOD_FINI(net)
   grub_unregister_command (cmd_deladdr);
   grub_unregister_command (cmd_addroute);
   grub_unregister_command (cmd_delroute);
+  grub_unregister_command (cmd_lsroutes);
+  grub_unregister_command (cmd_lscards);
   grub_net_open = NULL;
 }
index 0dd44a30ae997407ee13722b6b4b610ab0d81d3c..20d0e1979e2b4bfec2bb779fcf99fc7cc02d191a 100644 (file)
@@ -18,9 +18,8 @@
  */
 
 #include <grub/dl.h>
-#include <grub/fs.h>
+#include <grub/net.h>
 #include <grub/mm.h>
-#include <grub/disk.h>
 #include <grub/file.h>
 #include <grub/misc.h>
 #include <grub/bufio.h>
 #define SEGMENT(x)     ((x) >> 4)
 #define OFFSET(x)      ((x) & 0xF)
 #define SEGOFS(x)      ((SEGMENT(x) << 16) + OFFSET(x))
-#define LINEAR(x)      (void *) (((x >> 16) <<4) + (x & 0xFFFF))
-
-struct grub_pxe_disk_data
-{
-  grub_uint32_t server_ip;
-  grub_uint32_t gateway_ip;
-};
+#define LINEAR(x)      (void *) (((x >> 16) << 4) + (x & 0xFFFF))
 
 struct grub_pxenv *grub_pxe_pxenv;
 static grub_uint32_t grub_pxe_your_ip;
@@ -53,6 +46,8 @@ struct grub_pxe_data
 {
   grub_uint32_t packet_number;
   grub_uint32_t block_size;
+  grub_uint32_t server_ip;
+  grub_uint32_t gateway_ip;
   char filename[0];
 };
 
@@ -95,55 +90,33 @@ grub_pxe_scan (void)
   return ret;
 }
 
-static int
-grub_pxe_iterate (int (*hook) (const char *name))
-{
-  if (hook ("pxe"))
-    return 1;
-  return 0;
-}
-
 static grub_err_t
-parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
+grub_pxefs_dir (grub_device_t device  __attribute__ ((unused)),
+               const char *path  __attribute__ ((unused)),
+               int (*hook) (const char *filename,
+                            const struct grub_dirhook_info *info)
+               __attribute__ ((unused)))
 {
-  grub_uint32_t newip = 0;
-  unsigned long t;
-  int i;
-  const char *ptr = val;
-
-  for (i = 0; i < 4; i++)
-    {
-      t = grub_strtoul (ptr, (char **) &ptr, 0);
-      if (grub_errno)
-       return grub_errno;
-      if (t & ~0xff)
-       return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
-      newip >>= 8;
-      newip |= (t << 24);
-      if (i != 3 && *ptr != '.')
-       return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
-      ptr++;
-    }
-  *ip = newip;
-  if (rest)
-    *rest = ptr - 1;
-  return 0;
+  return GRUB_ERR_NONE;
 }
 
 static grub_err_t
-grub_pxe_open (const char *name, grub_disk_t disk)
+grub_pxefs_open (struct grub_file *file, const char *name)
 {
-  struct grub_pxe_disk_data *data;
-
-  if (grub_strcmp (name, "pxe") != 0
-      && grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) != 0)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk");
+  union
+    {
+      struct grub_pxenv_tftp_get_fsize c1;
+      struct grub_pxenv_tftp_open c2;
+    } c;
+  struct grub_pxe_data *data;
+  grub_file_t file_int, bufio;
 
   data = grub_malloc (sizeof (*data));
   if (!data)
     return grub_errno;
 
-  if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0)
+#if 0
+  if (grub_strncmp (file->device->net->name, "pxe:", sizeof ("pxe:") - 1) == 0)
     {
       const char *ptr;
       grub_err_t err;
@@ -161,84 +134,35 @@ grub_pxe_open (const char *name, grub_disk_t disk)
       else
        data->gateway_ip = grub_pxe_default_gateway_ip;
     }
-  else
+  else 
+#endif
     {
-      data->server_ip = grub_pxe_default_server_ip;
-      data->gateway_ip = grub_pxe_default_gateway_ip;
-    }
-
-  disk->total_sectors = 0;
-  disk->id = (unsigned long) data;
-
-  disk->has_partitions = 0;
-  disk->data = data;
-
-  return GRUB_ERR_NONE;
-}
-
-static void
-grub_pxe_close (grub_disk_t disk)
-{
-  grub_free (disk->data);
-}
-
-static grub_err_t
-grub_pxe_read (grub_disk_t disk __attribute((unused)),
-               grub_disk_addr_t sector __attribute((unused)),
-               grub_size_t size __attribute((unused)),
-               char *buf __attribute((unused)))
-{
-  return GRUB_ERR_OUT_OF_RANGE;
-}
-
-static grub_err_t
-grub_pxe_write (grub_disk_t disk __attribute((unused)),
-                grub_disk_addr_t sector __attribute((unused)),
-                grub_size_t size __attribute((unused)),
-                const char *buf __attribute((unused)))
-{
-  return GRUB_ERR_OUT_OF_RANGE;
-}
-
-static struct grub_disk_dev grub_pxe_dev =
-  {
-    .name = "pxe",
-    .id = GRUB_DISK_DEVICE_PXE_ID,
-    .iterate = grub_pxe_iterate,
-    .open = grub_pxe_open,
-    .close = grub_pxe_close,
-    .read = grub_pxe_read,
-    .write = grub_pxe_write,
-    .next = 0
-  };
-
-static grub_err_t
-grub_pxefs_dir (grub_device_t device,
-               const char *path  __attribute__ ((unused)),
-               int (*hook) (const char *filename,
-                            const struct grub_dirhook_info *info)
-               __attribute__ ((unused)))
-{
-  if (device->disk->dev->id != GRUB_DISK_DEVICE_PXE_ID)
-    return grub_error (GRUB_ERR_IO, "not a pxe disk");
-
-  return GRUB_ERR_NONE;
-}
-
-static grub_err_t
-grub_pxefs_open (struct grub_file *file, const char *name)
-{
-  union
-    {
-      struct grub_pxenv_tftp_get_fsize c1;
-      struct grub_pxenv_tftp_open c2;
-    } c;
-  struct grub_pxe_data *data;
-  struct grub_pxe_disk_data *disk_data = file->device->disk->data;
-  grub_file_t file_int, bufio;
+      grub_net_network_level_address_t addr;
+      grub_net_network_level_address_t gateway;
+      struct grub_net_network_level_interface *interf;
+      grub_err_t err;
 
-  if (file->device->disk->dev->id != GRUB_DISK_DEVICE_PXE_ID)
-    return grub_error (GRUB_ERR_IO, "not a pxe disk");
+      if (grub_strncmp (file->device->net->name,
+                       "pxe,", sizeof ("pxe,") - 1) == 0)
+       {
+         const char *ptr;
+         
+         ptr = name + sizeof ("pxe,") - 1;
+         err = grub_net_resolve_address (name + sizeof ("pxe,") - 1, &addr);
+         if (err)
+           return err;
+       }
+      else
+       {
+         addr.ipv4 = grub_pxe_default_server_ip;
+         addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+       }
+      err = grub_net_route_address (addr, &gateway, &interf);
+      if (err)
+       return err;
+      data->server_ip = addr.ipv4;
+      data->gateway_ip = gateway.ipv4;
+    }
 
   if (curr_file != 0)
     {
@@ -246,8 +170,8 @@ grub_pxefs_open (struct grub_file *file, const char *name)
       curr_file = 0;
     }
 
-  c.c1.server_ip = disk_data->server_ip;
-  c.c1.gateway_ip = disk_data->gateway_ip;
+  c.c1.server_ip = data->server_ip;
+  c.c1.gateway_ip = data->gateway_ip;
   grub_strcpy ((char *)&c.c1.filename[0], name);
   grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1, pxe_rm_entry);
   if (c.c1.status)
@@ -297,7 +221,6 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
 {
   struct grub_pxenv_tftp_read c;
   struct grub_pxe_data *data;
-  struct grub_pxe_disk_data *disk_data = file->device->disk->data;
   grub_uint32_t pn, r;
 
   data = file->data;
@@ -317,8 +240,8 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
       if (curr_file != 0)
         grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o, pxe_rm_entry);
 
-      o.server_ip = disk_data->server_ip;
-      o.gateway_ip = disk_data->gateway_ip;
+      o.server_ip = data->server_ip;
+      o.gateway_ip = data->gateway_ip;
       grub_strcpy ((char *)&o.filename[0], data->filename);
       o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
       o.packet_size = grub_pxe_blksize;
@@ -513,18 +436,46 @@ grub_pxe_detect (void)
   grub_pxe_pxenv = pxenv;
 }
 
+static grub_size_t 
+grub_pxe_recv (struct grub_net_card *dev __attribute__ ((unused)),
+              void *buf __attribute__ ((unused)),
+              grub_size_t buflen __attribute__ ((unused)))
+{
+  return 0;
+}
+
+static grub_err_t 
+grub_pxe_send (struct grub_net_card *dev __attribute__ ((unused)),
+              void *buf __attribute__ ((unused)),
+              grub_size_t buflen __attribute__ ((unused)))
+{
+  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "not implemented");
+}
+
+struct grub_net_card_driver grub_pxe_card_driver =
+{
+  .send = grub_pxe_send,
+  .recv = grub_pxe_recv
+};
+
+struct grub_net_card grub_pxe_card =
+{
+  .driver = &grub_pxe_card_driver,
+  .name = "pxe"
+};
+
 void
 grub_pxe_unload (void)
 {
   if (grub_pxe_pxenv)
     {
-      grub_fs_unregister (&grub_pxefs_fs);
-      grub_disk_dev_unregister (&grub_pxe_dev);
-
+      grub_net_app_level_unregister (&grub_pxefs_fs);
+      grub_net_card_unregister (&grub_pxe_card);
       grub_pxe_pxenv = 0;
     }
 }
 
+#if 0
 static void
 set_ip_env (char *varname, grub_uint32_t ip)
 {
@@ -556,7 +507,9 @@ write_ip_env (grub_uint32_t *ip, const char *val)
 
   return buf; 
 }
+#endif
 
+#if 0
 static char *
 grub_env_write_pxe_default_server (struct grub_env_var *var 
                                   __attribute__ ((unused)),
@@ -572,6 +525,7 @@ grub_env_write_pxe_default_gateway (struct grub_env_var *var
 {
   return write_ip_env (&grub_pxe_default_gateway_ip, val);
 }
+#endif
 
 static char *
 grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)),
@@ -598,34 +552,58 @@ grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)),
   return buf;
 }
 
-
 GRUB_MOD_INIT(pxe)
 {
   grub_pxe_detect ();
   if (grub_pxe_pxenv)
     {
       char *buf;
+      grub_net_network_level_address_t addr;
+      struct grub_net_network_level_interface *inter;
+      
+#if 0
+      grub_register_variable_hook ("pxe_default_server", 0,
+                                  grub_env_write_pxe_default_server);
+      grub_register_variable_hook ("pxe_default_gateway", 0,
+                                  grub_env_write_pxe_default_gateway);
+#endif
+      grub_register_variable_hook ("pxe_blksize", 0,
+                                  grub_env_write_pxe_blocksize);
 
       buf = grub_xasprintf ("%d", grub_pxe_blksize);
       if (buf)
        grub_env_set ("pxe_blksize", buf);
       grub_free (buf);
 
+#if 0
       set_ip_env ("pxe_default_server", grub_pxe_default_server_ip);
-      set_ip_env ("pxe_default_gateway", grub_pxe_default_gateway_ip);
-      set_ip_env ("net_pxe_ip", grub_pxe_your_ip);
-      grub_register_variable_hook ("pxe_default_server", 0,
-                                  grub_env_write_pxe_default_server);
-      grub_register_variable_hook ("pxe_default_gateway", 0,
-                                  grub_env_write_pxe_default_gateway);
-
-      /* XXX: Is it possible to change IP in PXE?  */
-      grub_register_variable_hook ("net_pxe_ip", 0,
-                                  grub_env_write_readonly);
-      grub_register_variable_hook ("pxe_blksize", 0,
-                                  grub_env_write_pxe_blocksize);
-      grub_disk_dev_register (&grub_pxe_dev);
-      grub_fs_register (&grub_pxefs_fs);
+#endif
+
+      grub_net_app_level_register (&grub_pxefs_fs);
+      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);
+      if (grub_pxe_default_gateway_ip)
+       {
+         grub_net_network_level_netaddress_t target;
+         grub_net_network_level_address_t gw;
+         
+         target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+         target.ipv4.base = grub_pxe_default_server_ip;
+         target.ipv4.masksize = 32;
+         gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+         gw.ipv4 = grub_pxe_default_gateway_ip;
+         grub_net_add_route_gw ("pxe_default", target, gw);
+       }
+      {
+       grub_net_network_level_netaddress_t target;
+       target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+       target.ipv4.base = grub_pxe_default_gateway_ip ?
+         : grub_pxe_default_server_ip;
+       target.ipv4.masksize = 32;
+       grub_net_add_route ("pxe_default", target, inter);
+      }
     }
 }
 
index b5e852f9b6cf7732132736cc0df8e110f7ec1001..84e881efe4ba8b03f7f4f87939a4babb768ed0e2 100644 (file)
@@ -54,71 +54,37 @@ struct grub_net_card
 
 struct grub_net_network_level_interface;
 
+typedef enum grub_network_level_protocol_id 
+{
+  GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
+} grub_network_level_protocol_id_t;
+
 typedef union grub_net_network_level_address
 {
+  grub_network_level_protocol_id_t type;
   grub_uint32_t ipv4;
 } grub_net_network_level_address_t;
 
 typedef union grub_net_network_level_netaddress
 {
+  grub_network_level_protocol_id_t type;
   struct {
     grub_uint32_t base;
     int masksize; 
   } ipv4;
 } grub_net_network_level_netaddress_t;
 
-typedef enum grub_network_level_protocol_id 
-{
-  GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
-} grub_network_level_protocol_id_t;
-
 struct grub_net_network_level_interface;
 
-struct grub_net_network_level_protocol
-{
-  struct grub_net_network_level_protocol *next;
-  char *name;
-  grub_network_level_protocol_id_t id;
-  grub_err_t (*ntoa) (char *name, grub_net_network_level_address_t *addr);
-  char * (*aton) (union grub_net_network_level_address addr);
-  grub_err_t (*net_ntoa) (char *name,
-                         grub_net_network_level_netaddress_t *addr);
-  char * (*net_aton) (grub_net_network_level_netaddress_t addr);
-  int (* match_net) (grub_net_network_level_netaddress_t net,
-                    grub_net_network_level_address_t addr);
-  grub_err_t (*init) (struct grub_net_network_level_interface *dev);
-  grub_err_t (*fini) (struct grub_net_network_level_interface *dev);
-  grub_err_t (*send) (struct grub_net_network_level_interface *dev, void *buf,
-                     grub_size_t buflen);
-  grub_size_t (*recv) (struct grub_net_network_level_interface *dev, void *buf,
-                      grub_size_t buflen);  
-};
-
 struct grub_net_network_level_interface
 {
   struct grub_net_network_level_interface *next;
   char *name;
-  /* Underlying protocol.  */
-  struct grub_net_network_level_protocol *protocol;
   struct grub_net_card *card;
   union grub_net_network_level_address address;
   void *data;
 };
 
-struct grub_net_route
-{
-  struct grub_net_route *next;
-  grub_net_network_level_netaddress_t target;
-  char *name;
-  struct grub_net_network_level_protocol *prot;
-  int is_gateway;
-  union
-  {
-    struct grub_net_network_level_interface *interface;
-    grub_net_network_level_address_t gw;
-  };
-};
-
 struct grub_net_session;
 
 struct grub_net_session_level_protocol
@@ -156,23 +122,11 @@ grub_net_session_recv (struct grub_net_session *session, void *buf,
   return session->protocol->recv (session, buf, size);
 }
 
-extern struct grub_net_network_level_interface *grub_net_network_level_interfaces;
+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);
 
-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)
-{
-  grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_interfaces),
-                   GRUB_AS_LIST (inter));
-}
-
-#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next)
+extern struct grub_net_network_level_interface *grub_net_network_level_interfaces;
 
 extern grub_net_app_level_t grub_net_app_level_list;
 
@@ -195,25 +149,6 @@ grub_net_app_level_unregister (grub_net_app_level_t 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
-grub_net_route_register (struct grub_net_route *route)
-{
-  grub_list_push (GRUB_AS_LIST_P (&grub_net_routes),
-                 GRUB_AS_LIST (route));
-}
-
-static inline void
-grub_net_route_unregister (struct grub_net_route *route)
-{
-  grub_list_remove (GRUB_AS_LIST_P (&grub_net_routes),
-                   GRUB_AS_LIST (route));
-}
-
-#define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next)
-
 extern struct grub_net_card *grub_net_cards;
 
 static inline void
@@ -232,44 +167,32 @@ grub_net_card_unregister (struct grub_net_card *card)
 
 #define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next)
 
-extern struct grub_net_network_level_protocol *grub_net_network_level_protocols;
-
-static inline void
-grub_net_network_level_protocol_register (struct grub_net_network_level_protocol *prot)
-{
-  grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_protocols),
-                 GRUB_AS_LIST (prot));
-}
-
-static inline void
-grub_net_network_level_protocol_unregister (struct grub_net_network_level_protocol *prot)
-{
-  grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_protocols),
-                   GRUB_AS_LIST (prot));
-}
-
-#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_level_protocols; (var); (var) = (var)->next)
-
-static inline grub_err_t
-grub_net_resolve_address_in_protocol (struct grub_net_network_level_protocol *prot,
-                                     char *name,
-                                     grub_net_network_level_address_t *addr)
-{
-  return prot->ntoa (name, addr);
-}
-
 struct grub_net_session *
 grub_net_open_tcp (char *address, grub_uint16_t port);
 
 grub_err_t
-grub_net_resolve_address (struct grub_net_network_level_protocol **prot,
-                         char *name,
+grub_net_resolve_address (const char *name,
                          grub_net_network_level_address_t *addr);
 
+grub_err_t
+grub_net_resolve_net_address (const char *name,
+                             grub_net_network_level_netaddress_t *addr);
+
 grub_err_t
 grub_net_route_address (grub_net_network_level_address_t addr,
                        grub_net_network_level_address_t *gateway,
                        struct grub_net_network_level_interface **interf);
 
 
+grub_err_t
+grub_net_add_route (const char *name,
+                   grub_net_network_level_netaddress_t target,
+                   struct grub_net_network_level_interface *inter);
+
+grub_err_t
+grub_net_add_route_gw (const char *name,
+                      grub_net_network_level_netaddress_t target,
+                      grub_net_network_level_address_t gw);
+
+
 #endif /* ! GRUB_NET_HEADER */