return GRUB_ERR_NONE;
}
-/*
- Currently suppoerted adresses:
- IPv4: XXX.XXX.XXX.XXX
- */
-#define MAX_STR_ADDR_LEN sizeof ("XXX.XXX.XXX.XXX")
-
-static void
-addr_to_str (const grub_net_network_level_address_t *target, char *buf)
+void
+grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf)
{
switch (target->type)
{
case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4:
{
grub_uint32_t n = grub_be_to_cpu32 (target->ipv4);
- grub_snprintf (buf, MAX_STR_ADDR_LEN, "%d.%d.%d.%d",
+ grub_snprintf (buf, GRUB_NET_MAX_STR_ADDR_LEN, "%d.%d.%d.%d",
((n >> 24) & 0xff), ((n >> 16) & 0xff),
((n >> 8) & 0xff), ((n >> 0) & 0xff));
}
}
{
- char buf[MAX_STR_ADDR_LEN];
+ char buf[GRUB_NET_MAX_STR_ADDR_LEN];
char name[grub_strlen (inter->name) + sizeof ("net__ip")];
- addr_to_str (&inter->address, buf);
+ grub_net_addr_to_str (&inter->address, buf);
grub_snprintf (name, sizeof (name), "net_%s_ip", inter->name);
grub_env_set (name, buf);
grub_register_variable_hook (name, 0, addr_set_env);
grub_memcpy (&(inter->hwaddress), &hwaddress, sizeof (inter->hwaddress));
inter->flags = flags;
inter->card = card;
+ inter->dhcp_ack = NULL;
+ inter->dhcp_acklen = 0;
grub_net_network_level_interface_register (inter);
static void
print_address (const grub_net_network_level_address_t *target)
{
- char buf[MAX_STR_ADDR_LEN];
- addr_to_str (target, buf);
+ char buf[GRUB_NET_MAX_STR_ADDR_LEN];
+ grub_net_addr_to_str (target, buf);
grub_xputs (buf);
}
return NULL;
}
+static char *
+grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)),
+ const char *val __attribute__ ((unused)))
+{
+ return NULL;
+}
+
+static void
+set_env_limn_ro (const char *intername, const char *suffix,
+ char *value, grub_size_t len)
+{
+ char c;
+ char varname[sizeof ("net_") + grub_strlen (intername) + sizeof ("_")
+ + grub_strlen (suffix)];
+ grub_snprintf (varname, sizeof (varname), "net_%s_%s", intername, suffix);
+ c = value[len];
+ value[len] = 0;
+ grub_env_set (varname, value);
+ value[len] = c;
+ grub_register_variable_hook (varname, 0, grub_env_write_readonly);
+}
+
+static void
+parse_dhcp_vendor (const char *name, void *vend, int limit)
+{
+ grub_uint8_t *ptr, *ptr0;
+
+ ptr = ptr0 = vend;
+
+ if (grub_be_to_cpu32 (*(grub_uint32_t *) ptr) != GRUB_NET_BOOTP_RFC1048_MAGIC)
+ return;
+ ptr = ptr + sizeof (grub_uint32_t);
+ while (ptr - ptr0 < limit)
+ {
+ grub_uint8_t tagtype;
+ grub_uint8_t taglength;
+
+ tagtype = *ptr++;
+
+ /* Pad tag. */
+ if (tagtype == 0)
+ continue;
+
+ /* End tag. */
+ if (tagtype == 0xff)
+ return;
+
+ taglength = *ptr++;
+
+ switch (tagtype)
+ {
+ case 12:
+ set_env_limn_ro (name, "hostname", (char *) ptr, taglength);
+ break;
+
+ case 15:
+ set_env_limn_ro (name, "domain", (char *) ptr, taglength);
+ break;
+
+ case 17:
+ set_env_limn_ro (name, "rootpath", (char *) ptr, taglength);
+ break;
+
+ case 18:
+ set_env_limn_ro (name, "extensionspath", (char *) ptr, taglength);
+ break;
+
+ /* If you need any other options please contact GRUB
+ developpement team. */
+ }
+
+ ptr += taglength;
+ }
+}
+
+#define OFFSET_OF(x, y) ((grub_uint8_t *)((y)->x) - (grub_uint8_t *)(y))
+
+struct grub_net_network_level_interface *
+grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_card *card,
+ grub_net_interface_flags_t flags,
+ struct grub_net_bootp_ack *bp,
+ grub_size_t size)
+{
+ grub_net_network_level_address_t addr;
+ grub_net_link_level_address_t hwaddr;
+ struct grub_net_network_level_interface *inter;
+
+ addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+ addr.ipv4 = bp->your_ip;
+
+ grub_memcpy (hwaddr.mac, bp->mac_addr,
+ bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len
+ : sizeof (hwaddr.mac));
+ hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
+
+ inter = grub_net_add_addr (name, card, addr, hwaddr, flags);
+ if (bp->gateway_ip != bp->server_ip)
+ {
+ grub_net_network_level_netaddress_t target;
+ grub_net_network_level_address_t gw;
+ char rname[grub_strlen (name) + sizeof ("_gw")];
+
+ target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+ target.ipv4.base = bp->server_ip;
+ target.ipv4.masksize = 32;
+ gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+ gw.ipv4 = bp->gateway_ip;
+ grub_snprintf (rname, sizeof (rname), "%s_gw", name);
+ grub_net_add_route_gw (rname, target, gw);
+ }
+ {
+ grub_net_network_level_netaddress_t target;
+ target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+ target.ipv4.base = bp->gateway_ip;
+ target.ipv4.masksize = 32;
+ grub_net_add_route (name, target, inter);
+ }
+
+ if (size > OFFSET_OF (boot_file, bp))
+ set_env_limn_ro (name, "boot_file", (char *) bp->boot_file,
+ sizeof (bp->boot_file));
+ if (size > OFFSET_OF (server_name, bp))
+ set_env_limn_ro (name, "dhcp_server_name", (char *) bp->server_name,
+ sizeof (bp->server_name));
+ if (size > OFFSET_OF (vendor, bp))
+ parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp));
+
+ inter->dhcp_ack = grub_malloc (size);
+ if (inter->dhcp_ack)
+ {
+ grub_memcpy (inter->dhcp_ack, bp, size);
+ inter->dhcp_acklen = size;
+ }
+ else
+ grub_errno = GRUB_ERR_NONE;
+
+ return inter;
+}
+
static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute;
static grub_command_t cmd_lsroutes, cmd_lscards;
#define LINEAR(x) (void *) (((x >> 16) << 4) + (x & 0xFFFF))
struct grub_pxe_bangpxe *grub_pxe_pxenv;
-static grub_uint32_t grub_pxe_your_ip;
static grub_uint32_t grub_pxe_default_server_ip;
+#if 0
static grub_uint32_t grub_pxe_default_gateway_ip;
+#endif
static unsigned grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE;
-
+static grub_uint32_t pxe_rm_entry = 0;
static grub_file_t curr_file = 0;
-static grub_net_link_level_address_t pxe_hwaddr;
struct grub_pxe_data
{
char filename[0];
};
-static grub_uint32_t pxe_rm_entry = 0;
static struct grub_pxe_bangpxe *
grub_pxe_scan (void)
.next = 0
};
-static char *
-grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)),
- const char *val __attribute__ ((unused)))
-{
- return NULL;
-}
-
-static void
-set_env_limn_ro (const char *varname, char *value, grub_size_t len)
-{
- char c;
- c = value[len];
- value[len] = 0;
- grub_env_set (varname, value);
- value[len] = c;
- grub_register_variable_hook (varname, 0, grub_env_write_readonly);
-}
-
-static void
-parse_dhcp_vendor (void *vend, int limit)
-{
- grub_uint8_t *ptr, *ptr0;
-
- ptr = ptr0 = vend;
-
- if (grub_be_to_cpu32 (*(grub_uint32_t *) ptr) != 0x63825363)
- return;
- ptr = ptr + sizeof (grub_uint32_t);
- while (ptr - ptr0 < limit)
- {
- grub_uint8_t tagtype;
- grub_uint8_t taglength;
-
- tagtype = *ptr++;
-
- /* Pad tag. */
- if (tagtype == 0)
- continue;
-
- /* End tag. */
- if (tagtype == 0xff)
- return;
-
- taglength = *ptr++;
-
- switch (tagtype)
- {
- case 12:
- set_env_limn_ro ("net_pxe_hostname", (char *) ptr, taglength);
- break;
-
- case 15:
- set_env_limn_ro ("net_pxe_domain", (char *) ptr, taglength);
- break;
-
- case 17:
- set_env_limn_ro ("net_pxe_rootpath", (char *) ptr, taglength);
- break;
-
- case 18:
- set_env_limn_ro ("net_pxe_extensionspath", (char *) ptr, taglength);
- break;
-
- /* If you need any other options please contact GRUB
- developpement team. */
- }
-
- ptr += taglength;
- }
-}
-
-static void
-grub_pxe_detect (void)
-{
- struct grub_pxe_bangpxe *pxenv;
- struct grub_pxenv_get_cached_info ci;
- struct grub_pxenv_boot_player *bp;
-
- pxenv = grub_pxe_scan ();
- if (! pxenv)
- return;
-
- ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
- ci.buffer = 0;
- ci.buffer_size = 0;
- grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci, pxe_rm_entry);
- if (ci.status)
- return;
-
- bp = LINEAR (ci.buffer);
-
- grub_pxe_your_ip = bp->your_ip;
- grub_pxe_default_server_ip = bp->server_ip;
- grub_pxe_default_gateway_ip = bp->gateway_ip;
- grub_memcpy (pxe_hwaddr.mac, bp->mac_addr,
- bp->hw_len < sizeof (pxe_hwaddr.mac)
- ? bp->hw_len : sizeof (pxe_hwaddr.mac));
- pxe_hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
- set_env_limn_ro ("net_pxe_boot_file", (char *) bp->boot_file,
- sizeof (bp->boot_file));
- set_env_limn_ro ("net_pxe_dhcp_server_name", (char *) bp->server_name,
- sizeof (bp->server_name));
- parse_dhcp_vendor (&bp->vendor, sizeof (bp->vendor));
- grub_pxe_pxenv = pxenv;
-}
-
static grub_size_t
grub_pxe_recv (struct grub_net_card *dev __attribute__ ((unused)),
void *buf __attribute__ ((unused)),
}
}
-#if 0
static void
set_ip_env (char *varname, grub_uint32_t ip)
{
- char buf[sizeof ("XXX.XXX.XXX.XXX")];
+ char buf[GRUB_NET_MAX_STR_ADDR_LEN];
+ grub_net_network_level_address_t addr;
+ addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+ addr.ipv4 = ip;
- grub_snprintf (buf, sizeof (buf), "%d.%d.%d.%d", (ip & 0xff),
- (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff);
+ grub_net_addr_to_str (&addr, buf);
grub_env_set (varname, buf);
}
{
char *buf;
grub_err_t err;
- grub_uint32_t newip;
-
- err = parse_ip (val, &newip, 0);
+ grub_net_network_level_address_t addr;
+
+ err = grub_net_resolve_address (val, &addr);
if (err)
return 0;
+ if (addr.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4)
+ return NULL;
/* Normalize the IP. */
- buf = grub_xasprintf ("%d.%d.%d.%d", (newip & 0xff), (newip >> 8) & 0xff,
- (newip >> 16) & 0xff, (newip >> 24) & 0xff);
+ buf = grub_malloc (GRUB_NET_MAX_STR_ADDR_LEN);
if (!buf)
return 0;
+ grub_net_addr_to_str (&addr, buf);
- *ip = newip;
+ *ip = addr.ipv4;
return buf;
}
-#endif
-#if 0
static char *
grub_env_write_pxe_default_server (struct grub_env_var *var
__attribute__ ((unused)),
return write_ip_env (&grub_pxe_default_server_ip, val);
}
+#if 0
static char *
grub_env_write_pxe_default_gateway (struct grub_env_var *var
__attribute__ ((unused)),
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);
+ struct grub_pxe_bangpxe *pxenv;
+ struct grub_pxenv_get_cached_info ci;
+ struct grub_net_bootp_ack *bp;
+ char *buf;
+
+ pxenv = grub_pxe_scan ();
+ if (! pxenv)
+ return;
- buf = grub_xasprintf ("%d", grub_pxe_blksize);
- if (buf)
- grub_env_set ("pxe_blksize", buf);
- grub_free (buf);
+ ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
+ ci.buffer = 0;
+ ci.buffer_size = 0;
+ grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci, pxe_rm_entry);
+ if (ci.status)
+ return;
+
+ bp = LINEAR (ci.buffer);
+
+ grub_pxe_default_server_ip = bp->server_ip;
+ grub_pxe_pxenv = pxenv;
+
+ set_ip_env ("pxe_default_server", grub_pxe_default_server_ip);
+ grub_register_variable_hook ("pxe_default_server", 0,
+ grub_env_write_pxe_default_server);
#if 0
- set_ip_env ("pxe_default_server", grub_pxe_default_server_ip);
+ grub_pxe_default_gateway_ip = bp->gateway_ip;
+
+ grub_register_variable_hook ("pxe_default_gateway", 0,
+ grub_env_write_pxe_default_gateway);
#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, pxe_hwaddr,
- GRUB_NET_INTERFACE_PERMANENT
- | GRUB_NET_INTERFACE_ADDRESS_IMMUTABLE
- | GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE);
- if (grub_pxe_default_gateway_ip != grub_pxe_default_server_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_gw", 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", target, inter);
- }
- }
+ buf = grub_xasprintf ("%d", grub_pxe_blksize);
+ if (buf)
+ grub_env_set ("pxe_blksize", buf);
+ grub_free (buf);
+
+ grub_register_variable_hook ("pxe_blksize", 0,
+ grub_env_write_pxe_blocksize);
+
+ grub_memcpy (grub_pxe_card.default_address.mac, bp->mac_addr,
+ bp->hw_len < sizeof (grub_pxe_card.default_address.mac)
+ ? bp->hw_len : sizeof (grub_pxe_card.default_address.mac));
+ grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
+
+ grub_net_app_level_register (&grub_pxefs_fs);
+ grub_net_card_register (&grub_pxe_card);
+ grub_net_configure_by_dhcp_ack ("pxe", &grub_pxe_card,
+ GRUB_NET_INTERFACE_PERMANENT
+ | GRUB_NET_INTERFACE_ADDRESS_IMMUTABLE
+ | GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE,
+ bp, GRUB_PXE_BOOTP_SIZE);
}
GRUB_MOD_FINI(pxe)
#define GRUB_PXE_BOOTP_BCAST 0x8000
#if 1
-#define GRUB_PXE_BOOTP_DHCPVEND 1024 /* DHCP extended vendor field size. */
+#define GRUB_PXE_BOOTP_SIZE (1024 + 236) /* DHCP extended vendor field size. */
#else
-#define GRUB_PXE_BOOTP_DHCPVEND 312 /* DHCP standard vendor field size. */
+#define GRUB_PXE_BOOTP_SIZE (312 + 236) /* DHCP standard vendor field size. */
#endif
#define GRUB_PXE_MIN_BLKSIZE 512
#define GRUB_PXE_TFTP_PORT 69
-#define GRUB_PXE_VM_RFC1048 0x63825363L
-
#define GRUB_PXE_ERR_LEN 0xFFFFFFFF
#ifndef ASM_FILE
grub_uint16_t buffer_limit;
} __attribute__ ((packed));
-#define GRUB_PXE_MAC_ADDR_LEN 16
-
-typedef grub_uint8_t grub_pxe_mac_addr_t[GRUB_PXE_MAC_ADDR_LEN];
-
-struct grub_pxenv_boot_player
-{
- grub_uint8_t opcode;
- grub_uint8_t hw_type; /* hardware type. */
- grub_uint8_t hw_len; /* hardware addr len. */
- grub_uint8_t gate_hops; /* zero it. */
- grub_uint32_t ident; /* random number chosen by client. */
- grub_uint16_t seconds; /* seconds since did initial bootstrap. */
- grub_uint16_t flags;
- grub_uint32_t client_ip;
- grub_uint32_t your_ip;
- grub_uint32_t server_ip;
- grub_uint32_t gateway_ip;
- grub_pxe_mac_addr_t mac_addr;
- grub_uint8_t server_name[64];
- grub_uint8_t boot_file[128];
- union
- {
- grub_uint8_t d[GRUB_PXE_BOOTP_DHCPVEND]; /* raw array of vendor/dhcp options. */
- struct
- {
- grub_uint32_t magic; /* DHCP magic cookie. */
- grub_uint32_t flags; /* bootp flags/opcodes. */
- grub_uint8_t padding[56];
- } v;
- } vendor;
-} __attribute__ ((packed));
-
struct grub_pxenv_tftp_open
{
grub_uint16_t status;
grub_net_network_level_address_t address;
grub_net_link_level_address_t hwaddress;
grub_net_interface_flags_t flags;
+ struct grub_net_bootp_ack *dhcp_ack;
+ grub_size_t dhcp_acklen;
void *data;
};
grub_net_network_level_address_t gw);
+#define GRUB_NET_BOOTP_MAC_ADDR_LEN 16
+
+typedef grub_uint8_t grub_net_bootp_mac_addr_t[GRUB_NET_BOOTP_MAC_ADDR_LEN];
+
+struct grub_net_bootp_ack
+{
+ grub_uint8_t opcode;
+ grub_uint8_t hw_type; /* hardware type. */
+ grub_uint8_t hw_len; /* hardware addr len. */
+ grub_uint8_t gate_hops; /* zero it. */
+ grub_uint32_t ident; /* random number chosen by client. */
+ grub_uint16_t seconds; /* seconds since did initial bootstrap. */
+ grub_uint16_t flags;
+ grub_uint32_t client_ip;
+ grub_uint32_t your_ip;
+ grub_uint32_t server_ip;
+ grub_uint32_t gateway_ip;
+ grub_net_bootp_mac_addr_t mac_addr;
+ grub_uint8_t server_name[64];
+ grub_uint8_t boot_file[128];
+ grub_uint8_t vendor[0];
+} __attribute__ ((packed));
+
+#define GRUB_NET_BOOTP_RFC1048_MAGIC 0x63825363L
+
+struct grub_net_network_level_interface *
+grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_card *card,
+ grub_net_interface_flags_t flags,
+ struct grub_net_bootp_ack *bp,
+ grub_size_t size);
+
+/*
+ Currently suppoerted adresses:
+ IPv4: XXX.XXX.XXX.XXX
+ */
+#define GRUB_NET_MAX_STR_ADDR_LEN sizeof ("XXX.XXX.XXX.XXX")
+
+void
+grub_net_addr_to_str (const grub_net_network_level_address_t *target,
+ char *buf);
+
#endif /* ! GRUB_NET_HEADER */