| #include <stdlib.h> |
| #include <string.h> |
| |
| #include "iface_internal.h" |
| #include "context_internal.h" |
| #include "debug.h" |
| |
| struct sepol_iface { |
| |
| /* Interface name */ |
| char *name; |
| |
| /* Interface context */ |
| sepol_context_t *netif_con; |
| |
| /* Message context */ |
| sepol_context_t *netmsg_con; |
| }; |
| |
| struct sepol_iface_key { |
| |
| /* Interface name */ |
| const char *name; |
| }; |
| |
| /* Key */ |
| int sepol_iface_key_create(sepol_handle_t * handle, |
| const char *name, sepol_iface_key_t ** key_ptr) |
| { |
| |
| sepol_iface_key_t *tmp_key = |
| (sepol_iface_key_t *) malloc(sizeof(sepol_iface_key_t)); |
| |
| if (!tmp_key) { |
| ERR(handle, "out of memory, could not create interface key"); |
| return STATUS_ERR; |
| } |
| |
| tmp_key->name = name; |
| |
| *key_ptr = tmp_key; |
| return STATUS_SUCCESS; |
| } |
| |
| hidden_def(sepol_iface_key_create) |
| |
| void sepol_iface_key_unpack(const sepol_iface_key_t * key, const char **name) |
| { |
| |
| *name = key->name; |
| } |
| |
| hidden_def(sepol_iface_key_unpack) |
| |
| int sepol_iface_key_extract(sepol_handle_t * handle, |
| const sepol_iface_t * iface, |
| sepol_iface_key_t ** key_ptr) |
| { |
| |
| if (sepol_iface_key_create(handle, iface->name, key_ptr) < 0) { |
| ERR(handle, "could not extract key from " |
| "interface %s", iface->name); |
| return STATUS_ERR; |
| } |
| |
| return STATUS_SUCCESS; |
| } |
| |
| void sepol_iface_key_free(sepol_iface_key_t * key) |
| { |
| free(key); |
| } |
| |
| int sepol_iface_compare(const sepol_iface_t * iface, |
| const sepol_iface_key_t * key) |
| { |
| |
| return strcmp(iface->name, key->name); |
| } |
| |
| int sepol_iface_compare2(const sepol_iface_t * iface, |
| const sepol_iface_t * iface2) |
| { |
| |
| return strcmp(iface->name, iface2->name); |
| } |
| |
| /* Create */ |
| int sepol_iface_create(sepol_handle_t * handle, sepol_iface_t ** iface) |
| { |
| |
| sepol_iface_t *tmp_iface = |
| (sepol_iface_t *) malloc(sizeof(sepol_iface_t)); |
| |
| if (!tmp_iface) { |
| ERR(handle, "out of memory, could not create " |
| "interface record"); |
| return STATUS_ERR; |
| } |
| |
| tmp_iface->name = NULL; |
| tmp_iface->netif_con = NULL; |
| tmp_iface->netmsg_con = NULL; |
| *iface = tmp_iface; |
| |
| return STATUS_SUCCESS; |
| } |
| |
| hidden_def(sepol_iface_create) |
| |
| /* Name */ |
| const char *sepol_iface_get_name(const sepol_iface_t * iface) |
| { |
| |
| return iface->name; |
| } |
| |
| hidden_def(sepol_iface_get_name) |
| |
| int sepol_iface_set_name(sepol_handle_t * handle, |
| sepol_iface_t * iface, const char *name) |
| { |
| |
| char *tmp_name = strdup(name); |
| if (!tmp_name) { |
| ERR(handle, "out of memory, " "could not set interface name"); |
| return STATUS_ERR; |
| } |
| free(iface->name); |
| iface->name = tmp_name; |
| return STATUS_SUCCESS; |
| } |
| |
| hidden_def(sepol_iface_set_name) |
| |
| /* Interface Context */ |
| sepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface) |
| { |
| |
| return iface->netif_con; |
| } |
| |
| hidden_def(sepol_iface_get_ifcon) |
| |
| int sepol_iface_set_ifcon(sepol_handle_t * handle, |
| sepol_iface_t * iface, sepol_context_t * con) |
| { |
| |
| sepol_context_t *newcon; |
| |
| if (sepol_context_clone(handle, con, &newcon) < 0) { |
| ERR(handle, "out of memory, could not set interface context"); |
| return STATUS_ERR; |
| } |
| |
| sepol_context_free(iface->netif_con); |
| iface->netif_con = newcon; |
| return STATUS_SUCCESS; |
| } |
| |
| hidden_def(sepol_iface_set_ifcon) |
| |
| /* Message Context */ |
| sepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface) |
| { |
| |
| return iface->netmsg_con; |
| } |
| |
| hidden_def(sepol_iface_get_msgcon) |
| |
| int sepol_iface_set_msgcon(sepol_handle_t * handle, |
| sepol_iface_t * iface, sepol_context_t * con) |
| { |
| |
| sepol_context_t *newcon; |
| if (sepol_context_clone(handle, con, &newcon) < 0) { |
| ERR(handle, "out of memory, could not set message context"); |
| return STATUS_ERR; |
| } |
| |
| sepol_context_free(iface->netmsg_con); |
| iface->netmsg_con = newcon; |
| return STATUS_SUCCESS; |
| } |
| |
| hidden_def(sepol_iface_set_msgcon) |
| |
| /* Deep copy clone */ |
| int sepol_iface_clone(sepol_handle_t * handle, |
| const sepol_iface_t * iface, sepol_iface_t ** iface_ptr) |
| { |
| |
| sepol_iface_t *new_iface = NULL; |
| if (sepol_iface_create(handle, &new_iface) < 0) |
| goto err; |
| |
| if (sepol_iface_set_name(handle, new_iface, iface->name) < 0) |
| goto err; |
| |
| if (iface->netif_con && |
| (sepol_context_clone |
| (handle, iface->netif_con, &new_iface->netif_con) < 0)) |
| goto err; |
| |
| if (iface->netmsg_con && |
| (sepol_context_clone |
| (handle, iface->netmsg_con, &new_iface->netmsg_con) < 0)) |
| goto err; |
| |
| *iface_ptr = new_iface; |
| return STATUS_SUCCESS; |
| |
| err: |
| ERR(handle, "could not clone interface record"); |
| sepol_iface_free(new_iface); |
| return STATUS_ERR; |
| } |
| |
| /* Destroy */ |
| void sepol_iface_free(sepol_iface_t * iface) |
| { |
| |
| if (!iface) |
| return; |
| |
| free(iface->name); |
| sepol_context_free(iface->netif_con); |
| sepol_context_free(iface->netmsg_con); |
| free(iface); |
| } |
| |
| hidden_def(sepol_iface_free) |