* 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>
+
+ 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
}
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;
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)
{
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;
}
}
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)
{
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. */
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"));
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;
}
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,
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);