pb-discover.h \
resource.c \
resource.h \
+ sysinfo.c \
+ sysinfo.h \
network.c \
network.h \
udev.c \
#include "device-handler.h"
#include "discover-server.h"
+#include "sysinfo.h"
struct discover_server {
int socket;
return client_write_message(server, client, message);
}
+static int write_system_info_message(struct discover_server *server,
+ struct client *client, const struct system_info *sysinfo)
+{
+ struct pb_protocol_message *message;
+ int len;
+
+ len = pb_protocol_system_info_len(sysinfo);
+
+ message = pb_protocol_create_message(client,
+ PB_PROTOCOL_ACTION_SYSTEM_INFO, len);
+ if (!message)
+ return -1;
+
+ pb_protocol_serialise_system_info(sysinfo, message->payload, len);
+
+ return client_write_message(server, client, message);
+}
+
static int discover_server_process_message(void *arg)
{
struct pb_protocol_message *message;
client->fd = fd;
client->server = server;
+ /* send sysinfo to client */
+ rc = write_system_info_message(server, client, system_info_get());
+ if (rc)
+ return 0;
+
/* send existing devices to client */
n_devices = device_handler_get_device_count(server->device_handler);
for (i = 0; i < n_devices; i++) {
write_boot_status_message(server, client, status);
}
+void discover_server_notify_system_info(struct discover_server *server,
+ const struct system_info *sysinfo)
+{
+ struct client *client;
+
+ list_for_each_entry(&server->clients, client, list)
+ write_system_info_message(server, client, sysinfo);
+}
+
void discover_server_set_device_source(struct discover_server *server,
struct device_handler *handler)
{
struct device_handler;
struct boot_option;
struct boot_status;
+struct system_info;
struct device;
struct discover_server *discover_server_init(struct waitset *waitset);
struct device *device);
void discover_server_notify_boot_status(struct discover_server *server,
struct boot_status *status);
+void discover_server_notify_system_info(struct discover_server *server,
+ const struct system_info *sysinfo);
#endif /* _DISCOVER_SERVER_H */
#include "file.h"
#include "network.h"
+#include "sysinfo.h"
#include "device-handler.h"
#define HWADDR_SIZE 6
memcpy(interface->hwaddr, ifaddr, sizeof(interface->hwaddr));
strncpy(interface->name, ifname, sizeof(interface->name) - 1);
add_interface(network, interface);
+
+ /* tell the sysinfo code about this interface */
+ if (strcmp(interface->name, "lo"))
+ system_info_register_interface(
+ sizeof(interface->hwaddr),
+ interface->hwaddr, interface->name);
}
configure_interface(network, interface,
#include "discover-server.h"
#include "device-handler.h"
#include "network.h"
+#include "sysinfo.h"
static void print_version(void)
{
if (opts.no_autoboot == opt_yes)
config_set_autoboot(false);
+ system_info_init(server);
+
handler = device_handler_init(server, waitset, opts.dry_run == opt_yes);
if (!handler)
return EXIT_FAILURE;
--- /dev/null
+
+#include <string.h>
+
+#include <talloc/talloc.h>
+
+#include "discover-server.h"
+#include "sysinfo.h"
+
+static struct system_info *sysinfo;
+static struct discover_server *server;
+
+const struct system_info *system_info_get(void)
+{
+ return sysinfo;
+}
+
+void system_info_register_interface(unsigned int hwaddr_size, uint8_t *hwaddr,
+ const char *name)
+{
+ struct interface_info *if_info;
+ unsigned int i;
+
+ for (i = 0; i < sysinfo->n_interfaces; i++) {
+ if_info = sysinfo->interfaces[i];
+
+ if (if_info->hwaddr_size != hwaddr_size)
+ continue;
+
+ if (memcmp(if_info->hwaddr, hwaddr, hwaddr_size))
+ continue;
+
+ /* update the name and we're done */
+ talloc_free(if_info->name);
+ if_info->name = talloc_strdup(if_info, name);
+ discover_server_notify_system_info(server, sysinfo);
+ return;
+ }
+
+ if_info = talloc_zero(sysinfo, struct interface_info);
+ if_info->hwaddr_size = hwaddr_size;
+ if_info->hwaddr = talloc_memdup(if_info, hwaddr, hwaddr_size);
+ if_info->name = talloc_strdup(if_info, name);
+
+ sysinfo->n_interfaces++;
+ sysinfo->interfaces = talloc_realloc(sysinfo, sysinfo->interfaces,
+ struct interface_info *,
+ sysinfo->n_interfaces);
+ sysinfo->interfaces[sysinfo->n_interfaces - 1] = if_info;
+
+ discover_server_notify_system_info(server, sysinfo);
+}
+
+static void system_info_set_identifier(struct system_info *info
+ __attribute__((unused)))
+{
+ /* todo: call helpers to set type & id */
+}
+
+void system_info_init(struct discover_server *s)
+{
+ sysinfo = talloc_zero(server, struct system_info);
+ server = s;
+ system_info_set_identifier(sysinfo);
+}
--- /dev/null
+#ifndef SYSINFO_H
+#define SYSINFO_H
+
+#include <types/types.h>
+
+struct discover_server;
+
+const struct system_info *system_info_get(void);
+
+void system_info_register_interface(unsigned hwaddr_size, uint8_t *hwaddr,
+ const char *name);
+
+void system_info_init(struct discover_server *server);
+
+#endif /* SYSINFO_H */
+
return 0;
}
+static int read_u32(const char **pos, unsigned int *len, unsigned int *p)
+{
+ if (*len < sizeof(uint32_t))
+ return -1;
+
+ *p = (unsigned int)__be32_to_cpu(*(uint32_t *)(*pos));
+ *pos += sizeof(uint32_t);
+ *len -= sizeof(uint32_t);
+
+ return 0;
+}
+
char *pb_protocol_deserialise_string(void *ctx,
const struct pb_protocol_message *message)
{
4;
}
+int pb_protocol_system_info_len(const struct system_info *sysinfo)
+{
+ unsigned int len, i;
+
+ len = 4 + optional_strlen(sysinfo->type) +
+ 4 + optional_strlen(sysinfo->identifier) +
+ 4;
+
+ for (i = 0; i < sysinfo->n_interfaces; i++) {
+ struct interface_info *if_info = sysinfo->interfaces[i];
+ len += 4 + if_info->hwaddr_size +
+ 4 + optional_strlen(if_info->name);
+ }
+
+ return len;
+}
+
int pb_protocol_serialise_device(const struct device *dev,
char *buf, int buf_len)
{
return 0;
}
+int pb_protocol_serialise_system_info(const struct system_info *sysinfo,
+ char *buf, int buf_len)
+{
+ char *pos = buf;
+ unsigned int i;
+
+ pos += pb_protocol_serialise_string(pos, sysinfo->type);
+ pos += pb_protocol_serialise_string(pos, sysinfo->identifier);
+
+ *(uint32_t *)pos = __cpu_to_be32(sysinfo->n_interfaces);
+ pos += sizeof(uint32_t);
+
+ for (i = 0; i < sysinfo->n_interfaces; i++) {
+ struct interface_info *if_info = sysinfo->interfaces[i];
+
+ *(uint32_t *)pos = __cpu_to_be32(if_info->hwaddr_size);
+ pos += sizeof(uint32_t);
+
+ memcpy(pos, if_info->hwaddr, if_info->hwaddr_size);
+ pos += if_info->hwaddr_size;
+
+ pos += pb_protocol_serialise_string(pos, if_info->name);
+ }
+
+ assert(pos <= buf + buf_len);
+ (void)buf_len;
+
+ return 0;
+}
+
int pb_protocol_write_message(int fd, struct pb_protocol_message *message)
{
int total_len, rc;
out:
return rc;
}
+
+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;
+
+ 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;
+
+ /* 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;
+
+ sysinfo->interfaces[i] = if_info;
+ }
+
+ rc = 0;
+
+out:
+ return rc;
+}
PB_PROTOCOL_ACTION_BOOT = 0x5,
PB_PROTOCOL_ACTION_STATUS = 0x6,
PB_PROTOCOL_ACTION_CANCEL_DEFAULT = 0x7,
+ PB_PROTOCOL_ACTION_SYSTEM_INFO = 0x8,
};
struct pb_protocol_message {
int pb_protocol_boot_option_len(const struct boot_option *opt);
int pb_protocol_boot_len(const struct boot_command *boot);
int pb_protocol_boot_status_len(const struct boot_status *status);
+int pb_protocol_system_info_len(const struct system_info *sysinfo);
int pb_protocol_device_cmp(const struct device *a, const struct device *b);
int pb_protocol_boot_option_cmp(const struct boot_option *a,
char *buf, int buf_len);
int pb_protocol_serialise_boot_status(const struct boot_status *status,
char *buf, int buf_len);
+int pb_protocol_serialise_system_info(const struct system_info *sysinfo,
+ char *buf, int buf_len);
int pb_protocol_write_message(int fd, struct pb_protocol_message *message);
int pb_protocol_deserialise_boot_status(struct boot_status *status,
const struct pb_protocol_message *message);
+int pb_protocol_deserialise_system_info(struct system_info *sysinfo,
+ const struct pb_protocol_message *message);
+
#endif /* _PB_PROTOCOL_H */
#define _TYPES_H
#include <stdbool.h>
+#include <stdint.h>
#include <list/list.h>
enum device_type {
int progress;
};
+struct interface_info {
+ unsigned int hwaddr_size;
+ uint8_t *hwaddr;
+ char *name;
+};
+
+struct system_info {
+ char *type;
+ char *identifier;
+ struct interface_info **interfaces;
+ unsigned int n_interfaces;
+};
+
+
#endif /* _TYPES_H */
talloc_free(status);
}
+static void update_sysinfo(struct discover_client *client,
+ struct system_info *sysinfo)
+{
+ if (client->ops.update_sysinfo)
+ client->ops.update_sysinfo(sysinfo, client->ops.cb_arg);
+ talloc_free(sysinfo);
+}
+
static int discover_client_process(void *arg)
{
struct discover_client *client = arg;
struct pb_protocol_message *message;
+ struct system_info *sysinfo;
struct boot_status *status;
struct boot_option *opt;
struct device *dev;
}
update_status(client, status);
break;
+ case PB_PROTOCOL_ACTION_SYSTEM_INFO:
+ sysinfo = talloc_zero(client, struct system_info);
+
+ rc = pb_protocol_deserialise_system_info(sysinfo, message);
+ if (rc) {
+ pb_log("%s: invalid sysinfo message?\n", __func__);
+ return 0;
+ }
+ update_sysinfo(client, sysinfo);
+ break;
default:
pb_log("%s: unknown action %d\n", __func__, message->action);
}
void *arg);
void (*device_remove)(struct device *device, void *arg);
void (*update_status)(struct boot_status *status, void *arg);
+ void (*update_sysinfo)(struct system_info *sysinfo, void *arg);
void *cb_arg;
};
}
+static void print_sysinfo(struct system_info *sysinfo,
+ void __attribute__((unused)) *arg)
+{
+ unsigned int i;
+
+ printf("sysinfo:\n");
+ printf("\ttype: %s\n", sysinfo->type);
+ printf("\tid: %s\n", sysinfo->identifier);
+
+ if (sysinfo->n_interfaces == 0)
+ printf("\tno interfaces.\n");
+ else
+ printf("\tinterfaces:\n");
+
+ for (i = 0; i < sysinfo->n_interfaces; i++) {
+ struct interface_info *if_info = sysinfo->interfaces[i];
+ uint8_t *m = if_info->hwaddr;
+
+ printf("\t\tname: %s\n", if_info->name);
+
+ if (if_info->hwaddr_size == 6)
+ printf("\t\tmac: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ m[0], m[1], m[2], m[3], m[4], m[5]);
+ else
+ printf("\t\tmac: unknown hwaddr size %d\n",
+ if_info->hwaddr_size);
+ }
+}
+
static struct discover_client_ops client_ops = {
.device_add = print_device_add,
.boot_option_add = print_boot_option_add,
.device_remove = print_device_remove,
.update_status = print_status,
+ .update_sysinfo = print_sysinfo,
};
int main(void)