|
Packit |
51d0f7 |
/** @file
|
|
Packit |
51d0f7 |
* Management Module Functions
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Author: Paul Moore <paul@paul-moore.com>
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/*
|
|
Packit |
51d0f7 |
* (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* This program is free software: you can redistribute it and/or modify
|
|
Packit |
51d0f7 |
* it under the terms of version 2 of the GNU General Public License as
|
|
Packit |
51d0f7 |
* published by the Free Software Foundation.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
51d0f7 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
51d0f7 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
51d0f7 |
* GNU General Public License for more details.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
51d0f7 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
#include <stdlib.h>
|
|
Packit |
51d0f7 |
#include <errno.h>
|
|
Packit |
51d0f7 |
#include <sys/types.h>
|
|
Packit |
51d0f7 |
#include <sys/socket.h>
|
|
Packit |
51d0f7 |
#include <linux/types.h>
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
#include <libnetlabel.h>
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
#include "netlabel_internal.h"
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* Generic Netlink family ID */
|
|
Packit |
51d0f7 |
static uint16_t nlbl_mgmt_fid = 0;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/*
|
|
Packit |
51d0f7 |
* Helper functions
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* Create a new NetLabel management message
|
|
Packit |
51d0f7 |
* @param command the NetLabel management command
|
|
Packit |
51d0f7 |
* @param flags the message flags
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* This function creates a new NetLabel management message using @command and
|
|
Packit |
51d0f7 |
* @flags. Returns a pointer to the new message on success, or NULL on
|
|
Packit |
51d0f7 |
* failure.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
static nlbl_msg *nlbl_mgmt_msg_new(uint16_t command, int flags)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
nlbl_msg *msg;
|
|
Packit |
51d0f7 |
struct nlmsghdr *nl_hdr;
|
|
Packit |
51d0f7 |
struct genlmsghdr *genl_hdr;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* create a new message */
|
|
Packit |
51d0f7 |
msg = nlbl_msg_new();
|
|
Packit |
51d0f7 |
if (msg == NULL)
|
|
Packit |
51d0f7 |
goto msg_new_failure;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* setup the netlink header */
|
|
Packit |
51d0f7 |
nl_hdr = nlbl_msg_nlhdr(msg);
|
|
Packit |
51d0f7 |
if (nl_hdr == NULL)
|
|
Packit |
51d0f7 |
goto msg_new_failure;
|
|
Packit |
51d0f7 |
nl_hdr->nlmsg_type = nlbl_mgmt_fid;
|
|
Packit |
51d0f7 |
nl_hdr->nlmsg_flags = flags;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* setup the generic netlink header */
|
|
Packit |
51d0f7 |
genl_hdr = nlbl_msg_genlhdr(msg);
|
|
Packit |
51d0f7 |
if (genl_hdr == NULL)
|
|
Packit |
51d0f7 |
goto msg_new_failure;
|
|
Packit |
51d0f7 |
genl_hdr->cmd = command;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
return msg;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
msg_new_failure:
|
|
Packit |
51d0f7 |
nlbl_msg_free(msg);
|
|
Packit |
51d0f7 |
return NULL;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* Read a NetLabel management message
|
|
Packit |
51d0f7 |
* @param hndl the NetLabel handle
|
|
Packit |
51d0f7 |
* @param msg the message
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Try to read a NetLabel management message and return the message in @msg.
|
|
Packit |
51d0f7 |
* Returns the number of bytes read on success, zero on EOF, and negative
|
|
Packit |
51d0f7 |
* values on failure.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
static int nlbl_mgmt_recv(struct nlbl_handle *hndl, nlbl_msg **msg)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
int rc;
|
|
Packit |
51d0f7 |
struct nlmsghdr *nl_hdr;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* try to get a message from the handle */
|
|
Packit |
51d0f7 |
rc = nlbl_comm_recv(hndl, msg);
|
|
Packit |
51d0f7 |
if (rc <= 0)
|
|
Packit |
51d0f7 |
goto recv_failure;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* process the response */
|
|
Packit |
51d0f7 |
nl_hdr = nlbl_msg_nlhdr(*msg);
|
|
Packit |
51d0f7 |
if (nl_hdr == NULL || (nl_hdr->nlmsg_type != nlbl_mgmt_fid &&
|
|
Packit |
51d0f7 |
nl_hdr->nlmsg_type != NLMSG_DONE &&
|
|
Packit |
51d0f7 |
nl_hdr->nlmsg_type != NLMSG_ERROR)) {
|
|
Packit |
51d0f7 |
rc = -EBADMSG;
|
|
Packit |
51d0f7 |
goto recv_failure;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
return rc;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
recv_failure:
|
|
Packit |
51d0f7 |
nlbl_msg_free(*msg);
|
|
Packit |
51d0f7 |
return rc;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* Parse an ACK message
|
|
Packit |
51d0f7 |
* @param msg the message
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Parse the ACK message in @msg and return the error code specified in the
|
|
Packit |
51d0f7 |
* ACK.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
static int nlbl_mgmt_parse_ack(nlbl_msg *msg)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
struct nlmsgerr *nl_err;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
nl_err = nlbl_msg_err(msg);
|
|
Packit |
51d0f7 |
if (nl_err == NULL)
|
|
Packit |
51d0f7 |
return -ENOMSG;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
return nl_err->error;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* Parse a LIST message with address selectors
|
|
Packit |
51d0f7 |
* @param nla_head the NLBL_MGMT_A_SELECTORLIST attribute
|
|
Packit |
51d0f7 |
* @param domain the domain mapping entry
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Parse the NLBL_MGMT_A_SELECTORLIST attribute and populate @domain with
|
|
Packit |
51d0f7 |
* the information. Returns zero on success, negative values on failure.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
static int nlbl_mgmt_list_addr(const struct nlattr *nla_head,
|
|
Packit |
51d0f7 |
struct nlbl_dommap *domain)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
struct nlbl_dommap_addr *addr_iter;
|
|
Packit |
51d0f7 |
struct nlattr *nla_a;
|
|
Packit |
51d0f7 |
struct nlattr *nla_b;
|
|
Packit |
51d0f7 |
int nla_a_rem;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
domain->proto_type = NETLBL_NLTYPE_ADDRSELECT;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* parse the attributes */
|
|
Packit |
51d0f7 |
nla_for_each_attr(nla_a,
|
|
Packit |
51d0f7 |
nla_data(nla_head), nla_len(nla_head),
|
|
Packit |
51d0f7 |
nla_a_rem)
|
|
Packit |
51d0f7 |
if (nla_a->nla_type == NLBL_MGMT_A_ADDRSELECTOR) {
|
|
Packit |
51d0f7 |
addr_iter = malloc(sizeof(*addr_iter));
|
|
Packit |
51d0f7 |
if (addr_iter == NULL)
|
|
Packit |
51d0f7 |
return -ENOMEM;
|
|
Packit |
51d0f7 |
memset(addr_iter, 0, sizeof(*addr_iter));
|
|
Packit |
51d0f7 |
if (domain->proto.addrsel != NULL) {
|
|
Packit |
51d0f7 |
struct nlbl_dommap_addr *iter;
|
|
Packit |
51d0f7 |
iter = domain->proto.addrsel;
|
|
Packit |
51d0f7 |
while (iter->next != NULL)
|
|
Packit |
51d0f7 |
iter = iter->next;
|
|
Packit |
51d0f7 |
iter->next = addr_iter;
|
|
Packit |
51d0f7 |
} else
|
|
Packit |
51d0f7 |
domain->proto.addrsel = addr_iter;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
nla_b = nla_find(nla_data(nla_a), nla_len(nla_a),
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_IPV4ADDR);
|
|
Packit |
51d0f7 |
if (nla_b != NULL) {
|
|
Packit |
51d0f7 |
if (nla_len(nla_b) != sizeof(struct in_addr))
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
memcpy(&addr_iter->addr.addr.v4,
|
|
Packit |
51d0f7 |
nla_data(nla_b), nla_len(nla_b));
|
|
Packit |
51d0f7 |
nla_b = nla_find(nla_data(nla_a),
|
|
Packit |
51d0f7 |
nla_len(nla_a),
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_IPV4MASK);
|
|
Packit |
51d0f7 |
if (nla_b == NULL ||
|
|
Packit |
51d0f7 |
nla_len(nla_b) != sizeof(struct in_addr))
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
memcpy(&addr_iter->addr.mask.v4,
|
|
Packit |
51d0f7 |
nla_data(nla_b), nla_len(nla_b));
|
|
Packit |
51d0f7 |
addr_iter->addr.type = AF_INET;
|
|
Packit |
51d0f7 |
nla_b = nla_find(nla_data(nla_a),
|
|
Packit |
51d0f7 |
nla_len(nla_a),
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_PROTOCOL);
|
|
Packit |
51d0f7 |
if (nla_b == NULL)
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
addr_iter->proto_type = nla_get_u32(nla_b);
|
|
Packit |
51d0f7 |
switch (addr_iter->proto_type) {
|
|
Packit |
51d0f7 |
case NETLBL_NLTYPE_CIPSOV4:
|
|
Packit |
51d0f7 |
nla_b = nla_find(nla_data(nla_a),
|
|
Packit |
51d0f7 |
nla_len(nla_a),
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_CV4DOI);
|
|
Packit |
51d0f7 |
if (nla_b == NULL)
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
addr_iter->proto.cip_doi =
|
|
Packit |
51d0f7 |
nla_get_u32(nla_b);
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
} else if ((nla_b = nla_find(nla_data(nla_a),
|
|
Packit |
51d0f7 |
nla_len(nla_a),
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_IPV6ADDR))) {
|
|
Packit |
51d0f7 |
if (nla_len(nla_b) != sizeof(struct in6_addr))
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
memcpy(&addr_iter->addr.addr.v6,
|
|
Packit |
51d0f7 |
nla_data(nla_b), nla_len(nla_b));
|
|
Packit |
51d0f7 |
nla_b = nla_find(nla_data(nla_a),
|
|
Packit |
51d0f7 |
nla_len(nla_a),
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_IPV6MASK);
|
|
Packit |
51d0f7 |
if (nla_b == NULL ||
|
|
Packit |
51d0f7 |
nla_len(nla_b) != sizeof(struct in6_addr))
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
memcpy(&addr_iter->addr.mask.v6,
|
|
Packit |
51d0f7 |
nla_data(nla_b), nla_len(nla_b));
|
|
Packit |
51d0f7 |
addr_iter->addr.type = AF_INET6;
|
|
Packit |
51d0f7 |
nla_b = nla_find(nla_data(nla_a),
|
|
Packit |
51d0f7 |
nla_len(nla_a),
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_PROTOCOL);
|
|
Packit |
51d0f7 |
if (nla_b == NULL)
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
addr_iter->proto_type = nla_get_u32(nla_b);
|
|
Packit |
51d0f7 |
switch (addr_iter->proto_type) {
|
|
Packit |
51d0f7 |
case NETLBL_NLTYPE_CALIPSO:
|
|
Packit |
51d0f7 |
nla_b = nla_find(nla_data(nla_a),
|
|
Packit |
51d0f7 |
nla_len(nla_a),
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_CLPDOI);
|
|
Packit |
51d0f7 |
if (nla_b == NULL)
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
addr_iter->proto.clp_doi =
|
|
Packit |
51d0f7 |
nla_get_u32(nla_b);
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
} else
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
return 0;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/*
|
|
Packit |
51d0f7 |
* Init functions
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* Perform any setup needed
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Do any setup needed for the management component, including determining the
|
|
Packit |
51d0f7 |
* NetLabel Mangement Generic Netlink family ID. Returns zero on success,
|
|
Packit |
51d0f7 |
* negative values on error.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
int nlbl_mgmt_init(void)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
int rc = -ENOMEM;
|
|
Packit |
51d0f7 |
struct nlbl_handle *hndl;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* get a netlabel handle */
|
|
Packit |
51d0f7 |
hndl = nlbl_comm_open();
|
|
Packit |
51d0f7 |
if (hndl == NULL)
|
|
Packit |
51d0f7 |
goto init_return;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* resolve the family */
|
|
Packit |
51d0f7 |
rc = genl_ctrl_resolve(hndl->nl_sock, NETLBL_NLTYPE_MGMT_NAME);
|
|
Packit |
51d0f7 |
if (rc < 0)
|
|
Packit |
51d0f7 |
goto init_return;
|
|
Packit |
51d0f7 |
nlbl_mgmt_fid = rc;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
rc = 0;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
init_return:
|
|
Packit |
51d0f7 |
nlbl_comm_close(hndl);
|
|
Packit |
51d0f7 |
return rc;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/*
|
|
Packit |
51d0f7 |
* NetLabel operations
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* Determine the supported list of NetLabel protocols
|
|
Packit |
51d0f7 |
* @param hndl the NetLabel handle
|
|
Packit |
51d0f7 |
* @param protocols protocol array
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Query the NetLabel subsystem and return the supported protocols in
|
|
Packit |
51d0f7 |
* @protocols. If @hndl is NULL then the function will handle opening and
|
|
Packit |
51d0f7 |
* closing it's own NetLabel handle. Returns the number of protocols on
|
|
Packit |
51d0f7 |
* success, zero if no protocols are supported, and negative values on failure.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
int nlbl_mgmt_protocols(struct nlbl_handle *hndl, nlbl_proto **protocols)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
int rc = -ENOMEM;
|
|
Packit |
51d0f7 |
struct nlbl_handle *p_hndl = hndl;
|
|
Packit |
51d0f7 |
unsigned char *data = NULL;
|
|
Packit |
51d0f7 |
nlbl_msg *msg = NULL;
|
|
Packit |
51d0f7 |
struct nlmsghdr *nl_hdr;
|
|
Packit |
51d0f7 |
struct genlmsghdr *genl_hdr;
|
|
Packit |
51d0f7 |
struct nlattr *nla_head;
|
|
Packit |
51d0f7 |
struct nlattr *nla;
|
|
Packit |
51d0f7 |
int data_len;
|
|
Packit |
51d0f7 |
int data_attrlen;
|
|
Packit |
51d0f7 |
nlbl_proto *protos = NULL, *protos_new;
|
|
Packit |
51d0f7 |
uint32_t protos_count = 0;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* sanity checks */
|
|
Packit |
51d0f7 |
if (protocols == NULL)
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
if (nlbl_mgmt_fid == 0)
|
|
Packit |
51d0f7 |
return -ENOPROTOOPT;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* open a handle if we need one */
|
|
Packit |
51d0f7 |
if (p_hndl == NULL) {
|
|
Packit |
51d0f7 |
p_hndl = nlbl_comm_open();
|
|
Packit |
51d0f7 |
if (p_hndl == NULL)
|
|
Packit |
51d0f7 |
goto protocols_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* create a new message */
|
|
Packit |
51d0f7 |
msg = nlbl_mgmt_msg_new(NLBL_MGMT_C_PROTOCOLS, NLM_F_DUMP);
|
|
Packit |
51d0f7 |
if (msg == NULL) {
|
|
Packit |
51d0f7 |
rc = -ENOMEM;
|
|
Packit |
51d0f7 |
goto protocols_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* send the request */
|
|
Packit |
51d0f7 |
rc = nlbl_comm_send(p_hndl, msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto protocols_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* read all of the messages (multi-message response) */
|
|
Packit |
51d0f7 |
do {
|
|
Packit |
51d0f7 |
if (data != NULL) {
|
|
Packit |
51d0f7 |
free(data);
|
|
Packit |
51d0f7 |
data = NULL;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* get the next set of messages */
|
|
Packit |
51d0f7 |
rc = nlbl_comm_recv_raw(p_hndl, &data);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto protocols_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
data_len = rc;
|
|
Packit |
51d0f7 |
nl_hdr = (struct nlmsghdr *)data;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* check to see if this is a netlink control message we don't
|
|
Packit |
51d0f7 |
* care about */
|
|
Packit |
51d0f7 |
if (nl_hdr->nlmsg_type == NLMSG_NOOP ||
|
|
Packit |
51d0f7 |
nl_hdr->nlmsg_type == NLMSG_ERROR ||
|
|
Packit |
51d0f7 |
nl_hdr->nlmsg_type == NLMSG_OVERRUN) {
|
|
Packit |
51d0f7 |
rc = -EBADMSG;
|
|
Packit |
51d0f7 |
goto protocols_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* loop through the messages */
|
|
Packit |
51d0f7 |
while (nlmsg_ok(nl_hdr, data_len) &&
|
|
Packit |
51d0f7 |
nl_hdr->nlmsg_type != NLMSG_DONE) {
|
|
Packit |
51d0f7 |
/* get the header pointers */
|
|
Packit |
51d0f7 |
genl_hdr = (struct genlmsghdr *)nlmsg_data(nl_hdr);
|
|
Packit |
51d0f7 |
if (genl_hdr == NULL ||
|
|
Packit |
51d0f7 |
genl_hdr->cmd != NLBL_MGMT_C_PROTOCOLS) {
|
|
Packit |
51d0f7 |
rc = -EBADMSG;
|
|
Packit |
51d0f7 |
goto protocols_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
nla_head = (struct nlattr *)(&genl_hdr[1]);
|
|
Packit |
51d0f7 |
data_attrlen = genlmsg_attrlen(genl_hdr, 0);
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* resize the array */
|
|
Packit |
51d0f7 |
protos_new = realloc(protos,
|
|
Packit |
51d0f7 |
sizeof(nlbl_proto) *
|
|
Packit |
51d0f7 |
(protos_count + 1));
|
|
Packit |
51d0f7 |
if (protos_new == NULL)
|
|
Packit |
51d0f7 |
goto protocols_return;
|
|
Packit |
51d0f7 |
protos = protos_new;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* get the attribute information */
|
|
Packit |
51d0f7 |
nla = nla_find(nla_head,
|
|
Packit |
51d0f7 |
data_attrlen, NLBL_MGMT_A_PROTOCOL);
|
|
Packit |
51d0f7 |
if (nla == NULL)
|
|
Packit |
51d0f7 |
goto protocols_return;
|
|
Packit |
51d0f7 |
protos[protos_count] = nla_get_u32(nla);
|
|
Packit |
51d0f7 |
protos_count++;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* next message */
|
|
Packit |
51d0f7 |
nl_hdr = nlmsg_next(nl_hdr, &data_len);
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
} while (NL_MULTI_CONTINUE(nl_hdr));
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
*protocols = protos;
|
|
Packit |
51d0f7 |
rc = protos_count;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
protocols_return:
|
|
Packit |
51d0f7 |
if (rc < 0 && protos)
|
|
Packit |
51d0f7 |
free(protos);
|
|
Packit |
51d0f7 |
if (hndl == NULL)
|
|
Packit |
51d0f7 |
nlbl_comm_close(p_hndl);
|
|
Packit |
51d0f7 |
if (data != NULL)
|
|
Packit |
51d0f7 |
free(data);
|
|
Packit |
51d0f7 |
nlbl_msg_free(msg);
|
|
Packit |
51d0f7 |
return rc;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* Determine the kernel's NetLabel protocol version
|
|
Packit |
51d0f7 |
* @param hndl the NetLabel handle
|
|
Packit |
51d0f7 |
* @param version the protocol version
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Request the NetLabel protocol version from the kernel and return the result
|
|
Packit |
51d0f7 |
* to the caller. If @hndl is NULL then the function will handle opening and
|
|
Packit |
51d0f7 |
* closing it's own NetLabel handle. Returns zero on success, negative values
|
|
Packit |
51d0f7 |
* on failure.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
int nlbl_mgmt_version(struct nlbl_handle *hndl, uint32_t *version)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
int rc = -ENOMEM;
|
|
Packit |
51d0f7 |
struct nlbl_handle *p_hndl = hndl;
|
|
Packit |
51d0f7 |
nlbl_msg *msg = NULL;
|
|
Packit |
51d0f7 |
nlbl_msg *ans_msg = NULL;
|
|
Packit |
51d0f7 |
struct genlmsghdr *genl_hdr;
|
|
Packit |
51d0f7 |
struct nlattr *nla;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* sanity checks */
|
|
Packit |
51d0f7 |
if (version == NULL)
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
if (nlbl_mgmt_fid == 0)
|
|
Packit |
51d0f7 |
return -ENOPROTOOPT;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* open a handle if we need one */
|
|
Packit |
51d0f7 |
if (p_hndl == NULL) {
|
|
Packit |
51d0f7 |
p_hndl = nlbl_comm_open();
|
|
Packit |
51d0f7 |
if (p_hndl == NULL)
|
|
Packit |
51d0f7 |
goto version_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* create a new message */
|
|
Packit |
51d0f7 |
msg = nlbl_mgmt_msg_new(NLBL_MGMT_C_VERSION, 0);
|
|
Packit |
51d0f7 |
if (msg == NULL)
|
|
Packit |
51d0f7 |
goto version_return;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* send the request */
|
|
Packit |
51d0f7 |
rc = nlbl_comm_send(p_hndl, msg);
|
|
Packit |
51d0f7 |
if (rc == 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto version_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* read the response */
|
|
Packit |
51d0f7 |
rc = nlbl_mgmt_recv(p_hndl, &ans_msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto version_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* check the response */
|
|
Packit |
51d0f7 |
rc = nlbl_mgmt_parse_ack(ans_msg);
|
|
Packit |
51d0f7 |
if (rc < 0 && rc != -ENOMSG)
|
|
Packit |
51d0f7 |
goto version_return;
|
|
Packit |
51d0f7 |
genl_hdr = nlbl_msg_genlhdr(ans_msg);
|
|
Packit |
51d0f7 |
if (genl_hdr == NULL || genl_hdr->cmd != NLBL_MGMT_C_VERSION) {
|
|
Packit |
51d0f7 |
rc = -EBADMSG;
|
|
Packit |
51d0f7 |
goto version_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* process the response */
|
|
Packit |
51d0f7 |
nla = nlbl_attr_find(ans_msg, NLBL_MGMT_A_VERSION);
|
|
Packit |
51d0f7 |
if (nla == NULL) {
|
|
Packit |
51d0f7 |
rc = -EBADMSG;
|
|
Packit |
51d0f7 |
goto version_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
*version = nla_get_u32(nla);
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
rc = 0;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
version_return:
|
|
Packit |
51d0f7 |
if (hndl == NULL)
|
|
Packit |
51d0f7 |
nlbl_comm_close(p_hndl);
|
|
Packit |
51d0f7 |
nlbl_msg_free(msg);
|
|
Packit |
51d0f7 |
nlbl_msg_free(ans_msg);
|
|
Packit |
51d0f7 |
return rc;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* Add a domain mapping to the NetLabel system
|
|
Packit |
51d0f7 |
* @param hndl the NetLabel handle
|
|
Packit |
51d0f7 |
* @param domain the NetLabel domain map
|
|
Packit |
51d0f7 |
* @param addr the network IP address
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Add the domain mapping in @domain to the NetLabel system. If @hndl is NULL
|
|
Packit |
51d0f7 |
* then the function will handle opening and closing it's own NetLabel handle.
|
|
Packit |
51d0f7 |
* Returns zero on success, negative values on failure.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
int nlbl_mgmt_add(struct nlbl_handle *hndl,
|
|
Packit |
51d0f7 |
struct nlbl_dommap *domain,
|
|
Packit |
51d0f7 |
struct nlbl_netaddr *addr)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
int rc = -ENOMEM;
|
|
Packit |
51d0f7 |
struct nlbl_handle *p_hndl = hndl;
|
|
Packit |
51d0f7 |
nlbl_msg *msg = NULL;
|
|
Packit |
51d0f7 |
nlbl_msg *ans_msg = NULL;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* sanity checks */
|
|
Packit |
51d0f7 |
if (domain == NULL || domain->domain == NULL)
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
if (nlbl_mgmt_fid == 0)
|
|
Packit |
51d0f7 |
return -ENOPROTOOPT;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* open a handle if we need one */
|
|
Packit |
51d0f7 |
if (p_hndl == NULL) {
|
|
Packit |
51d0f7 |
p_hndl = nlbl_comm_open();
|
|
Packit |
51d0f7 |
if (p_hndl == NULL)
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* create a new message */
|
|
Packit |
51d0f7 |
msg = nlbl_mgmt_msg_new(NLBL_MGMT_C_ADD, 0);
|
|
Packit |
51d0f7 |
if (msg == NULL)
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* add the required attributes to the message */
|
|
Packit |
51d0f7 |
rc = nla_put_string(msg, NLBL_MGMT_A_DOMAIN, domain->domain);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
rc = nla_put_u32(msg, NLBL_MGMT_A_PROTOCOL, domain->proto_type);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
rc = nla_put_u16(msg, NLBL_MGMT_A_FAMILY, domain->family);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
switch (domain->proto_type) {
|
|
Packit |
51d0f7 |
case NETLBL_NLTYPE_CIPSOV4:
|
|
Packit |
51d0f7 |
rc = nla_put_u32(msg,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_CV4DOI,
|
|
Packit |
51d0f7 |
domain->proto.cip_doi);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
case NETLBL_NLTYPE_CALIPSO:
|
|
Packit |
51d0f7 |
rc = nla_put_u32(msg,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_CLPDOI,
|
|
Packit |
51d0f7 |
domain->proto.clp_doi);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* optional attributes */
|
|
Packit |
51d0f7 |
switch (addr->type) {
|
|
Packit |
51d0f7 |
case AF_INET:
|
|
Packit |
51d0f7 |
rc = nla_put(msg,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_IPV4ADDR,
|
|
Packit |
51d0f7 |
sizeof(struct in_addr),
|
|
Packit |
51d0f7 |
&addr->addr.v4);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
rc = nla_put(msg,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_IPV4MASK,
|
|
Packit |
51d0f7 |
sizeof(struct in_addr),
|
|
Packit |
51d0f7 |
&addr->mask.v4);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
case AF_INET6:
|
|
Packit |
51d0f7 |
rc = nla_put(msg,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_IPV6ADDR,
|
|
Packit |
51d0f7 |
sizeof(struct in6_addr),
|
|
Packit |
51d0f7 |
&addr->addr.v6);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
rc = nla_put(msg,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_IPV6MASK,
|
|
Packit |
51d0f7 |
sizeof(struct in6_addr),
|
|
Packit |
51d0f7 |
&addr->mask.v6);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
case 0:
|
|
Packit |
51d0f7 |
rc = 0;
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
default:
|
|
Packit |
51d0f7 |
rc = -EINVAL;
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* send the request */
|
|
Packit |
51d0f7 |
rc = nlbl_comm_send(p_hndl, msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* read the response */
|
|
Packit |
51d0f7 |
rc = nlbl_mgmt_recv(p_hndl, &ans_msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto add_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* process the response */
|
|
Packit |
51d0f7 |
rc = nlbl_mgmt_parse_ack(ans_msg);
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
add_return:
|
|
Packit |
51d0f7 |
if (hndl == NULL)
|
|
Packit |
51d0f7 |
nlbl_comm_close(p_hndl);
|
|
Packit |
51d0f7 |
nlbl_msg_free(msg);
|
|
Packit |
51d0f7 |
nlbl_msg_free(ans_msg);
|
|
Packit |
51d0f7 |
return rc;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* Add the default domain mapping to the NetLabel system
|
|
Packit |
51d0f7 |
* @param hndl the NetLabel handle
|
|
Packit |
51d0f7 |
* @param domain the NetLabel domain map
|
|
Packit |
51d0f7 |
* @param addr the network IP address
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Add the domain mapping in @domain to the NetLabel system as the default
|
|
Packit |
51d0f7 |
* mapping. If @hndl is NULL then the function will handle opening and
|
|
Packit |
51d0f7 |
* closing it's own NetLabel handle. Returns zero on success, negative values
|
|
Packit |
51d0f7 |
* on failure.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
int nlbl_mgmt_adddef(struct nlbl_handle *hndl,
|
|
Packit |
51d0f7 |
struct nlbl_dommap *domain,
|
|
Packit |
51d0f7 |
struct nlbl_netaddr *addr)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
int rc = -ENOMEM;
|
|
Packit |
51d0f7 |
struct nlbl_handle *p_hndl = hndl;
|
|
Packit |
51d0f7 |
nlbl_msg *msg = NULL;
|
|
Packit |
51d0f7 |
nlbl_msg *ans_msg = NULL;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* sanity checks */
|
|
Packit |
51d0f7 |
if (domain == NULL)
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
if (nlbl_mgmt_fid == 0)
|
|
Packit |
51d0f7 |
return -ENOPROTOOPT;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* open a handle if we need one */
|
|
Packit |
51d0f7 |
if (p_hndl == NULL) {
|
|
Packit |
51d0f7 |
p_hndl = nlbl_comm_open();
|
|
Packit |
51d0f7 |
if (p_hndl == NULL)
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* create a new message */
|
|
Packit |
51d0f7 |
msg = nlbl_mgmt_msg_new(NLBL_MGMT_C_ADDDEF, 0);
|
|
Packit |
51d0f7 |
if (msg == NULL)
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* add the required attributes to the message */
|
|
Packit |
51d0f7 |
rc = nla_put_u32(msg, NLBL_MGMT_A_PROTOCOL, domain->proto_type);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
rc = nla_put_u16(msg, NLBL_MGMT_A_FAMILY, domain->family);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
switch (domain->proto_type) {
|
|
Packit |
51d0f7 |
case NETLBL_NLTYPE_CIPSOV4:
|
|
Packit |
51d0f7 |
rc = nla_put_u32(msg,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_CV4DOI,
|
|
Packit |
51d0f7 |
domain->proto.cip_doi);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
case NETLBL_NLTYPE_CALIPSO:
|
|
Packit |
51d0f7 |
rc = nla_put_u32(msg,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_CLPDOI,
|
|
Packit |
51d0f7 |
domain->proto.clp_doi);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* optional attributes */
|
|
Packit |
51d0f7 |
switch (addr->type) {
|
|
Packit |
51d0f7 |
case AF_INET:
|
|
Packit |
51d0f7 |
rc = nla_put(msg,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_IPV4ADDR,
|
|
Packit |
51d0f7 |
sizeof(struct in_addr),
|
|
Packit |
51d0f7 |
&addr->addr.v4);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
rc = nla_put(msg,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_IPV4MASK,
|
|
Packit |
51d0f7 |
sizeof(struct in_addr),
|
|
Packit |
51d0f7 |
&addr->mask.v4);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
case AF_INET6:
|
|
Packit |
51d0f7 |
rc = nla_put(msg,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_IPV6ADDR,
|
|
Packit |
51d0f7 |
sizeof(struct in6_addr),
|
|
Packit |
51d0f7 |
&addr->addr.v6);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
rc = nla_put(msg,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_IPV6MASK,
|
|
Packit |
51d0f7 |
sizeof(struct in6_addr),
|
|
Packit |
51d0f7 |
&addr->mask.v6);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
case 0:
|
|
Packit |
51d0f7 |
rc = 0;
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
default:
|
|
Packit |
51d0f7 |
rc = -EINVAL;
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* send the request */
|
|
Packit |
51d0f7 |
rc = nlbl_comm_send(p_hndl, msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* read the response */
|
|
Packit |
51d0f7 |
rc = nlbl_mgmt_recv(p_hndl, &ans_msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto adddef_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* process the response */
|
|
Packit |
51d0f7 |
rc = nlbl_mgmt_parse_ack(ans_msg);
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
adddef_return:
|
|
Packit |
51d0f7 |
if (hndl == NULL)
|
|
Packit |
51d0f7 |
nlbl_comm_close(p_hndl);
|
|
Packit |
51d0f7 |
nlbl_msg_free(msg);
|
|
Packit |
51d0f7 |
nlbl_msg_free(ans_msg);
|
|
Packit |
51d0f7 |
return rc;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* Remove a domain mapping from the NetLabel system
|
|
Packit |
51d0f7 |
* @param hndl the NetLabel handle
|
|
Packit |
51d0f7 |
* @param domain the domain
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Remove the domain mapping specified by @domain from the NetLabel system.
|
|
Packit |
51d0f7 |
* If @hndl is NULL then the function will handle opening and closing it's own
|
|
Packit |
51d0f7 |
* NetLabel handle. Returns zero on success, negative values on failure.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
int nlbl_mgmt_del(struct nlbl_handle *hndl, char *domain)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
int rc = -ENOMEM;
|
|
Packit |
51d0f7 |
struct nlbl_handle *p_hndl = hndl;
|
|
Packit |
51d0f7 |
nlbl_msg *msg = NULL;
|
|
Packit |
51d0f7 |
nlbl_msg *ans_msg = NULL;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* sanity checks */
|
|
Packit |
51d0f7 |
if (domain == NULL)
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
if (nlbl_mgmt_fid == 0)
|
|
Packit |
51d0f7 |
return -ENOPROTOOPT;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* open a handle if we need one */
|
|
Packit |
51d0f7 |
if (p_hndl == NULL) {
|
|
Packit |
51d0f7 |
p_hndl = nlbl_comm_open();
|
|
Packit |
51d0f7 |
if (p_hndl == NULL)
|
|
Packit |
51d0f7 |
goto del_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* create a new message */
|
|
Packit |
51d0f7 |
msg = nlbl_mgmt_msg_new(NLBL_MGMT_C_REMOVE, 0);
|
|
Packit |
51d0f7 |
if (msg == NULL)
|
|
Packit |
51d0f7 |
goto del_return;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* add the required attributes to the message */
|
|
Packit |
51d0f7 |
rc = nla_put_string(msg, NLBL_MGMT_A_DOMAIN, domain);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto del_return;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* send the request */
|
|
Packit |
51d0f7 |
rc = nlbl_comm_send(p_hndl, msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto del_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* read the response */
|
|
Packit |
51d0f7 |
rc = nlbl_mgmt_recv(p_hndl, &ans_msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto del_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* process the response */
|
|
Packit |
51d0f7 |
rc = nlbl_mgmt_parse_ack(ans_msg);
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
del_return:
|
|
Packit |
51d0f7 |
if (hndl == NULL)
|
|
Packit |
51d0f7 |
nlbl_comm_close(p_hndl);
|
|
Packit |
51d0f7 |
nlbl_msg_free(msg);
|
|
Packit |
51d0f7 |
nlbl_msg_free(ans_msg);
|
|
Packit |
51d0f7 |
return rc;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* Remove the default domain mapping from NetLabel
|
|
Packit |
51d0f7 |
* @param hndl the NetLabel handle
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Remove the default domain mapping from the NetLabel system. If @hndl is
|
|
Packit |
51d0f7 |
* NULL then the function will handle opening and closing it's own NetLabel
|
|
Packit |
51d0f7 |
* handle. Returns zero on success, negative values on failure.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
int nlbl_mgmt_deldef(struct nlbl_handle *hndl)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
int rc = -ENOMEM;
|
|
Packit |
51d0f7 |
struct nlbl_handle *p_hndl = hndl;
|
|
Packit |
51d0f7 |
nlbl_msg *msg = NULL;
|
|
Packit |
51d0f7 |
nlbl_msg *ans_msg = NULL;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* sanity checks */
|
|
Packit |
51d0f7 |
if (nlbl_mgmt_fid == 0)
|
|
Packit |
51d0f7 |
return -ENOPROTOOPT;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* open a handle if we need one */
|
|
Packit |
51d0f7 |
if (p_hndl == NULL) {
|
|
Packit |
51d0f7 |
p_hndl = nlbl_comm_open();
|
|
Packit |
51d0f7 |
if (p_hndl == NULL)
|
|
Packit |
51d0f7 |
goto deldef_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* create a new message */
|
|
Packit |
51d0f7 |
msg = nlbl_mgmt_msg_new(NLBL_MGMT_C_REMOVEDEF, 0);
|
|
Packit |
51d0f7 |
if (msg == NULL)
|
|
Packit |
51d0f7 |
goto deldef_return;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* send the request */
|
|
Packit |
51d0f7 |
rc = nlbl_comm_send(p_hndl, msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto deldef_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* read the response */
|
|
Packit |
51d0f7 |
rc = nlbl_mgmt_recv(p_hndl, &ans_msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto deldef_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* process the response */
|
|
Packit |
51d0f7 |
rc = nlbl_mgmt_parse_ack(ans_msg);
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
deldef_return:
|
|
Packit |
51d0f7 |
if (hndl == NULL)
|
|
Packit |
51d0f7 |
nlbl_comm_close(p_hndl);
|
|
Packit |
51d0f7 |
nlbl_msg_free(msg);
|
|
Packit |
51d0f7 |
nlbl_msg_free(ans_msg);
|
|
Packit |
51d0f7 |
return rc;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* List the default NetLabel domain mapping
|
|
Packit |
51d0f7 |
* @param hndl the NetLabel handle
|
|
Packit |
51d0f7 |
* @param domain the default domain map
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Query the NetLabel subsystem and return the default domain mapping in
|
|
Packit |
51d0f7 |
* @domain. If @hndl is NULL then the function will handle opening and
|
|
Packit |
51d0f7 |
* closing it's own NetLabel handle. Returns zero on success, negative values
|
|
Packit |
51d0f7 |
* on failure.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
int nlbl_mgmt_listdef(struct nlbl_handle *hndl, uint16_t family,
|
|
Packit |
51d0f7 |
struct nlbl_dommap *domain)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
int rc = -ENOMEM;
|
|
Packit |
51d0f7 |
struct nlbl_handle *p_hndl = hndl;
|
|
Packit |
51d0f7 |
nlbl_msg *msg = NULL;
|
|
Packit |
51d0f7 |
nlbl_msg *ans_msg = NULL;
|
|
Packit |
51d0f7 |
struct genlmsghdr *genl_hdr;
|
|
Packit |
51d0f7 |
struct nlattr *nla;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* sanity checks */
|
|
Packit |
51d0f7 |
if (domain == NULL)
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
if (nlbl_mgmt_fid == 0)
|
|
Packit |
51d0f7 |
return -ENOPROTOOPT;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* open a handle if we need one */
|
|
Packit |
51d0f7 |
if (p_hndl == NULL) {
|
|
Packit |
51d0f7 |
p_hndl = nlbl_comm_open();
|
|
Packit |
51d0f7 |
if (p_hndl == NULL)
|
|
Packit |
51d0f7 |
goto listdef_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* create a new message */
|
|
Packit |
51d0f7 |
msg = nlbl_mgmt_msg_new(NLBL_MGMT_C_LISTDEF, 0);
|
|
Packit |
51d0f7 |
if (msg == NULL)
|
|
Packit |
51d0f7 |
goto listdef_return;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
rc = nla_put_u16(msg, NLBL_MGMT_A_FAMILY, family);
|
|
Packit |
51d0f7 |
if (rc != 0)
|
|
Packit |
51d0f7 |
goto listdef_return;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* send the request */
|
|
Packit |
51d0f7 |
rc = nlbl_comm_send(p_hndl, msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto listdef_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* read the response */
|
|
Packit |
51d0f7 |
rc = nlbl_mgmt_recv(p_hndl, &ans_msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto listdef_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* check the response */
|
|
Packit |
51d0f7 |
rc = nlbl_mgmt_parse_ack(ans_msg);
|
|
Packit |
51d0f7 |
if (rc < 0 && rc != -ENOMSG)
|
|
Packit |
51d0f7 |
goto listdef_return;
|
|
Packit |
51d0f7 |
genl_hdr = nlbl_msg_genlhdr(ans_msg);
|
|
Packit |
51d0f7 |
if (genl_hdr == NULL || genl_hdr->cmd != NLBL_MGMT_C_LISTDEF) {
|
|
Packit |
51d0f7 |
rc = -EBADMSG;
|
|
Packit |
51d0f7 |
goto listdef_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* process the response */
|
|
Packit |
51d0f7 |
genl_hdr = nlbl_msg_genlhdr(ans_msg);
|
|
Packit |
51d0f7 |
if (genl_hdr == NULL || genl_hdr->cmd != NLBL_MGMT_C_LISTDEF)
|
|
Packit |
51d0f7 |
goto listdef_return;
|
|
Packit |
51d0f7 |
nla = nlbl_attr_find(ans_msg, NLBL_MGMT_A_FAMILY);
|
|
Packit |
51d0f7 |
if (nla != NULL)
|
|
Packit |
51d0f7 |
domain->family = nla_get_u16(nla);
|
|
Packit |
51d0f7 |
else
|
|
Packit |
51d0f7 |
domain->family = AF_UNSPEC;
|
|
Packit |
51d0f7 |
nla = nlbl_attr_find(ans_msg, NLBL_MGMT_A_PROTOCOL);
|
|
Packit |
51d0f7 |
if (nla != NULL) {
|
|
Packit |
51d0f7 |
domain->proto_type = nla_get_u32(nla);
|
|
Packit |
51d0f7 |
switch (domain->proto_type) {
|
|
Packit |
51d0f7 |
case NETLBL_NLTYPE_CIPSOV4:
|
|
Packit |
51d0f7 |
nla = nlbl_attr_find(ans_msg, NLBL_MGMT_A_CV4DOI);
|
|
Packit |
51d0f7 |
if (nla == NULL)
|
|
Packit |
51d0f7 |
goto listdef_return;
|
|
Packit |
51d0f7 |
domain->proto.cip_doi = nla_get_u32(nla);
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
case NETLBL_NLTYPE_CALIPSO:
|
|
Packit |
51d0f7 |
nla = nlbl_attr_find(ans_msg, NLBL_MGMT_A_CLPDOI);
|
|
Packit |
51d0f7 |
if (nla == NULL)
|
|
Packit |
51d0f7 |
goto listdef_return;
|
|
Packit |
51d0f7 |
domain->proto.clp_doi = nla_get_u32(nla);
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
} else if ((nla = nlbl_attr_find(ans_msg, NLBL_MGMT_A_SELECTORLIST))) {
|
|
Packit |
51d0f7 |
if (nlbl_mgmt_list_addr(nla, domain) != 0)
|
|
Packit |
51d0f7 |
goto listdef_return;
|
|
Packit |
51d0f7 |
} else
|
|
Packit |
51d0f7 |
goto listdef_return;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
rc = 0;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
listdef_return:
|
|
Packit |
51d0f7 |
if (hndl == NULL)
|
|
Packit |
51d0f7 |
nlbl_comm_close(p_hndl);
|
|
Packit |
51d0f7 |
nlbl_msg_free(msg);
|
|
Packit |
51d0f7 |
nlbl_msg_free(ans_msg);
|
|
Packit |
51d0f7 |
return rc;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/**
|
|
Packit |
51d0f7 |
* List all of the configured NetLabel domain mappings
|
|
Packit |
51d0f7 |
* @param hndl the NetLabel handle
|
|
Packit |
51d0f7 |
* @param domains domain mapping array
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
* Query the NetLabel subsystem and return the configured domain mappings in
|
|
Packit |
51d0f7 |
* @domains. If @hndl is NULL then the function will handle opening and
|
|
Packit |
51d0f7 |
* closing it's own NetLabel handle. Returns the number of domains on success,
|
|
Packit |
51d0f7 |
* zero if no domains are specified, and negative values on failure.
|
|
Packit |
51d0f7 |
*
|
|
Packit |
51d0f7 |
*/
|
|
Packit |
51d0f7 |
int nlbl_mgmt_listall(struct nlbl_handle *hndl, struct nlbl_dommap **domains)
|
|
Packit |
51d0f7 |
{
|
|
Packit |
51d0f7 |
int rc = -ENOMEM;
|
|
Packit |
51d0f7 |
struct nlbl_handle *p_hndl = hndl;
|
|
Packit |
51d0f7 |
unsigned char *data = NULL;
|
|
Packit |
51d0f7 |
nlbl_msg *msg = NULL;
|
|
Packit |
51d0f7 |
struct nlmsghdr *nl_hdr;
|
|
Packit |
51d0f7 |
struct genlmsghdr *genl_hdr;
|
|
Packit |
51d0f7 |
struct nlattr *nla_head;
|
|
Packit |
51d0f7 |
struct nlattr *nla;
|
|
Packit |
51d0f7 |
int data_len;
|
|
Packit |
51d0f7 |
int data_attrlen;
|
|
Packit |
51d0f7 |
struct nlbl_dommap *dmns = NULL, *dmns_new;
|
|
Packit |
51d0f7 |
uint32_t dmns_count = 0;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* sanity checks */
|
|
Packit |
51d0f7 |
if (domains == NULL)
|
|
Packit |
51d0f7 |
return -EINVAL;
|
|
Packit |
51d0f7 |
if (nlbl_mgmt_fid == 0)
|
|
Packit |
51d0f7 |
return -ENOPROTOOPT;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* open a handle if we need one */
|
|
Packit |
51d0f7 |
if (p_hndl == NULL) {
|
|
Packit |
51d0f7 |
p_hndl = nlbl_comm_open();
|
|
Packit |
51d0f7 |
if (p_hndl == NULL)
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* create a new message */
|
|
Packit |
51d0f7 |
msg = nlbl_mgmt_msg_new(NLBL_MGMT_C_LISTALL, NLM_F_DUMP);
|
|
Packit |
51d0f7 |
if (msg == NULL) {
|
|
Packit |
51d0f7 |
rc = -ENOMEM;
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* send the request */
|
|
Packit |
51d0f7 |
rc = nlbl_comm_send(p_hndl, msg);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* read all of the messages (multi-message response) */
|
|
Packit |
51d0f7 |
do {
|
|
Packit |
51d0f7 |
if (data != NULL) {
|
|
Packit |
51d0f7 |
free(data);
|
|
Packit |
51d0f7 |
data = NULL;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* get the next set of messages */
|
|
Packit |
51d0f7 |
rc = nlbl_comm_recv_raw(p_hndl, &data);
|
|
Packit |
51d0f7 |
if (rc <= 0) {
|
|
Packit |
51d0f7 |
if (rc == 0)
|
|
Packit |
51d0f7 |
rc = -ENODATA;
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
data_len = rc;
|
|
Packit |
51d0f7 |
nl_hdr = (struct nlmsghdr *)data;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* check to see if this is a netlink control message we don't
|
|
Packit |
51d0f7 |
* care about */
|
|
Packit |
51d0f7 |
if (nl_hdr->nlmsg_type == NLMSG_NOOP ||
|
|
Packit |
51d0f7 |
nl_hdr->nlmsg_type == NLMSG_ERROR ||
|
|
Packit |
51d0f7 |
nl_hdr->nlmsg_type == NLMSG_OVERRUN) {
|
|
Packit |
51d0f7 |
rc = -EBADMSG;
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* loop through the messages */
|
|
Packit |
51d0f7 |
while (nlmsg_ok(nl_hdr, data_len) &&
|
|
Packit |
51d0f7 |
nl_hdr->nlmsg_type != NLMSG_DONE) {
|
|
Packit |
51d0f7 |
/* get the header pointers */
|
|
Packit |
51d0f7 |
genl_hdr = (struct genlmsghdr *)nlmsg_data(nl_hdr);
|
|
Packit |
51d0f7 |
if (genl_hdr == NULL ||
|
|
Packit |
51d0f7 |
genl_hdr->cmd != NLBL_MGMT_C_LISTALL) {
|
|
Packit |
51d0f7 |
rc = -EBADMSG;
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
nla_head = (struct nlattr *)(&genl_hdr[1]);
|
|
Packit |
51d0f7 |
data_attrlen = genlmsg_attrlen(genl_hdr, 0);
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* resize the array */
|
|
Packit |
51d0f7 |
dmns_new = realloc(dmns,
|
|
Packit |
51d0f7 |
sizeof(*dmns) * (dmns_count + 1));
|
|
Packit |
51d0f7 |
if (dmns_new == NULL)
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
dmns = dmns_new;
|
|
Packit |
51d0f7 |
memset(&dmns[dmns_count], 0, sizeof(*dmns));
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* get the attribute information */
|
|
Packit |
51d0f7 |
nla = nla_find(nla_head,
|
|
Packit |
51d0f7 |
data_attrlen, NLBL_MGMT_A_DOMAIN);
|
|
Packit |
51d0f7 |
if (nla == NULL)
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
dmns[dmns_count].domain = malloc(nla_len(nla));
|
|
Packit |
51d0f7 |
if (dmns[dmns_count].domain == NULL)
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
strncpy(dmns[dmns_count].domain, nla_data(nla),
|
|
Packit |
51d0f7 |
nla_len(nla));
|
|
Packit |
51d0f7 |
nla = nla_find(nla_head,
|
|
Packit |
51d0f7 |
data_attrlen, NLBL_MGMT_A_FAMILY);
|
|
Packit |
51d0f7 |
if (nla != NULL)
|
|
Packit |
51d0f7 |
dmns[dmns_count].family = nla_get_u16(nla);
|
|
Packit |
51d0f7 |
else
|
|
Packit |
51d0f7 |
dmns[dmns_count].family = AF_UNSPEC;
|
|
Packit |
51d0f7 |
nla = nla_find(nla_head,
|
|
Packit |
51d0f7 |
data_attrlen, NLBL_MGMT_A_PROTOCOL);
|
|
Packit |
51d0f7 |
if (nla != NULL) {
|
|
Packit |
51d0f7 |
dmns[dmns_count].proto_type = nla_get_u32(nla);
|
|
Packit |
51d0f7 |
switch (dmns[dmns_count].proto_type) {
|
|
Packit |
51d0f7 |
case NETLBL_NLTYPE_CIPSOV4:
|
|
Packit |
51d0f7 |
nla = nla_find(nla_head,
|
|
Packit |
51d0f7 |
data_attrlen,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_CV4DOI);
|
|
Packit |
51d0f7 |
if (nla == NULL)
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
dmns[dmns_count].proto.cip_doi =
|
|
Packit |
51d0f7 |
nla_get_u32(nla);
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
case NETLBL_NLTYPE_CALIPSO:
|
|
Packit |
51d0f7 |
nla = nla_find(nla_head,
|
|
Packit |
51d0f7 |
data_attrlen,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_CLPDOI);
|
|
Packit |
51d0f7 |
if (nla == NULL)
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
dmns[dmns_count].proto.clp_doi =
|
|
Packit |
51d0f7 |
nla_get_u32(nla);
|
|
Packit |
51d0f7 |
break;
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
} else if ((nla = nla_find(nla_head, data_attrlen,
|
|
Packit |
51d0f7 |
NLBL_MGMT_A_SELECTORLIST))) {
|
|
Packit |
51d0f7 |
if (nlbl_mgmt_list_addr(nla,
|
|
Packit |
51d0f7 |
&dmns[dmns_count]) != 0)
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
} else
|
|
Packit |
51d0f7 |
goto listall_return;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
dmns_count++;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
/* next message */
|
|
Packit |
51d0f7 |
nl_hdr = nlmsg_next(nl_hdr, &data_len);
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
} while (NL_MULTI_CONTINUE(nl_hdr));
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
*domains = dmns;
|
|
Packit |
51d0f7 |
rc = dmns_count;
|
|
Packit |
51d0f7 |
|
|
Packit |
51d0f7 |
listall_return:
|
|
Packit |
51d0f7 |
if (rc < 0 && dmns) {
|
|
Packit |
51d0f7 |
do {
|
|
Packit |
51d0f7 |
if (dmns[dmns_count].domain) {
|
|
Packit |
51d0f7 |
free(dmns[dmns_count].domain);
|
|
Packit |
51d0f7 |
if (dmns[dmns_count].proto_type ==
|
|
Packit |
51d0f7 |
NETLBL_NLTYPE_ADDRSELECT) {
|
|
Packit |
51d0f7 |
struct nlbl_dommap_addr *iter, *prev;
|
|
Packit |
51d0f7 |
iter = dmns[dmns_count].proto.addrsel;
|
|
Packit |
51d0f7 |
while (iter) {
|
|
Packit |
51d0f7 |
prev = iter;
|
|
Packit |
51d0f7 |
iter = iter->next;
|
|
Packit |
51d0f7 |
free(prev);
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
} while (dmns_count-- > 0);
|
|
Packit |
51d0f7 |
free(dmns);
|
|
Packit |
51d0f7 |
}
|
|
Packit |
51d0f7 |
if (hndl == NULL)
|
|
Packit |
51d0f7 |
nlbl_comm_close(p_hndl);
|
|
Packit |
51d0f7 |
if (data)
|
|
Packit |
51d0f7 |
free(data);
|
|
Packit |
51d0f7 |
nlbl_msg_free(msg);
|
|
Packit |
51d0f7 |
return rc;
|
|
Packit |
51d0f7 |
}
|