X-Git-Url: http://git.ozlabs.org/?p=yaboot.git;a=blobdiff_plain;f=second%2Ffile.c;h=a52b664e8900c6e789764c696f5d4e61ab9fab0d;hp=6b997b0589b0506155088d25d809eca41e02781b;hb=3cbe90093acba116c5fc46beaf50f74c7c8a1b69;hpb=11f8168a5e7a6f966693e371697920e0be7abc0f diff --git a/second/file.c b/second/file.c index 6b997b0..a52b664 100644 --- a/second/file.c +++ b/second/file.c @@ -172,6 +172,7 @@ extract_ipv4_args(char *imagepath, struct boot_fspec_t *result) result->giaddr = is_valid_ipv4_str(scopy(&str, &args)); result->bootp_retries = scopy(&str, &args); result->tftp_retries = scopy(&str, &args); + result->subnetmask = is_valid_ipv4_str(scopy(&str, &args)); if (*args) { result->addl_params = strdup(args); if (!result->addl_params) @@ -185,7 +186,6 @@ enum dhcp_options { DHCP_PAD = 0, DHCP_NETMASK = 1, DHCP_ROUTERS = 3, - DHCP_DNS = 6, DHCP_END = 255, }; @@ -217,13 +217,18 @@ extract_vendor_options(struct bootp_packet *packet, struct boot_fspec_t *result) * it's malformed. :( */ while (options[i] != DHCP_END) { __u8 tag = options[i++], len; - __u32 value; + __u32 value = 0; if (tag == DHCP_PAD) continue; len = options[i++]; - memcpy(&value, &options[i], len); + /* Clamp the maxium length of the memcpy() to the right size for + * value. */ + if (len > sizeof(value)) + memcpy(&value, &options[i], sizeof(value)); + else + memcpy(&value, &options[i], len); #if DEBUG { @@ -237,7 +242,12 @@ extract_vendor_options(struct bootp_packet *packet, struct boot_fspec_t *result) switch (tag) { case DHCP_NETMASK: - /* FIXME: do we need to grok the subnet mask? */ + if ((result->subnetmask == NULL || + *(result->subnetmask) == '\x0') && value != 0) { + result->subnetmask = ipv4_to_str(value); + DEBUG_F("Storing %s as subnetmask from options\n", + result->subnetmask); + } break; case DHCP_ROUTERS: if ((result->giaddr == NULL || *(result->giaddr) == '\x0') @@ -255,10 +265,8 @@ extract_vendor_options(struct bootp_packet *packet, struct boot_fspec_t *result) /* * Check netinfo for ipv4 parameters and add them to the fspec iff the * fspec has no existing value. - * - * Returns 1 on success, 0 on failure. */ -static int +static void extract_netinfo_args(struct boot_fspec_t *result) { struct bootp_packet *packet; @@ -266,7 +274,7 @@ extract_netinfo_args(struct boot_fspec_t *result) /* Check to see if we can get the [scyg]iaddr fields from netinfo */ packet = prom_get_netinfo(); if (!packet) - return 0; + return; DEBUG_F("We have a boot packet\n"); DEBUG_F(" siaddr = <%x>\n", packet->siaddr); @@ -298,6 +306,48 @@ extract_netinfo_args(struct boot_fspec_t *result) result->giaddr = ipv4_to_str(packet->siaddr); DEBUG_F("Forcing giaddr to siaddr <%s>\n", result->giaddr); } +} + +/* + * Extract all the ipv6 arguments from the bootpath provided and fill result + * Syntax: ipv6,[dhcpv6[=diaddr,]]ciaddr=c_iaddr,giaddr=g_iaddr,siaddr=s_iaddr, + * filename=file_name,tftp-retries=tftp_retries,blksize=block_size + * Returns 1 on success, 0 on failure. + */ +static int +extract_ipv6_args(char *imagepath, struct boot_fspec_t *result) +{ + char *str, *tmp; + int total_len; + + result->is_ipv6 = 1; + + /* Just allocate the max required size */ + total_len = strlen(imagepath) + 1; + str = malloc(total_len); + if (!str) + return 0; + + if ((tmp = strstr(imagepath, "dhcpv6=")) != NULL) + result->dhcpv6 = scopy(&str, &tmp); + + if ((tmp = strstr(imagepath, "ciaddr=")) != NULL) + result->ciaddr = scopy(&str, &tmp); + + if ((tmp = strstr(imagepath, "giaddr=")) != NULL) + result->giaddr = scopy(&str, &tmp); + + if ((tmp = strstr(imagepath, "siaddr=")) != NULL) + result->siaddr = scopy(&str, &tmp); + + if ((tmp = strstr(imagepath, "filename=")) != NULL) + result->file = scopy(&str, &tmp); + + if ((tmp = strstr(imagepath, "tftp-retries=")) != NULL) + result->tftp_retries = scopy(&str, &tmp); + + if ((tmp = strstr(imagepath, "blksize=")) != NULL) + result->blksize = scopy(&str, &tmp); return 1; } @@ -316,9 +366,13 @@ extract_netboot_args(char *imagepath, struct boot_fspec_t *result) if (!imagepath) return 1; - ret = extract_ipv4_args(imagepath, result); - ret |= extract_netinfo_args(result); + if (strstr(imagepath, TOK_IPV6)) + ret = extract_ipv6_args(imagepath, result); + else + ret = extract_ipv4_args(imagepath, result); + extract_netinfo_args(result); + DEBUG_F("ipv6 = <%d>\n", result->is_ipv6); DEBUG_F("siaddr = <%s>\n", result->siaddr); DEBUG_F("file = <%s>\n", result->file); DEBUG_F("ciaddr = <%s>\n", result->ciaddr); @@ -326,7 +380,9 @@ extract_netboot_args(char *imagepath, struct boot_fspec_t *result) DEBUG_F("bootp_retries = <%s>\n", result->bootp_retries); DEBUG_F("tftp_retries = <%s>\n", result->tftp_retries); DEBUG_F("addl_params = <%s>\n", result->addl_params); - + DEBUG_F("dhcpv6 = <%s>\n", result->dhcpv6); + DEBUG_F("blksize = <%s>\n", result->blksize); + return ret; } @@ -619,6 +675,9 @@ int open_file(struct boot_fspec_t* spec, struct boot_file_t* file) case FILE_DEVICE_BLOCK: DEBUG_F("device is a block device\n"); return file_block_open(file, spec, spec->part); + case FILE_DEVICE_ISCSI: + DEBUG_F("device is a iSCSI device\n"); + return file_block_open(file, spec, spec->part); case FILE_DEVICE_NET: DEBUG_F("device is a network device\n"); return file_net_open(file, spec);