]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Respect netmask from bootp/dhcp.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Wed, 20 Jun 2012 21:46:50 +0000 (23:46 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Wed, 20 Jun 2012 21:46:50 +0000 (23:46 +0200)
* grub-core/net/bootp.c (parse_dhcp_vendor): Parse mask.
(grub_net_configure_by_dhcp_ack): Use mask and grub_net_add_ipv4_local.
* grub-core/net/net.c (grub_net_add_addr): Split creating local route
into ...
(grub_net_add_ipv4_local): ... this.
(grub_cmd_addaddr): Use grub_net_add_ipv4_local.
* include/grub/net.h (GRUB_NET_BOOTP_NETMASK): New enum value.
(grub_net_add_ipv4_local): New proto.

ChangeLog
grub-core/net/bootp.c
grub-core/net/net.c
include/grub/net.h

index e10dcd0726b112135652c021f05f2396fe7bbc95..7c0bfb32cf72f3e0b3bd5c63e8b77726e433611b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2012-06-20  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Respect netmask from bootp/dhcp.
+
+       * grub-core/net/bootp.c (parse_dhcp_vendor): Parse mask.
+       (grub_net_configure_by_dhcp_ack): Use mask and grub_net_add_ipv4_local.
+       * grub-core/net/net.c (grub_net_add_addr): Split creating local route
+       into ...
+       (grub_net_add_ipv4_local): ... this.
+       (grub_cmd_addaddr): Use grub_net_add_ipv4_local.
+       * include/grub/net.h (GRUB_NET_BOOTP_NETMASK): New enum value.
+       (grub_net_add_ipv4_local): New proto.
+
 2012-06-20  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/loader/i386/linux.c (grub_linux_boot): Setup video before
index a303bb19c665c754f877ff49ffcd34f1a9cab8f9..04fdd57de2247edf2c7f05fb85fd94dbddb4c34c 100644 (file)
@@ -52,7 +52,7 @@ set_env_limn_ro (const char *intername, const char *suffix,
 }
 
 static void
-parse_dhcp_vendor (const char *name, void *vend, int limit)
+parse_dhcp_vendor (const char *name, void *vend, int limit, int *mask)
 {
   grub_uint8_t *ptr, *ptr0;
 
@@ -83,6 +83,17 @@ parse_dhcp_vendor (const char *name, void *vend, int limit)
 
       switch (tagtype)
        {
+       case GRUB_NET_BOOTP_NETMASK:
+         if (taglength == 4)
+           {
+             int i;
+             for (i = 0; i < 32; i++)
+               if (!(ptr[i / 8] & (1 << (7 - (i % 8)))))
+                 break;
+             *mask = i;
+           }
+         break;
+
        case GRUB_NET_BOOTP_ROUTER:
          if (taglength == 4)
            {
@@ -149,6 +160,7 @@ grub_net_configure_by_dhcp_ack (const char *name,
   grub_net_network_level_address_t addr;
   grub_net_link_level_address_t hwaddr;
   struct grub_net_network_level_interface *inter;
+  int mask = -1;
 
   addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
   addr.ipv4 = bp->your_ip;
@@ -242,8 +254,9 @@ grub_net_configure_by_dhcp_ack (const char *name,
        }
     }
   if (size > OFFSET_OF (vendor, bp))
-    parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp));
-
+    parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask);
+  grub_net_add_ipv4_local (inter, mask);
+  
   inter->dhcp_ack = grub_malloc (size);
   if (inter->dhcp_ack)
     {
index 9f1afd1e764928c7a247e676386e6b1f1ad9e03b..924de2a7d26bdfe6a50461ef6abe1e25baf11a47 100644 (file)
@@ -874,44 +874,53 @@ grub_net_add_addr (const char *name,
 
   grub_net_network_level_interface_register (inter);
 
-  if (addr->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4)
+  return inter;
+}
+
+grub_err_t
+grub_net_add_ipv4_local (struct grub_net_network_level_interface *inter,
+                        int mask)
+{
+  grub_uint32_t ip_cpu;
+  struct grub_net_route *route;
+
+  if (inter->address.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4)
+    return 0;
+
+  ip_cpu = grub_be_to_cpu32 (inter->address.ipv4);
+
+  if (mask == -1)
     {
-      int mask = -1;
-      grub_uint32_t ip_cpu = grub_be_to_cpu32 (addr->ipv4);
       if (!(ip_cpu & 0x80000000))
        mask = 8;
       else if (!(ip_cpu & 0x40000000))
        mask = 16;
       else if (!(ip_cpu & 0x20000000))
        mask = 24;
-      else
-       mask = -1;
-      if (mask != -1)
-       {
-         struct grub_net_route *route;
+    }
+  if (mask == -1)
+    return 0;
 
-         route = grub_zalloc (sizeof (*route));
-         if (!route)
-           return NULL;
+  route = grub_zalloc (sizeof (*route));
+  if (!route)
+    return grub_errno;
 
-         route->name = grub_xasprintf ("%s:local", name);
-         if (!route->name)
-           {
-             grub_free (route);
-             return NULL;
-           }
+  route->name = grub_xasprintf ("%s:local", inter->name);
+  if (!route->name)
+    {
+      grub_free (route);
+      return grub_errno;
+    }
 
-         route->target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
-         route->target.ipv4.base = grub_cpu_to_be32 (ip_cpu & (0xffffffff << (32 - mask)));
-         route->target.ipv4.masksize = mask;
-         route->is_gateway = 0;
-         route->interface = inter;
+  route->target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+  route->target.ipv4.base = grub_cpu_to_be32 (ip_cpu & (0xffffffff << (32 - mask)));
+  route->target.ipv4.masksize = mask;
+  route->is_gateway = 0;
+  route->interface = inter;
 
-         grub_net_route_register (route);
-       }
-    }
+  grub_net_route_register (route);
 
-  return inter;
+  return 0;
 }
 
 /* FIXME: support MAC specifying.  */
@@ -923,6 +932,7 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)),
   grub_net_network_level_address_t addr;
   grub_err_t err;
   grub_net_interface_flags_t flags = 0;
+  struct grub_net_network_level_interface *inf;
 
   if (argc != 3)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("three arguments expected"));
@@ -944,8 +954,11 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)),
   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);
+  inf = grub_net_add_addr (args[0], card, &addr, &card->default_address,
+                          flags);
+  if (inf)
+    grub_net_add_ipv4_local (inf, -1);
+
   return grub_errno;
 }
 
index 859f81f15f0d05288fe9631e2c225d02cb312800..1db05e8064ea1c316806978bfedaba218bd899b2 100644 (file)
@@ -409,6 +409,7 @@ struct grub_net_bootp_packet
 enum
   {
     GRUB_NET_BOOTP_PAD = 0x00,
+    GRUB_NET_BOOTP_NETMASK = 0x01,
     GRUB_NET_BOOTP_ROUTER = 0x03,
     GRUB_NET_BOOTP_DNS = 0x06,
     GRUB_NET_BOOTP_HOSTNAME = 0x0c,
@@ -426,6 +427,10 @@ grub_net_configure_by_dhcp_ack (const char *name,
                                grub_size_t size,
                                int is_def, char **device, char **path);
 
+grub_err_t
+grub_net_add_ipv4_local (struct grub_net_network_level_interface *inf,
+                        int mask);
+
 void
 grub_net_process_dhcp (struct grub_net_buff *nb,
                       struct grub_net_card *card);