+ return (pos <= buf + buf_len) ? 0 : -1;
+}
+
+static int pb_protocol_serialise_config_interface(char *buf,
+ struct interface_config *conf)
+{
+ char *pos = buf;
+
+ memcpy(pos, conf->hwaddr, sizeof(conf->hwaddr));
+ pos += sizeof(conf->hwaddr);
+
+ *(uint32_t *)pos = conf->ignore;
+ pos += 4;
+
+ if (conf->ignore)
+ return pos - buf;
+
+ *(uint32_t *)pos = __cpu_to_be32(conf->method);
+ pos += 4;
+
+ if (conf->method == CONFIG_METHOD_STATIC) {
+ pos += pb_protocol_serialise_string(pos,
+ conf->static_config.address);
+ pos += pb_protocol_serialise_string(pos,
+ conf->static_config.gateway);
+ pos += pb_protocol_serialise_string(pos,
+ conf->static_config.url);
+ }
+
+ *(uint32_t *)pos = conf->override;
+ pos += 4;
+
+ return pos - buf;
+}
+
+int pb_protocol_serialise_config(const struct config *config,
+ char *buf, int buf_len)
+{
+ char *pos = buf;
+ unsigned int i;
+
+ *(uint32_t *)pos = config->autoboot_enabled;
+ pos += 4;
+
+ *(uint32_t *)pos = __cpu_to_be32(config->autoboot_timeout_sec);
+ pos += 4;
+
+ *(uint32_t *)pos = config->safe_mode;
+ pos += 4;
+
+ *(uint32_t *)pos = __cpu_to_be32(config->network.n_interfaces);
+ pos += 4;
+ for (i = 0; i < config->network.n_interfaces; i++) {
+ struct interface_config *iface =
+ config->network.interfaces[i];
+ pos += pb_protocol_serialise_config_interface(pos, iface);
+ }
+
+ *(uint32_t *)pos = __cpu_to_be32(config->network.n_dns_servers);
+ pos += 4;
+ for (i = 0; i < config->network.n_dns_servers; i++) {
+ pos += pb_protocol_serialise_string(pos,
+ config->network.dns_servers[i]);
+ }
+
+ pos += pb_protocol_serialise_string(pos, config->http_proxy);
+ pos += pb_protocol_serialise_string(pos, config->https_proxy);
+
+ *(uint32_t *)pos = __cpu_to_be32(config->n_autoboot_opts);
+ pos += 4;
+ for (i = 0; i < config->n_autoboot_opts; i++) {
+ *(uint32_t *)pos =
+ __cpu_to_be32(config->autoboot_opts[i].boot_type);
+ pos += 4;
+ if (config->autoboot_opts[i].boot_type == BOOT_DEVICE_TYPE) {
+ *(uint32_t *)pos =
+ __cpu_to_be32(config->autoboot_opts[i].type);
+ pos += 4;
+ } else {
+ pos += pb_protocol_serialise_string(pos,
+ config->autoboot_opts[i].uuid);
+ }
+ }
+
+ *(uint32_t *)pos = __cpu_to_be32(config->ipmi_bootdev);
+ pos += 4;
+ *(uint32_t *)pos = config->ipmi_bootdev_persistent;
+ pos += 4;
+ *(uint32_t *)pos = config->ipmi_bootdev_mailbox;
+ pos += 4;
+
+ *(uint32_t *)pos = config->allow_writes;
+ pos += 4;
+
+ *(uint32_t *)pos = __cpu_to_be32(config->n_consoles);
+ pos += 4;
+ for (i = 0; i < config->n_consoles; i++)
+ pos += pb_protocol_serialise_string(pos, config->consoles[i]);
+
+ pos += pb_protocol_serialise_string(pos, config->boot_console);
+ *(uint32_t *)pos = config->manual_console;
+ pos += 4;
+
+ pos += pb_protocol_serialise_string(pos, config->lang);
+
+ assert(pos <= buf + buf_len);
+
+ return (pos <= buf + buf_len) ? 0 : -1;
+}
+
+int pb_protocol_serialise_url(const char *url, char *buf, int buf_len)
+{
+ char *pos = buf;
+
+ pos += pb_protocol_serialise_string(pos, url);
+
+ assert(pos <=buf+buf_len);
+
+ return (pos <= buf + buf_len) ? 0 : -1;
+}
+
+int pb_protocol_serialise_plugin_option(const struct plugin_option *opt,
+ char *buf, int buf_len)
+{
+ char *pos = buf;
+ unsigned int i;
+
+ pos += pb_protocol_serialise_string(pos, opt->id);
+ pos += pb_protocol_serialise_string(pos, opt->name);
+ pos += pb_protocol_serialise_string(pos, opt->vendor);
+ pos += pb_protocol_serialise_string(pos, opt->vendor_id);
+ pos += pb_protocol_serialise_string(pos, opt->version);
+ pos += pb_protocol_serialise_string(pos, opt->date);
+ pos += pb_protocol_serialise_string(pos, opt->plugin_file);
+
+ *(uint32_t *)pos = __cpu_to_be32(opt->n_executables);
+ pos += 4;
+
+ for (i = 0; i < opt->n_executables; i++)
+ pos += pb_protocol_serialise_string(pos, opt->executables[i]);
+
+ assert(pos <= buf + buf_len);
+
+ return (pos <= buf + buf_len) ? 0 : -1;
+}
+
+int pb_protocol_serialise_temp_autoboot(const struct autoboot_option *opt,
+ char *buf, int buf_len)
+{
+ char *pos = buf;
+
+ *(uint32_t *)pos = __cpu_to_be32(opt->boot_type);
+ pos += 4;
+
+ if (opt->boot_type == BOOT_DEVICE_TYPE) {
+ *(uint32_t *)pos = __cpu_to_be32(opt->type);
+ pos += 4;
+ } else {
+ pos += pb_protocol_serialise_string(pos, opt->uuid);
+ }
+
+ assert(pos <= buf + buf_len);
+
+ return (pos <= buf + buf_len) ? 0 : -1;
+}
+
+int pb_protocol_serialise_authenticate(struct auth_message *msg,
+ char *buf, int buf_len)
+{
+ char *pos = buf;
+
+ *(enum auth_msg_type *)pos = msg->op;
+ pos += sizeof(enum auth_msg_type);
+
+ switch(msg->op) {
+ case AUTH_MSG_REQUEST:
+ pos += pb_protocol_serialise_string(pos, msg->password);
+ break;
+ case AUTH_MSG_RESPONSE:
+ *(bool *)pos = msg->authenticated;
+ pos += sizeof(bool);
+ break;
+ case AUTH_MSG_SET:
+ pos += pb_protocol_serialise_string(pos,
+ msg->set_password.password);
+ pos += pb_protocol_serialise_string(pos,
+ msg->set_password.new_password);
+ break;
+ case AUTH_MSG_DECRYPT:
+ pos += pb_protocol_serialise_string(pos,
+ msg->decrypt_dev.password);
+ pos += pb_protocol_serialise_string(pos,
+ msg->decrypt_dev.device_id);
+ break;
+ default:
+ pb_log("%s: invalid msg\n", __func__);
+ return -1;
+ };
+
+ assert(pos <= buf + buf_len);
+
+ return (pos <= buf + buf_len) ? 0 : -1;