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.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-06-20 23:46:50 +02:00
parent 67caf9eb06
commit d6b7c7c986
4 changed files with 76 additions and 32 deletions

View file

@ -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

View 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)
{

View 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->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);
}
route->name = grub_xasprintf ("%s:local", inter->name);
if (!route->name)
{
grub_free (route);
return grub_errno;
}
return 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);
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;
}

View 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);