+
+int pb_protocol_deserialise_system_info(struct system_info *sysinfo,
+ const struct pb_protocol_message *message)
+{
+ unsigned int len, i;
+ const char *pos;
+ int rc = -1;
+ char *tmp;
+
+ len = message->payload_len;
+ pos = message->payload;
+
+ /* type and identifier strings */
+ if (read_string(sysinfo, &pos, &len, &sysinfo->type))
+ goto out;
+
+ if (read_string(sysinfo, &pos, &len, &sysinfo->identifier))
+ goto out;
+
+ /* Platform version strings for openpower platforms */
+ if (read_u32(&pos, &len, &sysinfo->n_primary))
+ goto out;
+ sysinfo->platform_primary = talloc_array(sysinfo, char *,
+ sysinfo->n_primary);
+ for (i = 0; i < sysinfo->n_primary; i++) {
+ if (read_string(sysinfo, &pos, &len, &tmp))
+ goto out;
+ sysinfo->platform_primary[i] = talloc_strdup(sysinfo, tmp);
+ }
+
+ if (read_u32(&pos, &len, &sysinfo->n_other))
+ goto out;
+ sysinfo->platform_other = talloc_array(sysinfo, char *,
+ sysinfo->n_other);
+ for (i = 0; i < sysinfo->n_other; i++) {
+ if (read_string(sysinfo, &pos, &len, &tmp))
+ goto out;
+ sysinfo->platform_other[i] = talloc_strdup(sysinfo, tmp);
+ }
+
+ /* BMC version strings for openpower platforms */
+ if (read_u32(&pos, &len, &sysinfo->n_bmc_current))
+ goto out;
+ sysinfo->bmc_current = talloc_array(sysinfo, char *,
+ sysinfo->n_bmc_current);
+ for (i = 0; i < sysinfo->n_bmc_current; i++) {
+ if (read_string(sysinfo, &pos, &len, &tmp))
+ goto out;
+ sysinfo->bmc_current[i] = talloc_strdup(sysinfo, tmp);
+ }
+
+ if (read_u32(&pos, &len, &sysinfo->n_bmc_golden))
+ goto out;
+ sysinfo->bmc_golden = talloc_array(sysinfo, char *,
+ sysinfo->n_bmc_golden);
+ for (i = 0; i < sysinfo->n_bmc_golden; i++) {
+ if (read_string(sysinfo, &pos, &len, &tmp))
+ goto out;
+ sysinfo->bmc_golden[i] = talloc_strdup(sysinfo, tmp);
+ }
+
+ /* number of interfaces */
+ if (read_u32(&pos, &len, &sysinfo->n_interfaces))
+ goto out;
+
+ sysinfo->interfaces = talloc_array(sysinfo, struct interface_info *,
+ sysinfo->n_interfaces);
+
+ for (i = 0; i < sysinfo->n_interfaces; i++) {
+ struct interface_info *if_info = talloc(sysinfo,
+ struct interface_info);
+
+ if (read_u32(&pos, &len, &if_info->hwaddr_size))
+ goto out;
+
+ if (len < if_info->hwaddr_size)
+ goto out;
+
+ if_info->hwaddr = talloc_memdup(if_info, pos,
+ if_info->hwaddr_size);
+ pos += if_info->hwaddr_size;
+ len -= if_info->hwaddr_size;
+
+ if (read_string(if_info, &pos, &len, &if_info->name))
+ goto out;
+
+ if_info->link = *(bool *)pos;
+ pos += sizeof(if_info->link);
+
+ sysinfo->interfaces[i] = if_info;
+ }
+
+ /* number of interfaces */
+ if (read_u32(&pos, &len, &sysinfo->n_blockdevs))
+ goto out;
+
+ sysinfo->blockdevs = talloc_array(sysinfo, struct blockdev_info *,
+ sysinfo->n_blockdevs);
+
+ for (i = 0; i < sysinfo->n_blockdevs; i++) {
+ struct blockdev_info *bd_info = talloc(sysinfo,
+ struct blockdev_info);
+
+ if (read_string(bd_info, &pos, &len, &bd_info->name))
+ goto out;
+
+ if (read_string(bd_info, &pos, &len, &bd_info->uuid))
+ goto out;
+
+ if (read_string(bd_info, &pos, &len, &bd_info->mountpoint))
+ goto out;
+
+ sysinfo->blockdevs[i] = bd_info;
+ }
+
+ for (i = 0; i < HWADDR_SIZE; i++) {
+ if (pos[i] != 0) {
+ sysinfo->bmc_mac = talloc_memdup(sysinfo, pos, HWADDR_SIZE);
+ break;
+ }
+ }
+
+ pos += HWADDR_SIZE;
+ len -= HWADDR_SIZE;
+
+ rc = 0;
+out:
+ return rc;
+}
+
+static int pb_protocol_deserialise_config_interface(const char **buf,
+ unsigned int *len, struct interface_config *iface)
+{
+ unsigned int tmp;
+
+ if (*len < sizeof(iface->hwaddr))
+ return -1;
+
+ memcpy(iface->hwaddr, *buf, sizeof(iface->hwaddr));
+ *buf += sizeof(iface->hwaddr);
+ *len -= sizeof(iface->hwaddr);
+
+ if (read_u32(buf, len, &tmp))
+ return -1;
+ iface->ignore = !!tmp;
+
+ if (iface->ignore)
+ return 0;
+
+ if (read_u32(buf, len, &iface->method))
+ return -1;
+
+ if (iface->method == CONFIG_METHOD_STATIC) {
+ if (read_string(iface, buf, len, &iface->static_config.address))
+ return -1;
+
+ if (read_string(iface, buf, len, &iface->static_config.gateway))
+ return -1;
+
+ if (read_string(iface, buf, len, &iface->static_config.url))
+ return -1;
+ }
+
+ return 0;
+}
+
+int pb_protocol_deserialise_config(struct config *config,
+ const struct pb_protocol_message *message)
+{
+ unsigned int len, i, tmp;
+ const char *pos;
+ int rc = -1;
+ char *str;
+
+ len = message->payload_len;
+ pos = message->payload;
+
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->autoboot_enabled = !!tmp;
+
+ if (read_u32(&pos, &len, &config->autoboot_timeout_sec))
+ goto out;
+
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->safe_mode = !!tmp;
+
+ if (read_u32(&pos, &len, &config->network.n_interfaces))
+ goto out;
+
+ config->network.interfaces = talloc_array(config,
+ struct interface_config *, config->network.n_interfaces);
+
+ for (i = 0; i < config->network.n_interfaces; i++) {
+ struct interface_config *iface = talloc_zero(
+ config->network.interfaces,
+ struct interface_config);
+ if (pb_protocol_deserialise_config_interface(&pos, &len, iface))
+ goto out;
+ config->network.interfaces[i] = iface;
+ }
+
+ if (read_u32(&pos, &len, &config->network.n_dns_servers))
+ goto out;
+ config->network.dns_servers = talloc_array(config, const char *,
+ config->network.n_dns_servers);
+
+ for (i = 0; i < config->network.n_dns_servers; i++) {
+ if (read_string(config->network.dns_servers, &pos, &len, &str))
+ goto out;
+ config->network.dns_servers[i] = str;
+ }
+
+ if (read_u32(&pos, &len, &config->n_autoboot_opts))
+ goto out;
+ config->autoboot_opts = talloc_array(config, struct autoboot_option,
+ config->n_autoboot_opts);
+
+ for (i = 0; i < config->n_autoboot_opts; i++) {
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->autoboot_opts[i].boot_type = (int)tmp;
+ if (config->autoboot_opts[i].boot_type == BOOT_DEVICE_TYPE) {
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->autoboot_opts[i].type = tmp;
+ } else {
+ if (read_string(config, &pos, &len, &str))
+ goto out;
+ config->autoboot_opts[i].uuid = str;
+ }
+ }
+
+ if (read_u32(&pos, &len, &config->ipmi_bootdev))
+ goto out;
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->ipmi_bootdev_persistent = !!tmp;
+
+ if (read_u32(&pos, &len, &tmp))
+ goto out;
+ config->allow_writes = !!tmp;
+
+ if (read_u32(&pos, &len, &config->n_tty))
+ goto out;
+
+ config->tty_list = talloc_array(config, char *, config->n_tty);
+ for (i = 0; i < config->n_tty; i++) {
+ if (read_string(config->tty_list, &pos, &len, &str))
+ goto out;
+ config->tty_list[i] = str;
+ }
+
+ if (read_string(config, &pos, &len, &str))
+ goto out;
+
+ config->boot_tty = str;
+
+ if (read_string(config, &pos, &len, &str))
+ goto out;
+
+ config->lang = str;
+
+ rc = 0;
+
+out:
+ return rc;
+}