/*
- * Copy the string from source to dest till newline or comma(,) is seen
+ * Copy the string from source to dest until the end of string or comma is seen
* in the source.
* Move source and dest pointers respectively.
* Returns pointer to the start of the string that has just been copied.
while (**source != ',' && **source != '\0')
*(*dest)++ = *(*source)++;
if (**source != '\0')
- *(*source)++;
+ (void)*(*source)++;
**dest = '\0';
- *(*dest)++;
+ (void)*(*dest)++;
return ret;
}
DHCP_PAD = 0,
DHCP_NETMASK = 1,
DHCP_ROUTERS = 3,
- DHCP_DNS = 6,
DHCP_END = 255,
};
* 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
{
/*
* 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;
/* 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);
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;
}
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);
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;
}
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);