Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP5:GA
grub2.6869
grub2-efinet-httpboot.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File grub2-efinet-httpboot.patch of Package grub2.6869
Index: grub-2.02~beta2/grub-core/net/bootp.c =================================================================== --- grub-2.02~beta2.orig/grub-core/net/bootp.c +++ grub-2.02~beta2/grub-core/net/bootp.c @@ -121,6 +121,11 @@ parse_dhcp_vendor (const char *name, con taglength); break; + case GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER: + grub_env_set_net_property (name, "vendor_class_identifier", (const char *) ptr, + taglength); + break; + /* If you need any other options please contact GRUB development team. */ } @@ -180,9 +185,83 @@ grub_net_configure_by_dhcp_ack (const ch grub_net_add_route (name, target, inter); } + if (size > OFFSET_OF (vendor, bp)) + parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask); + grub_net_add_ipv4_local (inter, mask); + if (size > OFFSET_OF (boot_file, bp)) - grub_env_set_net_property (name, "boot_file", bp->boot_file, + { + char *cidvar; + const char *cid; + cidvar = grub_xasprintf ("net_%s_%s", name, "vendor_class_identifier"); + cid = grub_env_get (cidvar); + grub_free (cidvar); + + if (cid && grub_strcmp (cid, "HTTPClient") == 0) + { + char *p, *q, *proto, *ip, *pa; + grub_size_t len; + p = grub_strstr (bp->boot_file, "://"); + q = NULL; + if (p) + q = grub_strchr (p + grub_strlen("://"), '/'); + + if (p && q) + { + len = p - bp->boot_file; + proto = grub_malloc (len + 1); + grub_memcpy (proto, bp->boot_file, len); + proto[len] = '\0'; + len = q - (p + 3); + ip = grub_malloc (len + 1); + grub_memcpy (ip, p + 3, len); + ip[len] = '\0'; + pa = grub_strdup (q); + grub_env_set_net_property (name, "boot_file", pa, grub_strlen (pa)); + if (is_def) + { + grub_net_default_server = grub_strdup (ip); + grub_env_set ("net_default_interface", name); + grub_env_export ("net_default_interface"); + } + if (device && !*device) + { + *device = grub_xasprintf ("%s,%s", proto, ip); + grub_print_error (); + } + if (path) + { + *path = grub_strdup (pa); + grub_print_error (); + if (*path) + { + char *slash; + slash = grub_strrchr (*path, '/'); + if (slash) + *slash = 0; + else + **path = 0; + } + } + 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; + + grub_free (proto); + grub_free (ip); + grub_free (pa); + return inter; + } + } + else + grub_env_set_net_property (name, "boot_file", bp->boot_file, sizeof (bp->boot_file)); + } if (is_def) grub_net_default_server = 0; if (is_def && !grub_net_default_server && bp->server_ip) @@ -241,9 +320,6 @@ grub_net_configure_by_dhcp_ack (const ch **path = 0; } } - if (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) @@ -257,54 +333,6 @@ grub_net_configure_by_dhcp_ack (const ch return inter; } -struct grub_dhcpv6_option { - grub_uint16_t code; - grub_uint16_t len; - grub_uint8_t data[0]; -} GRUB_PACKED; - - -struct grub_dhcpv6_iana_option { - grub_uint32_t iaid; - grub_uint32_t t1; - grub_uint32_t t2; - grub_uint8_t data[0]; -} GRUB_PACKED; - -struct grub_dhcpv6_iaaddr_option { - grub_uint8_t addr[16]; - grub_uint32_t preferred_lifetime; - grub_uint32_t valid_lifetime; - grub_uint8_t data[0]; -} GRUB_PACKED; - -struct grub_DUID_LL -{ - grub_uint16_t type; - grub_uint16_t hw_type; - grub_uint8_t hwaddr[6]; -} GRUB_PACKED; - -struct grub_dhcpv6_dns_servers { - grub_uint8_t addr[16]; - grub_uint8_t next_addr[0]; -} GRUB_PACKED; - -//http://tools.ietf.org/html/rfc1035#section-3.1 - -#define DHCPv6_REPLY 7 -#define DHCPv6_ADVERTISE 2 -#define DHCPv6_REQUEST 3 -#define OPTION_BOOTFILE_URL 59 -//RFC3646 http://tools.ietf.org/html/rfc3646 -#define OPTION_DNS_SERVERS 23 -#define OPTION_IA_NA 3 -#define OPTION_IAADDR 5 -#define OPTION_CLIENTID 1 -#define OPTION_SERVERID 2 -#define OPTION_ORO 6 -#define OPTION_ELAPSED_TIME 8 - struct grub_dhcpv6_session { struct grub_dhcpv6_session *next; @@ -554,19 +582,15 @@ find_bootfile_url (const struct grub_net ip_start = ip_end = NULL; ip_start = bootfile_url + grub_strlen(pr); + path = grub_strchr (ip_start, '/'); - if (*ip_start != '[') - ip_start = NULL; - else - ip_end = grub_strchr (++ip_start, ']'); - - if (!ip_start || !ip_end) + if (!ip_start || !path) { - grub_error (GRUB_ERR_IO, N_("IPv6-address not in square brackets")); + grub_error (GRUB_ERR_IO, N_("invalid url format")); goto cleanup; } - ip_len = ip_end - ip_start; + ip_len = path - ip_start; if (proto) { @@ -582,6 +606,13 @@ find_bootfile_url (const struct grub_net if (server_ip) { + + if (ip_len > 2 && *ip_start == '[' && *(ip_start + ip_len - 1) == ']') + { + ++ip_start; + ip_len -= 2; + } + *server_ip = grub_malloc (ip_len + 1); if (!*server_ip) @@ -591,8 +622,6 @@ find_bootfile_url (const struct grub_net *(*server_ip + ip_len) = '\0'; } - path = ip_end + 1; - if (boot_file) { *boot_file = grub_strdup (path); @@ -747,8 +776,8 @@ grub_net_configure_by_dhcpv6_adv (const popt = (struct grub_dhcpv6_option*) nb->data; popt->code = grub_cpu_to_be16 (OPTION_ORO); popt->len = grub_cpu_to_be16 (4); - *((grub_uint16_t *) popt->data) = grub_cpu_to_be16 (OPTION_BOOTFILE_URL); - *((grub_uint16_t *) (popt->data + 2)) = grub_cpu_to_be16 (OPTION_DNS_SERVERS); + grub_set_unaligned16 (popt->data, grub_cpu_to_be16 (OPTION_BOOTFILE_URL)); + grub_set_unaligned16 (popt->data + 2, grub_cpu_to_be16 (OPTION_DNS_SERVERS)); err = grub_netbuff_push (nb, 6); if (err) @@ -766,7 +795,7 @@ grub_net_configure_by_dhcpv6_adv (const if (elapsed > 0xffff) elapsed = 0xffff; - *((grub_uint16_t *) popt->data) = grub_cpu_to_be16 ((grub_uint16_t)elapsed); + grub_set_unaligned16 (popt->data, grub_cpu_to_be16 ((grub_uint16_t)elapsed)); err = grub_netbuff_push (nb, 4); if (err) @@ -1381,7 +1410,7 @@ grub_cmd_bootp6 (struct grub_command *cm opt = (struct grub_dhcpv6_option *)nb->data; opt->code = grub_cpu_to_be16 (OPTION_ELAPSED_TIME); opt->len = grub_cpu_to_be16 (2); - *((grub_uint16_t *) opt->data) = 0; + grub_set_unaligned16 (opt->data, 0); err = grub_netbuff_push (nb, sizeof(*duid) + 4); if (err) Index: grub-2.02~beta2/grub-core/net/drivers/efi/efinet.c =================================================================== --- grub-2.02~beta2.orig/grub-core/net/drivers/efi/efinet.c +++ grub-2.02~beta2/grub-core/net/drivers/efi/efinet.c @@ -23,12 +23,15 @@ #include <grub/efi/api.h> #include <grub/efi/efi.h> #include <grub/i18n.h> +#include <grub/net/netbuff.h> GRUB_MOD_LICENSE ("GPLv3+"); /* GUID. */ static grub_efi_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID; static grub_efi_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID; +static grub_efi_guid_t ip4_config_guid = GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID; +static grub_efi_guid_t ip6_config_guid = GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID; static grub_err_t send_card_buffer (struct grub_net_card *dev, @@ -364,6 +367,380 @@ grub_efinet_findcards (void) grub_free (handles); } +static grub_efi_handle_t +grub_efi_locate_device_path (grub_efi_guid_t *protocol, grub_efi_device_path_t *device_path, + grub_efi_device_path_t **r_device_path) +{ + grub_efi_handle_t handle; + grub_efi_status_t status; + + status = efi_call_3 (grub_efi_system_table->boot_services->locate_device_path, + protocol, &device_path, &handle); + + if (status != GRUB_EFI_SUCCESS) + return 0; + + if (r_device_path) + *r_device_path = device_path; + + return handle; +} + +static grub_efi_ipv4_address_t * +grub_dns_server_ip4_address (grub_efi_device_path_t *dp, grub_efi_uintn_t *num_dns) +{ + grub_efi_handle_t hnd; + grub_efi_status_t status; + grub_efi_ip4_config2_protocol_t *conf; + grub_efi_ipv4_address_t *addrs; + grub_efi_uintn_t data_size = 1 * sizeof (grub_efi_ipv4_address_t); + + hnd = grub_efi_locate_device_path (&ip4_config_guid, dp, NULL); + + if (!hnd) + return 0; + + conf = grub_efi_open_protocol (hnd, &ip4_config_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + if (!conf) + return 0; + + addrs = grub_malloc (data_size); + if (!addrs) + return 0; + + status = efi_call_4 (conf->get_data, conf, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, + &data_size, addrs); + + if (status == GRUB_EFI_BUFFER_TOO_SMALL) + { + grub_free (addrs); + addrs = grub_malloc (data_size); + if (!addrs) + return 0; + + status = efi_call_4 (conf->get_data, conf, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, + &data_size, addrs); + } + + if (status != GRUB_EFI_SUCCESS) + { + grub_free (addrs); + return 0; + } + + *num_dns = data_size / sizeof (grub_efi_ipv4_address_t); + return addrs; +} + +static grub_efi_ipv6_address_t * +grub_dns_server_ip6_address (grub_efi_device_path_t *dp, grub_efi_uintn_t *num_dns) +{ + grub_efi_handle_t hnd; + grub_efi_status_t status; + grub_efi_ip6_config_protocol_t *conf; + grub_efi_ipv6_address_t *addrs; + grub_efi_uintn_t data_size = 1 * sizeof (grub_efi_ipv6_address_t); + + hnd = grub_efi_locate_device_path (&ip6_config_guid, dp, NULL); + + if (!hnd) + return 0; + + conf = grub_efi_open_protocol (hnd, &ip6_config_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + if (!conf) + return 0; + + addrs = grub_malloc (data_size); + if (!addrs) + return 0; + + status = efi_call_4 (conf->get_data, conf, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, + &data_size, addrs); + + if (status == GRUB_EFI_BUFFER_TOO_SMALL) + { + grub_free (addrs); + addrs = grub_malloc (data_size); + if (!addrs) + return 0; + + status = efi_call_4 (conf->get_data, conf, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, + &data_size, addrs); + } + + if (status != GRUB_EFI_SUCCESS) + { + grub_free (addrs); + return 0; + } + + *num_dns = data_size / sizeof (grub_efi_ipv6_address_t); + return addrs; +} + +static struct grub_net_buff * +grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *use_ipv6) +{ + grub_efi_uint16_t uri_len; + grub_efi_device_path_t *ldp, *ddp; + grub_efi_uri_device_path_t *uri_dp; + struct grub_net_buff *nb; + grub_err_t err; + + ddp = grub_efi_duplicate_device_path (dp); + ldp = grub_efi_find_last_device_path (ddp); + + if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE + || GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE) + { + grub_free (ddp); + return NULL; + } + + uri_len = GRUB_EFI_DEVICE_PATH_LENGTH (ldp) > 4 ? GRUB_EFI_DEVICE_PATH_LENGTH (ldp) - 4 : 0; + + if (!uri_len) + { + grub_free (ddp); + return NULL; + } + + uri_dp = (grub_efi_uri_device_path_t *) ldp; + + ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; + ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + ldp->length = sizeof (*ldp); + + ldp = grub_efi_find_last_device_path (ddp); + + if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE + || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE + && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) + { + grub_free (ddp); + return NULL; + } + + nb = grub_netbuff_alloc (512); + if (!nb) + return NULL; + + if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE) + { + grub_efi_ipv4_device_path_t *ipv4 = (grub_efi_ipv4_device_path_t *) ldp; + struct grub_net_bootp_packet *bp; + grub_uint8_t *ptr; + grub_efi_ipv4_address_t *dns; + grub_efi_uintn_t num_dns; + + bp = (struct grub_net_bootp_packet *) nb->tail; + err = grub_netbuff_put (nb, sizeof (*bp) + 4); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + + if (sizeof(bp->boot_file) < uri_len) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + grub_memcpy (bp->boot_file, uri_dp->uri, uri_len); + grub_memcpy (&bp->your_ip, ipv4->local_ip_address, sizeof (bp->your_ip)); + grub_memcpy (&bp->server_ip, ipv4->remote_ip_address, sizeof (bp->server_ip)); + + bp->vendor[0] = GRUB_NET_BOOTP_RFC1048_MAGIC_0; + bp->vendor[1] = GRUB_NET_BOOTP_RFC1048_MAGIC_1; + bp->vendor[2] = GRUB_NET_BOOTP_RFC1048_MAGIC_2; + bp->vendor[3] = GRUB_NET_BOOTP_RFC1048_MAGIC_3; + + ptr = nb->tail; + err = grub_netbuff_put (nb, sizeof (ipv4->subnet_mask) + 2); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + *ptr++ = GRUB_NET_BOOTP_NETMASK; + *ptr++ = sizeof (ipv4->subnet_mask); + grub_memcpy (ptr, ipv4->subnet_mask, sizeof (ipv4->subnet_mask)); + + ptr = nb->tail; + err = grub_netbuff_put (nb, sizeof (ipv4->gateway_ip_address) + 2); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + *ptr++ = GRUB_NET_BOOTP_ROUTER; + *ptr++ = sizeof (ipv4->gateway_ip_address); + grub_memcpy (ptr, ipv4->gateway_ip_address, sizeof (ipv4->gateway_ip_address)); + + ptr = nb->tail; + err = grub_netbuff_put (nb, sizeof ("HTTPClient") + 1); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + *ptr++ = GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER; + *ptr++ = sizeof ("HTTPClient") - 1; + grub_memcpy (ptr, "HTTPClient", sizeof ("HTTPClient") - 1); + + dns = grub_dns_server_ip4_address (dp, &num_dns); + if (dns) + { + grub_efi_uintn_t size_dns = sizeof (*dns) * num_dns; + + ptr = nb->tail; + err = grub_netbuff_put (nb, size_dns + 2); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + *ptr++ = GRUB_NET_BOOTP_DNS; + *ptr++ = size_dns; + grub_memcpy (ptr, dns, size_dns); + } + + ptr = nb->tail; + err = grub_netbuff_put (nb, 1); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + *ptr = 0xff; + *use_ipv6 = 0; + + ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; + ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + ldp->length = sizeof (*ldp); + ldp = grub_efi_find_last_device_path (ddp); + + if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE) + { + grub_efi_mac_address_device_path_t *mac = (grub_efi_mac_address_device_path_t *) ldp; + bp->hw_type = mac->if_type; + bp->hw_len = sizeof (bp->mac_addr); + grub_memcpy (bp->mac_addr, mac->mac_address, bp->hw_len); + } + } + else + { + grub_efi_ipv6_device_path_t *ipv6 = (grub_efi_ipv6_device_path_t *) ldp; + + struct grub_net_dhcpv6_packet *d6p; + struct grub_dhcpv6_option *opt; + struct grub_dhcpv6_iana_option *iana; + struct grub_dhcpv6_iaaddr_option *iaaddr; + grub_efi_ipv6_address_t *dns; + grub_efi_uintn_t num_dns; + + d6p = (struct grub_net_dhcpv6_packet *)nb->tail; + err = grub_netbuff_put (nb, sizeof(*d6p)); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + d6p->message_type = DHCPv6_REPLY; + + opt = (struct grub_dhcpv6_option *)nb->tail; + err = grub_netbuff_put (nb, sizeof(*opt)); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + opt->code = grub_cpu_to_be16_compile_time (OPTION_IA_NA); + opt->len = grub_cpu_to_be16_compile_time (sizeof(*iana) + sizeof(*opt) + sizeof(*iaaddr)); + + err = grub_netbuff_put (nb, sizeof(*iana)); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + + opt = (struct grub_dhcpv6_option *)nb->tail; + err = grub_netbuff_put (nb, sizeof(*opt)); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + opt->code = grub_cpu_to_be16_compile_time (OPTION_IAADDR); + opt->len = grub_cpu_to_be16_compile_time (sizeof (*iaaddr)); + + iaaddr = (struct grub_dhcpv6_iaaddr_option *)nb->tail; + err = grub_netbuff_put (nb, sizeof(*iaaddr)); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + grub_memcpy (iaaddr->addr, ipv6->local_ip_address, sizeof(ipv6->local_ip_address)); + + opt = (struct grub_dhcpv6_option *)nb->tail; + err = grub_netbuff_put (nb, sizeof(*opt) + uri_len); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + opt->code = grub_cpu_to_be16_compile_time (OPTION_BOOTFILE_URL); + opt->len = grub_cpu_to_be16 (uri_len); + grub_memcpy (opt->data, uri_dp->uri, uri_len); + + dns = grub_dns_server_ip6_address (dp, &num_dns); + if (dns) + { + grub_efi_uintn_t size_dns = sizeof (*dns) * num_dns; + + opt = (struct grub_dhcpv6_option *)nb->tail; + err = grub_netbuff_put (nb, sizeof(*opt) + size_dns); + if (err) + { + grub_free (ddp); + grub_netbuff_free (nb); + return NULL; + } + opt->code = grub_cpu_to_be16_compile_time (OPTION_DNS_SERVERS); + opt->len = grub_cpu_to_be16_compile_time (size_dns); + grub_memcpy (opt->data, dns, size_dns); + } + + *use_ipv6 = 1; + } + + return nb; +} + + static void grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, char **path) @@ -380,6 +757,11 @@ grub_efi_net_config_real (grub_efi_handl grub_efi_device_path_t *cdp; struct grub_efi_pxe *pxe; struct grub_efi_pxe_mode *pxe_mode; + grub_uint8_t *dhcp_ack; + grub_size_t dhcp_ack_size ; + int ipv6; + struct grub_net_buff *nb = NULL; + if (card->driver != &efidriver) continue; cdp = grub_efi_get_device_path (card->efi_handle); @@ -399,11 +781,21 @@ grub_efi_net_config_real (grub_efi_handl ldp = grub_efi_find_last_device_path (dp); if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE - && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) + && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE + && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)) continue; dup_dp = grub_efi_duplicate_device_path (dp); if (!dup_dp) continue; + + if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_URI_DEVICE_PATH_SUBTYPE) + { + dup_ldp = grub_efi_find_last_device_path (dup_dp); + dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; + dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + dup_ldp->length = sizeof (*dup_ldp); + } + dup_ldp = grub_efi_find_last_device_path (dup_dp); dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; @@ -415,29 +807,44 @@ grub_efi_net_config_real (grub_efi_handl } pxe = grub_efi_open_protocol (hnd, &pxe_io_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (! pxe) - continue; - pxe_mode = pxe->mode; + if (!pxe) + { + nb = grub_efinet_create_dhcp_ack_from_device_path (dp, &ipv6); + if (!nb) + continue; + dhcp_ack = nb->head; + dhcp_ack_size = nb->tail - nb->head; + } + else + { + pxe_mode = pxe->mode; + dhcp_ack = (grub_uint8_t *) &pxe_mode->dhcp_ack; + dhcp_ack_size = sizeof (pxe_mode->dhcp_ack); + ipv6 = pxe_mode->using_ipv6; + } - if (pxe_mode->using_ipv6) + if (ipv6) { grub_net_configure_by_dhcpv6_reply (card->name, card, 0, (struct grub_net_dhcpv6_packet *) - &pxe_mode->dhcp_ack, - sizeof (pxe_mode->dhcp_ack), + dhcp_ack, + dhcp_ack_size, 1, device, path); if (grub_errno) grub_print_error (); - return; } else { grub_net_configure_by_dhcp_ack (card->name, card, 0, (struct grub_net_bootp_packet *) - &pxe_mode->dhcp_ack, - sizeof (pxe_mode->dhcp_ack), + dhcp_ack, + dhcp_ack_size, 1, device, path); } + + if (nb) + grub_netbuff_free (nb); + return; } } Index: grub-2.02~beta2/grub-core/net/http.c =================================================================== --- grub-2.02~beta2.orig/grub-core/net/http.c +++ grub-2.02~beta2/grub-core/net/http.c @@ -312,24 +312,49 @@ http_establish (struct grub_file *file, int i; struct grub_net_buff *nb; grub_err_t err; + grub_net_network_level_netaddress_t addr; + char *host; + + grub_error_push (); + err = grub_net_resolve_net_address (file->device->net->server, &addr); + grub_error_pop (); + + if (err == GRUB_ERR_NONE && + addr.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6 && + addr.ipv6.masksize == 128) + { + int hostsz = grub_strlen (file->device->net->server) + 3; + host = grub_malloc (hostsz); + if (host) + grub_snprintf (host, hostsz, "[%s]", file->device->net->server); + } + else + host = grub_strdup (file->device->net->server); + + if (!host) + return grub_errno; nb = grub_netbuff_alloc (GRUB_NET_TCP_RESERVE_SIZE + sizeof ("GET ") - 1 + grub_strlen (data->filename) + sizeof (" HTTP/1.1\r\nHost: ") - 1 - + grub_strlen (file->device->net->server) + + grub_strlen (host) + sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n") - 1 + sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX" "-\r\n\r\n")); if (!nb) - return grub_errno; + { + grub_free (host); + return grub_errno; + } grub_netbuff_reserve (nb, GRUB_NET_TCP_RESERVE_SIZE); ptr = nb->tail; err = grub_netbuff_put (nb, sizeof ("GET ") - 1); if (err) { + grub_free (host); grub_netbuff_free (nb); return err; } @@ -340,6 +365,7 @@ http_establish (struct grub_file *file, err = grub_netbuff_put (nb, grub_strlen (data->filename)); if (err) { + grub_free (host); grub_netbuff_free (nb); return err; } @@ -349,6 +375,7 @@ http_establish (struct grub_file *file, err = grub_netbuff_put (nb, sizeof (" HTTP/1.1\r\nHost: ") - 1); if (err) { + grub_free (host); grub_netbuff_free (nb); return err; } @@ -356,14 +383,15 @@ http_establish (struct grub_file *file, sizeof (" HTTP/1.1\r\nHost: ") - 1); ptr = nb->tail; - err = grub_netbuff_put (nb, grub_strlen (file->device->net->server)); + err = grub_netbuff_put (nb, grub_strlen (host)); if (err) { + grub_free (host); grub_netbuff_free (nb); return err; } - grub_memcpy (ptr, file->device->net->server, - grub_strlen (file->device->net->server)); + grub_memcpy (ptr, host, grub_strlen (host)); + grub_free (host); ptr = nb->tail; err = grub_netbuff_put (nb, @@ -381,9 +409,8 @@ http_establish (struct grub_file *file, ptr = nb->tail; grub_snprintf ((char *) ptr, sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX-" - "\r\n" "\r\n"), - "Range: bytes=%" PRIuGRUB_UINT64_T "-\r\n\r\n", + "Range: bytes=%" PRIuGRUB_UINT64_T "-\r\n", offset); grub_netbuff_put (nb, grub_strlen ((char *) ptr)); } Index: grub-2.02~beta2/include/grub/efi/api.h =================================================================== --- grub-2.02~beta2.orig/include/grub/efi/api.h +++ grub-2.02~beta2/include/grub/efi/api.h @@ -286,6 +286,16 @@ { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \ } +#define GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID \ + { 0x5b446ed1, 0xe30b, 0x4faa, \ + { 0x87, 0x1a, 0x36, 0x54, 0xec, 0xa3, 0x60, 0x80 } \ + } + +#define GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID \ + { 0x937fe521, 0x95ae, 0x4d1a, \ + { 0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \ + } + struct grub_efi_sal_system_table { grub_uint32_t signature; @@ -776,6 +786,8 @@ struct grub_efi_ipv4_device_path grub_efi_uint16_t remote_port; grub_efi_uint16_t protocol; grub_efi_uint8_t static_ip_address; + grub_efi_ipv4_address_t gateway_ip_address; + grub_efi_ipv4_address_t subnet_mask; } GRUB_PACKED; typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t; @@ -830,6 +842,15 @@ struct grub_efi_sata_device_path } GRUB_PACKED; typedef struct grub_efi_sata_device_path grub_efi_sata_device_path_t; +#define GRUB_EFI_URI_DEVICE_PATH_SUBTYPE 24 + +struct grub_efi_uri_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t uri[0]; +} GRUB_PACKED; +typedef struct grub_efi_uri_device_path grub_efi_uri_device_path_t; + #define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10 /* Media Device Path. */ @@ -1627,6 +1648,72 @@ struct grub_efi_block_io }; typedef struct grub_efi_block_io grub_efi_block_io_t; +enum grub_efi_ip4_config2_data_type { + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_POLICY, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_GATEWAY, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MAXIMUM +}; +typedef enum grub_efi_ip4_config2_data_type grub_efi_ip4_config2_data_type_t; + +struct grub_efi_ip4_config2_protocol +{ + grub_efi_status_t (*set_data) (struct grub_efi_ip4_config2_protocol *this, + grub_efi_ip4_config2_data_type_t data_type, + grub_efi_uintn_t data_size, + void *data); + + grub_efi_status_t (*get_data) (struct grub_efi_ip4_config2_protocol *this, + grub_efi_ip4_config2_data_type_t data_type, + grub_efi_uintn_t *data_size, + void *data); + + grub_efi_status_t (*register_data_notify) (struct grub_efi_ip4_config2_protocol *this, + grub_efi_ip4_config2_data_type_t data_type, + grub_efi_event_t event); + + grub_efi_status_t (*unregister_datanotify) (struct grub_efi_ip4_config2_protocol *this, + grub_efi_ip4_config2_data_type_t data_type, + grub_efi_event_t event); +}; +typedef struct grub_efi_ip4_config2_protocol grub_efi_ip4_config2_protocol_t; + +enum grub_efi_ip6_config_data_type { + GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_ALT_INTERFACEID, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_POLICY, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_DUP_ADDR_DETECT_TRANSMITS, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_GATEWAY, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_MAXIMUM +}; +typedef enum grub_efi_ip6_config_data_type grub_efi_ip6_config_data_type_t; + +struct grub_efi_ip6_config_protocol +{ + grub_efi_status_t (*set_data) (struct grub_efi_ip6_config_protocol *this, + grub_efi_ip6_config_data_type_t data_type, + grub_efi_uintn_t data_size, + void *data); + + grub_efi_status_t (*get_data) (struct grub_efi_ip6_config_protocol *this, + grub_efi_ip6_config_data_type_t data_type, + grub_efi_uintn_t *data_size, + void *data); + + grub_efi_status_t (*register_data_notify) (struct grub_efi_ip6_config_protocol *this, + grub_efi_ip6_config_data_type_t data_type, + grub_efi_event_t event); + + grub_efi_status_t (*unregister_datanotify) (struct grub_efi_ip6_config_protocol *this, + grub_efi_ip6_config_data_type_t data_type, + grub_efi_event_t event); +}; +typedef struct grub_efi_ip6_config_protocol grub_efi_ip6_config_protocol_t; + #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) Index: grub-2.02~beta2/include/grub/net.h =================================================================== --- grub-2.02~beta2.orig/include/grub/net.h +++ grub-2.02~beta2/include/grub/net.h @@ -433,6 +433,53 @@ struct grub_net_dhcpv6_packet grub_uint8_t dhcp_options[0]; } GRUB_PACKED; +struct grub_dhcpv6_option { + grub_uint16_t code; + grub_uint16_t len; + grub_uint8_t data[0]; +} GRUB_PACKED; + +struct grub_dhcpv6_iana_option { + grub_uint32_t iaid; + grub_uint32_t t1; + grub_uint32_t t2; + grub_uint8_t data[0]; +} GRUB_PACKED; + +struct grub_dhcpv6_iaaddr_option { + grub_uint8_t addr[16]; + grub_uint32_t preferred_lifetime; + grub_uint32_t valid_lifetime; + grub_uint8_t data[0]; +} GRUB_PACKED; + +struct grub_DUID_LL +{ + grub_uint16_t type; + grub_uint16_t hw_type; + grub_uint8_t hwaddr[6]; +} GRUB_PACKED; + +struct grub_dhcpv6_dns_servers { + grub_uint8_t addr[16]; + grub_uint8_t next_addr[0]; +} GRUB_PACKED; + +//http://tools.ietf.org/html/rfc1035#section-3.1 + +#define DHCPv6_REPLY 7 +#define DHCPv6_ADVERTISE 2 +#define DHCPv6_REQUEST 3 +#define OPTION_BOOTFILE_URL 59 +//RFC3646 http://tools.ietf.org/html/rfc3646 +#define OPTION_DNS_SERVERS 23 +#define OPTION_IA_NA 3 +#define OPTION_IAADDR 5 +#define OPTION_CLIENTID 1 +#define OPTION_SERVERID 2 +#define OPTION_ORO 6 +#define OPTION_ELAPSED_TIME 8 + #define GRUB_NET_BOOTP_RFC1048_MAGIC_0 0x63 #define GRUB_NET_BOOTP_RFC1048_MAGIC_1 0x82 #define GRUB_NET_BOOTP_RFC1048_MAGIC_2 0x53 @@ -448,6 +495,7 @@ enum GRUB_NET_BOOTP_DOMAIN = 0x0f, GRUB_NET_BOOTP_ROOT_PATH = 0x11, GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12, + GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER = 0x3C, GRUB_NET_BOOTP_END = 0xff };
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor