diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-06-04 07:28:19 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-06-17 20:47:39 +0200 |
commit | c8f69207e6d5fb654814833676f5f786084a8576 (patch) | |
tree | 229f8e227af42111adc988015112707330f530d8 | |
parent | f3146e2631f23c80e9ce43cbff33b294cab9f535 (diff) | |
download | kernel-crypto-c8f69207e6d5fb654814833676f5f786084a8576.tar.gz kernel-crypto-c8f69207e6d5fb654814833676f5f786084a8576.tar.xz kernel-crypto-c8f69207e6d5fb654814833676f5f786084a8576.zip |
Some updates in the server approach (not working yet).
-rw-r--r-- | cryptodev_main.c | 14 | ||||
-rw-r--r-- | examples/new.c | 157 | ||||
-rw-r--r-- | ncr-storage-low.c | 165 | ||||
-rw-r--r-- | ncr-storage-low.h | 8 | ||||
-rw-r--r-- | ncr-storage.c | 9 | ||||
-rw-r--r-- | ncr-storage.h | 4 | ||||
-rw-r--r-- | ncr_int.h | 2 | ||||
-rw-r--r-- | userspace/ncr-server/Makefile | 4 | ||||
-rw-r--r-- | userspace/ncr-server/ncr-server.c | 81 |
9 files changed, 360 insertions, 84 deletions
diff --git a/cryptodev_main.c b/cryptodev_main.c index 460e3d3df1e..58ae45b647e 100644 --- a/cryptodev_main.c +++ b/cryptodev_main.c @@ -510,7 +510,6 @@ cryptodev_open(struct inode *inode, struct file *filp) init_MUTEX(&pcr->fcrypt.sem); INIT_LIST_HEAD(&pcr->fcrypt.list); - pcr->ncr = ncr_init_lists(); if (pcr->ncr == NULL) { kfree(pcr); @@ -730,9 +729,17 @@ cryptodev_register(void) ncr_limits_init(); + rc = ncr_gnl_init(); + if (rc < 0) { + ncr_limits_deinit(); + return rc; + } + rc = misc_register (&cryptodev); if (unlikely(rc)) { - printk(KERN_ERR PFX "registeration of /dev/crypto failed\n"); + ncr_gnl_deinit(); + ncr_limits_deinit(); + printk(KERN_ERR PFX "registration of /dev/crypto failed\n"); return rc; } @@ -742,8 +749,9 @@ cryptodev_register(void) static void cryptodev_deregister(void) { - ncr_limits_deinit(); misc_deregister(&cryptodev); + ncr_gnl_deinit(); + ncr_limits_deinit(); } /* ====== Module init/exit ====== */ diff --git a/examples/new.c b/examples/new.c index 32e17dcfc51..cdc3baa5d70 100644 --- a/examples/new.c +++ b/examples/new.c @@ -10,6 +10,8 @@ #include <fcntl.h> #include <time.h> #include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> #include "../ncr.h" #include <stdlib.h> @@ -376,6 +378,158 @@ static int test_ncr_data(int cfd) return 0; } +static int +test_ncr_store_key(int cfd) +{ + struct ncr_data_init_st dinit; + struct ncr_key_generate_st kgen; + ncr_key_t key, key2; + struct ncr_key_data_st keydata; + struct ncr_data_st kdata; + uint8_t data[KEY_DATA_SIZE]; + uint8_t data_bak[KEY_DATA_SIZE]; + struct ncr_storage_st kstore; + + fprintf(stdout, "Tests on Key Storage:\n"); + + /* test 1: generate a key in kernel and store it. + * The try to load it. + */ + fprintf(stdout, "\tKey storage/retrieval...\n"); + + /* initialize data */ + dinit.max_object_size = KEY_DATA_SIZE; + dinit.flags = NCR_DATA_FLAG_EXPORTABLE; + dinit.initial_data = NULL; + dinit.initial_data_size = 0; + + if (ioctl(cfd, NCRIO_DATA_INIT, &dinit)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_DATA_INIT)"); + return 1; + } + + if (ioctl(cfd, NCRIO_KEY_INIT, &key)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_INIT)"); + return 1; + } + + if (ioctl(cfd, NCRIO_KEY_INIT, &key2)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_INIT)"); + return 1; + } + + kgen.desc = key; + kgen.params.algorithm = NCR_ALG_AES_CBC; + kgen.params.keyflags = NCR_KEY_FLAG_EXPORTABLE; + kgen.params.params.secret.bits = 128; /* 16 bytes */ + + if (ioctl(cfd, NCRIO_KEY_GENERATE, &kgen)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_IMPORT)"); + return 1; + } + + + memset(&keydata, 0, sizeof(keydata)); + keydata.key = key; + keydata.data = dinit.desc; + + if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_IMPORT)"); + return 1; + } + + /* now read data */ + memset(data, 0, sizeof(data)); + + kdata.desc = dinit.desc; + kdata.data = data_bak; + kdata.data_size = sizeof(data_bak); + kdata.append_flag = 0; + + if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_DATA_GET)"); + return 1; + } + + /* ok now key stands in data[]. Store it. */ + + kstore.key = key; + strcpy(kstore.label, "testkey"); + kstore.mode = S_IRWXU; + + if (ioctl(cfd, NCRIO_STORAGE_STORE, &kstore)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_STORAGE_STORE)"); + return 1; + } + + kstore.key = key2; + + if (ioctl(cfd, NCRIO_STORAGE_LOAD, &kstore)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_STORAGE_LOAD)"); + return 1; + } + + /* export it */ + memset(&keydata, 0, sizeof(keydata)); + keydata.key = key2; + keydata.data = dinit.desc; + + if (ioctl(cfd, NCRIO_KEY_EXPORT, &keydata)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_IMPORT)"); + return 1; + } + + /* now read data */ + memset(data, 0, sizeof(data)); + + kdata.desc = dinit.desc; + kdata.data = data; + kdata.data_size = sizeof(data); + kdata.append_flag = 0; + + if (ioctl(cfd, NCRIO_DATA_GET, &kdata)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_DATA_GET)"); + return 1; + } + + if (memcmp(data, data_bak, kdata.data_size)!=0) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + fprintf(stderr, "Loaded data do not match stored\n"); + return 1; + } + + if (ioctl(cfd, NCRIO_KEY_DEINIT, &key)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_DEINIT)"); + return 1; + } + + if (ioctl(cfd, NCRIO_KEY_DEINIT, &key2)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_KEY_DEINIT)"); + return 1; + } + + if (ioctl(cfd, NCRIO_DATA_DEINIT, &dinit.desc)) { + fprintf(stderr, "Error: %s:%d\n", __func__, __LINE__); + perror("ioctl(NCRIO_DATA_DEINIT)"); + return 1; + } + + + return 0; +} + int main() { @@ -410,6 +564,9 @@ main() if (test_ncr_key(fd)) return 1; + if (test_ncr_store_key(fd)) + return 1; + /* Close the original descriptor */ if (close(fd)) { perror("close(fd)"); diff --git a/ncr-storage-low.c b/ncr-storage-low.c index 418bc8ff969..489aa2ecfe4 100644 --- a/ncr-storage-low.c +++ b/ncr-storage-low.c @@ -60,6 +60,7 @@ struct event_item_st* item; item->id = id; item->reply = NULL; item->reply_size = 0; + item->ireply = -1; init_completion(&item->completed); down(&event_list.sem); @@ -73,10 +74,8 @@ static int event_wait(uint32_t id) { struct event_item_st* item; struct completion* completed = NULL; -int ret = 0; down(&event_list.sem); - list_for_each_entry(item, &event_list.list, list) { if (id == item->id) { completed = &item->completed; @@ -84,10 +83,13 @@ int ret = 0; } } up(&event_list.sem); + if (completed) { - ret = wait_for_completion_interruptible(completed); + return wait_for_completion_interruptible(completed); + } else { + err(); + return -EIO; } - return 0; } @@ -203,23 +205,73 @@ struct event_item_st* item, *tmp; static struct nla_policy ncr_genl_policy[ATTR_MAX + 1] = { [ATTR_STRUCT_LOAD] = { .type = NLA_BINARY }, [ATTR_STRUCT_LOADED] = { .type = NLA_BINARY }, - [ATTR_STORE_ACK] = { .type = NLA_BINARY }, + [ATTR_STORE_U8] = { .type = NLA_BINARY }, [ATTR_STRUCT_STORE] = { .type = NLA_BINARY }, }; static atomic_t ncr_event_sr; static uint32_t listener_pid = -1; -#define VERSION_NR 1 /* family definition */ static struct genl_family ncr_gnl_family = { .id = GENL_ID_GENERATE, //genetlink should generate an id .hdrsize = 0, .name = NCR_NL_STORAGE_NAME, //the name of this family, used by userspace application - .version = VERSION_NR, //version number + .version = NCR_NL_STORAGE_VERSION, //version number .maxattr = ATTR_MAX, }; +/* an echo command, receives a message, prints it and sends another message back */ +static void _ncr_nl_close(void) +{ + struct sk_buff *skb; + int ret; + void *msg_head; + uint32_t id; + + if (listener_pid == -1) { + err(); + return; + } + + skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (skb == NULL) { + ret = -ENOMEM; + goto out; + } + + id = atomic_add_return(1, &ncr_event_sr); + msg_head = genlmsg_put(skb, 0, id, &ncr_gnl_family, 0, CMD_CLOSE); + if (msg_head == NULL) { + err(); + ret = -ENOMEM; + goto out; + } + + ret = nla_put_u8(skb, ATTR_STORE_U8, 1); + if (ret != 0) { + err(); + goto out; + } + + /* finalize the message */ + genlmsg_end(skb, msg_head); + + /* send the message back */ + ret = genlmsg_unicast(skb, listener_pid); + if (ret != 0) { + err(); + goto out; + } + + return; + +out: + nlmsg_free(skb); + printk("an error occured in ncr_gnl_store\n"); + + return; +} /* an echo command, receives a message, prints it and sends another message back */ int _ncr_store(const struct storage_item_st * tostore) @@ -236,7 +288,7 @@ int _ncr_store(const struct storage_item_st * tostore) err(); return -EIO; } - + /* send a message back*/ /* allocate some memory, since the size is not yet known use NLMSG_GOODSIZE*/ size = nla_total_size(sizeof(struct storage_item_st)) + @@ -248,7 +300,7 @@ int _ncr_store(const struct storage_item_st * tostore) goto out; } - id = atomic_long_inc_return(&ncr_event_sr); + id = atomic_add_return(1, &ncr_event_sr); msg_head = genlmsg_put(skb, 0, id, &ncr_gnl_family, 0, CMD_STORE); if (msg_head == NULL) { @@ -278,6 +330,12 @@ int _ncr_store(const struct storage_item_st * tostore) /* finalize the message */ genlmsg_end(skb, msg_head); + ret = event_add(id); + if (ret < 0) { + err(); + goto out; + } + /* send the message back */ ret = genlmsg_unicast(skb, listener_pid); if (ret != 0) @@ -286,10 +344,13 @@ int _ncr_store(const struct storage_item_st * tostore) /* wait for an acknowledgment */ ret = event_wait(id); if (ret) { - goto out; + err(); + printk(KERN_DEBUG"Error waiting for id %u\n", id); + event_remove(id); + return ret; } - reply = event_get_idata(id, &reply_size); + reply = event_get_idata(id); if (reply == (uint32_t)-1) BUG(); @@ -317,7 +378,7 @@ int _ncr_load(struct storage_item_st * toload) struct sk_buff *skb; int ret; void *msg_head; - size_t size, reply_size; + size_t reply_size=0, size; struct nlattr *attr; void* msg, *reply; struct ncr_gnl_load_cmd_st cmd; @@ -339,7 +400,7 @@ int _ncr_load(struct storage_item_st * toload) goto out; } - id = atomic_long_inc_return(&ncr_event_sr); + id = atomic_add_return(1, &ncr_event_sr); msg_head = genlmsg_put(skb, 0, id, &ncr_gnl_family, 0, CMD_LOAD); if (msg_head == NULL) { @@ -386,7 +447,10 @@ int _ncr_load(struct storage_item_st * toload) /* wait for an answer */ ret = event_wait(id); if (ret) { - goto out; + err(); + printk(KERN_DEBUG"Error waiting for id %u\n", id); + event_remove(id); + return ret; } reply = event_get_data(id, &reply_size); @@ -413,6 +477,8 @@ int ncr_gnl_listen(struct sk_buff *skb, struct genl_info *info) return -EIO; listener_pid = info->snd_pid; + atomic_set(&ncr_event_sr, info->snd_seq+1); + printk(KERN_DEBUG"Setting listener pid to %d!\n", (int)listener_pid); return 0; } @@ -421,33 +487,32 @@ int ncr_gnl_listen(struct sk_buff *skb, struct genl_info *info) /* with this command the userspace server registers */ int ncr_gnl_store_ack(struct sk_buff *skb, struct genl_info *info) { - uint8_t * data, *event_reply; + uint8_t * data; size_t len; - struct ncr_gnl_store_ack_st reply; + struct ncr_gnl_store_ack_st *reply; struct nlattr *na; if (info == NULL) return -EIO; + printk("Received store ack!\n"); /*for each attribute there is an index in info->attrs which points to a nlattr structure *in this structure the data is given */ - na = info->attrs[ATTR_STORE_ACK]; + na = info->attrs[ATTR_STORE_U8]; if (na) { len = nla_len(na); data = (void *)nla_data(na); if (data == NULL || len != sizeof(struct ncr_gnl_store_ack_st)) printk(KERN_DEBUG"error while receiving data\n"); else { - - memcpy( &reply, data, sizeof(reply)); - - event_set_idata(reply.id, (uint32_t)reply.reply[0]); + reply = (void*)data; + event_set_idata(reply->id, (uint32_t)reply->reply); - event_complete(reply.id); + event_complete(reply->id); } } else - printk(KERN_DEBUG"no info->attrs %i\n", ATTR_STORE_ACK); + printk(KERN_DEBUG"no info->attrs %i\n", ATTR_STORE_U8); return 0; } @@ -457,7 +522,7 @@ int ncr_gnl_loaded_data(struct sk_buff *skb, struct genl_info *info) { uint8_t * data, *event_reply; size_t len; - struct ncr_gnl_loaded_st reply; + struct ncr_gnl_loaded_st *reply; struct nlattr *na; if (info == NULL) @@ -473,14 +538,13 @@ int ncr_gnl_loaded_data(struct sk_buff *skb, struct genl_info *info) if (data == NULL || len != sizeof(struct ncr_gnl_loaded_st)) printk(KERN_DEBUG"error while receiving data\n"); else { - - memcpy( &reply, data, sizeof(reply)); - event_reply = kmalloc(sizeof(reply.storage), GFP_KERNEL); + reply = (void*)data; + event_reply = kmalloc(sizeof(reply->storage), GFP_KERNEL); if (event_reply != NULL) { - memcpy(event_reply, &reply.storage, sizeof(reply.storage)); - event_set_data(reply.id, event_reply, sizeof(reply.storage)); + memcpy(event_reply, &reply->storage, sizeof(reply->storage)); + event_set_data(reply->id, event_reply, sizeof(reply->storage)); } - event_complete(reply.id); + event_complete(reply->id); } } else printk(KERN_DEBUG"no info->attrs %i\n", ATTR_STRUCT_LOADED); @@ -519,35 +583,38 @@ struct genl_ops ncr_gnl_ops_store_ack = { int ncr_gnl_init(void) { int rc; - printk("INIT GENERIC NETLINK EXEMPLE MODULE\n"); + + printk(KERN_NOTICE"cryptodev: Initializing netlink subsystem.\n"); init_MUTEX(&event_list.sem); INIT_LIST_HEAD(&event_list.list); - atomic_set(&ncr_event_sr, 0); + atomic_set(&ncr_event_sr, 1); - /*register new family*/ + /*register new family*/ rc = genl_register_family(&ncr_gnl_family); - if (rc != 0) + if (rc != 0) { + err(); goto failure; - /*register functions (commands) of the new family*/ + } + /*register functions (commands) of the new family*/ rc = genl_register_ops(&ncr_gnl_family, &ncr_gnl_ops_listen); if (rc != 0) { - printk("register ops: %i\n",rc); + err(); genl_unregister_family(&ncr_gnl_family); goto failure; } rc = genl_register_ops(&ncr_gnl_family, &ncr_gnl_ops_store_ack); if (rc != 0) { - printk("register ops: %i\n",rc); + err(); genl_unregister_family(&ncr_gnl_family); goto failure; } rc = genl_register_ops(&ncr_gnl_family, &ncr_gnl_ops_load); if (rc != 0) { - printk("register ops: %i\n",rc); + err(); genl_unregister_family(&ncr_gnl_family); goto failure; } @@ -555,7 +622,7 @@ int ncr_gnl_init(void) return 0; failure: - printk("an error occured while inserting the generic netlink example module\n"); + printk(KERN_ERR"an error occured while loading the cryptodev netlink subsystem\n"); return rc; } @@ -563,15 +630,8 @@ void ncr_gnl_deinit(void) { int ret; struct event_item_st *item, *tmp; - printk("EXIT GENERIC NETLINK EXEMPLE MODULE\n"); - /* deinitialize the event list */ - down(&event_list.sem); - list_for_each_entry_safe(item, tmp, &event_list.list, list) { - list_del(&item->list); - kfree(item); - } - up(&event_list.sem); + _ncr_nl_close(); ret = genl_unregister_ops(&ncr_gnl_family, &ncr_gnl_ops_store_ack); if(ret != 0) { @@ -596,4 +656,15 @@ void ncr_gnl_deinit(void) if(ret !=0) { printk("unregister family %i\n",ret); } + + /* deinitialize the event list */ + down(&event_list.sem); + list_for_each_entry_safe(item, tmp, &event_list.list, list) { + list_del(&item->list); + if (item->reply) + kfree(item->reply); + kfree(item); + } + up(&event_list.sem); + } diff --git a/ncr-storage-low.h b/ncr-storage-low.h index 814b0df2893..080a161cf11 100644 --- a/ncr-storage-low.h +++ b/ncr-storage-low.h @@ -1,7 +1,7 @@ #ifndef _STORAGE_LOW #define _STORAGE_LOW -#include <ncr.h> +#include "ncr.h" #define NCR_NL_STORAGE_NAME "KEY_STORAGE" @@ -16,6 +16,7 @@ enum { CMD_LOAD, /* sent by kernel */ CMD_STORE_ACK, /* sent by server */ CMD_LOADED_DATA, /* sent by server */ + CMD_CLOSE, /* sent by kernel */ __CMD_MAX, }; #define CMD_MAX (__CMD_MAX - 1) @@ -29,7 +30,7 @@ enum { ATTR_STRUCT_LOAD, ATTR_STRUCT_LOADED, ATTR_STRUCT_STORE, - ATTR_STORE_ACK, /* u8*/ + ATTR_STORE_U8, /* u8*/ __ATTR_MAX, }; #define ATTR_MAX (__ATTR_MAX - 1) @@ -43,9 +44,10 @@ struct storage_item_st { uint32_t owner; uint32_t group; mode_t mode; - + uint16_t algorithm; uint8_t type; + uint32_t flags; uint8_t key_id[MAX_KEY_ID_SIZE]; uint8_t key_id_size; diff --git a/ncr-storage.c b/ncr-storage.c index 15df0debc1c..d19a44fb98f 100644 --- a/ncr-storage.c +++ b/ncr-storage.c @@ -25,6 +25,8 @@ #include <asm/uaccess.h> #include <asm/ioctl.h> #include <linux/scatterlist.h> +#include <linux/file.h> +#include <linux/cred.h> #include <linux/version.h> #include "ncr.h" #include "ncr_int.h" @@ -39,12 +41,13 @@ int _ncr_key_to_store(const struct key_item_st *key, const char* label, uid_t uid = key->filp->f_uid; gid_t gid = key->filp->f_gid; #else - gid_t gid = key->filp->f_cred->fsgid; + uid_t uid = key->filp->f_cred->fsuid; gid_t gid = key->filp->f_cred->fsgid; #endif /* copy metadata first */ memcpy(output->key_id, key->key_id, sizeof(output->key_id)); output->key_id_size = key->key_id_size; + output->flags = key->flags; output->algorithm = key->algorithm; output->type = key->type; @@ -79,6 +82,7 @@ int _ncr_store_to_key(const struct storage_item_st* raw, struct key_item_st *key key->algorithm = raw->algorithm; key->type = raw->type; + key->flags = raw->flags; switch(key->type) { case NCR_KEY_TYPE_SECRET: @@ -120,6 +124,7 @@ int ncr_storage_store(struct list_sem_st* key_lst, void __user* arg) ret = _ncr_store(&tostore); if (ret < 0) { + printk("cryptodev: Cannot store. Is ncr-server running?\n"); err(); goto fail; } @@ -154,7 +159,7 @@ int ncr_storage_load(struct list_sem_st* key_lst, void __user* arg) uid = key->filp->f_uid; gid = key->filp->f_gid; #else - gid = key->filp->f_cred->fsgid; + uid = key->filp->f_cred->fsuid; gid = key->filp->f_cred->fsgid; #endif diff --git a/ncr-storage.h b/ncr-storage.h index 9384b6ef6f5..0f15f726f9f 100644 --- a/ncr-storage.h +++ b/ncr-storage.h @@ -18,4 +18,8 @@ int ncr_storage_traverse_deinit(struct list_sem_st* tr_lst, void __user* arg); int _ncr_store(const struct storage_item_st * tostore); int _ncr_load(struct storage_item_st * loaded); +/* Netlink subsystem; */ +void ncr_gnl_deinit(void); +int ncr_gnl_init(void); + #endif /* NCR_STORAGE_H */ diff --git a/ncr_int.h b/ncr_int.h index cf265072fa4..22fc7c53f77 100644 --- a/ncr_int.h +++ b/ncr_int.h @@ -4,7 +4,7 @@ #include "ncr.h" #include <asm/atomic.h> -#define err() printk(KERN_DEBUG"ncr: %s: %d\n", __func__, __LINE__) +#define err() printk(KERN_DEBUG"ncr: %s: %s: %d\n", __FILE__, __func__, __LINE__) struct data_item_st { struct list_head list; diff --git a/userspace/ncr-server/Makefile b/userspace/ncr-server/Makefile index ee46dd6ae46..79e380d1803 100644 --- a/userspace/ncr-server/Makefile +++ b/userspace/ncr-server/Makefile @@ -1,7 +1,7 @@ all: ncr-server -CFLAGS=-O2 -Wall -g -I.. -I. +CFLAGS=-O2 -Wall -g -I.. -I. -I../../ CC=gcc ncr-server: ncr-server.c ncr-server.h - $(CC) $(CFLAGS) ncr-server.c -o ncr-server + $(CC) $(CFLAGS) ncr-server.c -o ncr-server -lnl diff --git a/userspace/ncr-server/ncr-server.c b/userspace/ncr-server/ncr-server.c index 3b3c72ad145..bbcf859e9c5 100644 --- a/userspace/ncr-server/ncr-server.c +++ b/userspace/ncr-server/ncr-server.c @@ -7,9 +7,9 @@ #include <netlink/genl/ctrl.h> #include "../ncr-storage-low.h" #include "ncr-server.h" -#include <list.h> +#include "list.h" -static int _notify_listening(struct nl_sock * sock); +static int _notify_listening(int family, struct nl_handle * sock); static struct nla_policy def_policy[ATTR_MAX+1] = { @@ -19,18 +19,20 @@ static struct nla_policy def_policy[ATTR_MAX+1] = .minlen = sizeof(struct ncr_gnl_load_cmd_st) }, }; -static struct actions { - list_head list; +struct todo_actions { + struct list_head list; int cmd; /* CMD_* */ union { struct storage_item_st tostore; struct ncr_gnl_load_cmd_st toload; } data; -} todo; +}; + +static struct todo_actions todo; static int add_store_cmd(struct storage_item_st* tostore) { - struct actions* item; + struct todo_actions* item; item = malloc(sizeof(*item)); if (item == NULL) { @@ -38,15 +40,15 @@ static int add_store_cmd(struct storage_item_st* tostore) return -ERR_MEM; } item->cmd = CMD_STORE; - memcpy(item->data.tostore, tostore, sizeof(item->data.tostore)); + memcpy(&item->data.tostore, tostore, sizeof(item->data.tostore)); - list_add(item, &todo.list); + list_add(&item->list, &todo.list); return 0; } static int add_load_cmd(struct ncr_gnl_load_cmd_st* toload) { - struct actions* item; + struct todo_actions* item; item = malloc(sizeof(*item)); if (item == NULL) { @@ -54,9 +56,9 @@ static int add_load_cmd(struct ncr_gnl_load_cmd_st* toload) return -ERR_MEM; } item->cmd = CMD_LOAD; - memcpy(item->data.toload, toload, sizeof(item->data.toload)); + memcpy(&item->data.toload, toload, sizeof(item->data.toload)); - list_add(item, &todo.list); + list_add(&item->list, &todo.list); return 0; } @@ -65,37 +67,55 @@ static int msg_cb(struct nl_msg *msg, void *arg) struct nlmsghdr *nlh = nlmsg_hdr(msg); struct nlattr *attrs[ATTR_MAX+1]; +fprintf(stderr, "Received message: "); // Validate message and parse attributes genlmsg_parse(nlh, 0, attrs, ATTR_MAX, def_policy); if (attrs[ATTR_STRUCT_STORE]) { - struct storage_item_st *item = nla_get(attrs[ATTR_STRUCT_STORE]); + struct nl_data* data = nla_get_data(attrs[ATTR_STRUCT_STORE]); + struct storage_item_st *item = nl_data_get(data); + +fprintf(stderr, "Store!\n"); + + if (nl_data_get_size(data) != sizeof(struct storage_item_st)) { + err(); + fprintf(stderr, "Received incorrect structure!\n"); + return -1; + } fprintf(stderr, "asked to store: %s\n", item->label); add_store_cmd(item); } if (attrs[ATTR_STRUCT_LOAD]) { - struct ncr_gnl_load_cmd_st *load = nla_get(attrs[ATTR_STRUCT_LOAD]); + struct nl_data* data = nla_get_data(attrs[ATTR_STRUCT_STORE]); + struct ncr_gnl_load_cmd_st *load = nl_data_get(data); + +fprintf(stderr, "Load!\n"); + if (nl_data_get_size(data) != sizeof(struct ncr_gnl_load_cmd_st)) { + err(); + fprintf(stderr, "Received incorrect structure!\n"); + return -1; + } fprintf(stderr, "asked to load: %s\n", load->label); - add_load_cmd(item); + add_load_cmd(load); } - +fprintf(stderr, "\n"); return NL_STOP; } int main() { -struct nl_sock *sock; -int ret; +struct nl_handle *sock; +int ret, family; memset(&todo, 0, sizeof(todo)); - LIST_HEAD_INIT(&todo.list); + INIT_LIST_HEAD(&todo.list); // Allocate a new netlink socket - sock = nl_socket_alloc(); + sock = nl_handle_alloc(); if (sock == NULL) { err(); return ERR_CONNECT; @@ -122,14 +142,16 @@ int ret; exit(1); } - ret = _notify_listening(sock); + ret = _notify_listening(family, sock); if (ret < 0) { fprintf(stderr, "Could not notify kernel subsystem.\n"); exit(1); } + fprintf(stderr, "Notified kernel for being a listener...\n"); // Wait for the answer and receive it do { + fprintf(stderr, "Waiting for message...\n"); ret = nl_recvmsgs_default(sock); /* we have to consume the todo list */ @@ -140,12 +162,14 @@ int ret; } while (ret == 0); fprintf(stderr, "received: %d\n", ret); + return 0; } -static int _notify_listening(struct nl_sock * sock) +static int _notify_listening(int family, struct nl_handle * sock) { struct nl_msg *msg; -int family, ret; +void * hdr; +int ret; // Construct a generic netlink by allocating a new message, fill in // the header and append a simple integer attribute. @@ -155,8 +179,13 @@ int family, ret; return ERR_MEM; } - genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST, + hdr = genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST, CMD_LISTENING, NCR_NL_STORAGE_VERSION); + + if (hdr == NULL) { + err(); + return ERR_SEND; + } // Send message over netlink socket ret = nl_send_auto_complete(sock, msg); @@ -171,10 +200,10 @@ int family, ret; } -static int send_store_ack(struct nl_sock * sock, uint8_t val) +static int send_store_ack(int family, struct nl_handle * sock, uint8_t val) { struct nl_msg *msg; -int family, ret; +int ret; // Construct a generic netlink by allocating a new message, fill in // the header and append a simple integer attribute. @@ -187,7 +216,7 @@ int family, ret; genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST, CMD_STORE_ACK, NCR_NL_STORAGE_VERSION); - ret = nla_put_u8(msg, ATTR_STORE_ACK, val); + ret = nla_put_u8(msg, ATTR_STORE_U8, val); if (ret < 0) { err(); ret = ERR_SEND; |